大家好,我是Kason。越来越多的前端开发者放弃了webpack,转而使用vite作为项目打包工具。主要原因是vite在开发环境中实现了基于ESM规范的Nobundle模式,节省了代码打包的时间(当然也有ESBuild的功劳)。在生产环境中,还是需要打包的。随着浏览器的迭代,ESM规范的兼容性越来越好,总有一天会进入生产环境大面积可用的状态。届时,生产环境中的打包将不再是硬性要求。另一方面,从HTTP协议的角度来看,在HTTP/1.1时代,将多个模块打包到一个文件中,以减少浏览器的并发请求数,达到优化的目的。但是在HTTP/2多路复用流行之后,这样做意义不大。可以说,当这些基础设施成熟之后,在生产环境中使用ESM模块就是水到渠成的事情了。很多团队对此都有预感,很早就开始布局相关产品。今天要介绍的Skypack就是这样一款产品。欢迎加入人类优质前端框架群。不同的CDNSkypack于2019年6月首次发布(以前称为PikaCDN)。它是一种基于ESM规范的CDN服务。在浏览器中,常见的CDN服务通常以script标签的形式引入UMD规范代码,以ReactDOM为例:代码执行后,会全局暴露window.ReactDOM对象。在某些情况下,一个包还依赖于其他包。比如ReactDOM还依赖了如下三个包:Reactschedulerobject-assign为了应对这种情况,开发者通常会在生产环境中统一打包第三方依赖。而Skypack导入ESM规范的代码://在业务代码中引入如下语句importReactDOMfrom'https://cdn.skypack.dev/react-dom';浏览器会依次发起对包及其依赖的请求:配合浏览器的ModulePreload特性,可以让这些资源统一预加载。这样就解决了需要打包第三方依赖的问题。On-demandpolyfill如果你访问上面的CDN链接(https://cdn.skypack.dev/react...),你会发现返回的结果不是ReactDOM的代码,而是下面两条导出语句:*来自'/-/react-dom@v17.0.1-oZ1BXZ5opQ1DbTh7nu9r/dist=es2019,mode=imports/optimized/react-dom.js';从'/-/react-dom@v17.0.1-oZ1BXZ5opQ1DbTh7nu9r/dist=es2019,mode=imports/optimized/react-dom.js'导出{默认};语句后面是ESM规范的ReactDOM代码。这样做的原因是:Skypack会根据目标浏览器的UA,为浏览器提供合适的包。高版本Chrome的代码不需要polyfill,而低版本IE的代码需要polyfill,所以不同的目标浏览器得到不同的ReactDOM代码。上述export语句中hash(oZ1BXZ5opQ1DbTh7nu9r)的不同,对应的是同一版本的ReactDOM经过不同程度的polyfilling后的不同结果。另外,可以通过在url后面加上min来获取压缩后的代码:importReactDOMfrom'https://cdn.skypack.dev/react-dom?min';接下来我们看看Skypack是如何处理请求的。处理请求的过程不是所有包的ESM规范的产物(React不是)。当访问以下url格式的任何包时://xxx被替换为任何包名importReactfrom'https://cdn.skypack.开发/xxx';如果以前从未访问过包,则将构建并返回包及其依赖的ESM工件。例如,ReactDOM本身只提供UMD规范的产品。第一个访问他的SkypackCDN链接的用户会经历以下步骤:收集ReactDOM及其依赖项将ReactDOM及其依赖项转化为ESM规范构建具有不同polyfill级别的ESM产品根据目标浏览可以看到UA返回的对应ReactDOM在ReactDOM的产品代码中。它所依赖的三个包都已经转换为ESM规范:总结除了Skypack,esm.sh也是一个功能类似的ESMCDN服务。当前端基础设施成熟时,相信这些ESMCDN服务会大放异彩。
