社区精选 | Skypack:我老早就在布局前端基建了

业界 作者:SegmentFault 2022-07-07 13:18:00

今天为各位小伙伴推荐的是社区作者 卡颂 的文章,在这篇文章中他介绍了一款基于 ESM 规范的 CDN 服务产品 Skypack,让我们一起来学习吧!




大家好,我卡颂。


已经有越来越多前端开发者放弃 webpack,改用 vite 作为项目打包工具。


其中最主要的原因是 —— vite 在开发环境基于 ESM 规范实现的 Nobundle模式,节省了代码打包的时间(当然,也有 ESBuild 的功劳)。


而在生产环境,当前仍有打包的需求。


随着浏览器的迭代,ESM 规范兼容性越来越好,终有一天会进入生产环境大面积可用的状态。



届时生产环境打包将不再是刚需。


另一方面,从 HTTP 协议的角度看,在 HTTP/1.1 时代,多个模块被打包成一个文件能减少浏览器并发请求数,达到优化目的。


但在 HTTP/2 多路复用普及后,这么做的意义就不大了。


可以说,当这些基建成熟后,生产环境使用 ESM 模块是水到渠成的事情。


很多团队预感到这点,很早就开始布局相关产品。今天要介绍的 Skypack 就是这样一款产品。


不一样的 CDN



Skypack 首次发布于 19 年 6 月(曾用名 Pika CDN),是一款基于 ESM 规范的 CDN 服务


在浏览器中,常见的 CDN 服务通常以 script 标签的形式引入 UMD 规范的代码,以 ReactDOM 举例:


<script crossorigin src="https://unpkg.com/react-dom@18.2.0/umd/react-dom.development.js"></script>

代码执行后会在全局暴露对象 window.ReactDOM


一些情况下,一个包还会依赖其他包,比如 ReactDOM 还会依赖如下 3 个包:


  • React

  • scheduler

  • object-assign


为了应对这种情况,在生产环境开发者通常会将第三方依赖统一打包。

Skypack ESM 规范引入代码:

// 在业务代码中引入如下语句
import ReactDOM from 'https://cdn.skypack.dev/react-dom';

浏览器会依次发起对包及其依赖的请求:


配合上浏览器的 Module Preload 特性,可以让这些资源统一预加载。
https://developer.chrome.com/blog/modulepreload/

这就解决了第三方依赖需要打包的问题。

按需polyfill



如果你访问上述 CDN 链接(https://cdn.skypack.dev/react-dom),会发现返回的结果并不是 ReactDOM 的代码,而是下面两句 export 语句:

export * from '/-/react-dom@v17.0.1-oZ1BXZ5opQ1DbTh7nu9r/dist=es2019,mode=imports/optimized/react-dom.js';
export {default} from '/-/react-dom@v17.0.1-oZ1BXZ5opQ1DbTh7nu9r/dist=es2019,mode=imports/optimized/react-dom.js';

语句的背后才是 ESM 规范的 ReactDOM 代码。

之所以这么做是因为:Skypack 会根据目标浏览器的 UA 为浏览器提供适合的包。

在高版本 Chrome 中的代码不需要 polyfill,而在低版本 IE 中的代码需要 polyfill,所以不同目标浏览器拿到的是不同的 ReactDOM 代码。

上述 export 语句中哈希(oZ1BXZ5opQ1DbTh7nu9r)的不同就对应同一个版本的 ReactDOM 经过不同程度 polyfill 后的不同结果

此外,在 url 后加 min 能得到压缩后的代码

import ReactDOM from 'https://cdn.skypack.dev/react-dom?min';

接下来让我们看看 Skypack 是如何处理请求的。

处理请求的流程



并不是所有包都有 ESM 规范的产物(React 就没有),当以如下 url 格式访问任意包时:

// xxx替换为任意包名
import React from 'https://cdn.skypack.dev/xxx';

如果之前从未有人访问过这个包,则会构建包及其依赖的 ESM 产物并返回。

比如 ReactDOM 本身只提供 UMD 规范的产物,第一个访问他的 Skypack CDN 链接的用户会经历如下步骤:

  • 收集 ReactDOM 及其依赖

  • ReactDOM 及其依赖变为 ESM 规范

  • 构建不同 polyfill 程度的 ESM 产物

  • 根据目标浏览器 UA 返回对应的 ReactDOM


ReactDOM 的产物代码中可以看到,他依赖的三个包已经转为 ESM 规范:


总结



除了 Skypack 外,esm.sh 也是类似功能的 ESM CDN 服务。
https://esm.sh/

等到前端基建成熟的那天,相信这些 ESM CDN 服务一定能大放异彩。



SegmentFault 思否社区小编说


自 2022-07-01 起 SegmentFault 思否公众号改版啦!之后将陆续推出新的栏目和大家见面!(请拭目以待呀~


在「社区精选」栏目中,我们将为广大开发者推荐来自 SegmentFault 思否开发者社区的优质技术文章,这些文章全部出自社区中充满智慧的技术创作者哦!


希望通过这一栏目,大家可以共同学习技术干货,GET 新技能和各种花式技术小 Tips。


欢迎越来越多的开发者加入创作者的行列,我们将持续甄选出社区中优质的内容推介给更多人,让闪闪发光的技术创作者们走到聚光灯下,被更多人认识。


「社区精选」投稿邮箱:pr@segmentfault.com

投稿请附上社区文章地址






点击左下角阅读原文,到 SegmentFault 思否社区 和文章作者展开更多互动和交流,公众号后台回复“ 入群 ”即可加入我们的技术交流群,收获更多的技术文章~

- END -

关注公众号:拾黑(shiheibook)了解更多

赞助链接:

关注数据与安全,洞悉企业级服务市场:https://www.ijiandao.com/
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接