Preset-Env 按需 Polyfill 是怎么实现的?
本文转载自微信公众号「神光的编程秘籍」,作者神说要有光。转载本文请联系神光的编程秘籍公众号。
开发时我们会使用一些新的 api,但用户的浏览器各种版本都有,可能并不支持这些 api,但我们也不能因此就不用了,这时候就可以通过 polyfill 来解决。
polyfill 是垫片的意思,也就是在运行业务代码之前,在全局注入一些 api 的实现,这样之后运行的业务代码用到该 api 时就有了,也就不会有兼容问题。
但用户的浏览器可能是各种各样的,有可能我们 polyfill 的 api 本来就支持,这时候加载 polyfill 就很没必要,而且也浪费了性能。
有没有什么办法能够既解决不支持这个 api 的运行环境的兼容问题,又不会在支持这个 api 的环境引 入不必要的代码呢?
答案就是 preset-env,它实现了按需引入 polyfill。
这里的 preset-env 指的是 babel 的 @babel/preset-env 和 postcss 的 postcss-preset-env,它们一个是按需做语法转换、按需引入 JS 的 polyfill,一个是按需做添加 prefix 等 css 兼容处理。
虽然分别是针对 JS 和 CSS 的,但他们两个的原理差不多,我们分别来看一下。
@babel/preset-env
按需指的是按照目标运行环境是否支持,那怎么指定目标运行环境呢?
@babel/preset-env 支持通过 targets 来指定目标环境:
{
"presets": [
["@babel/preset-env", {
"targets": "> 0.25%, not dead"
}]
]
}
这里的 targets 是 browserslist 的查询字符串,它可以解析查询字符串返回对应的浏览器版本:
有了这些目标浏览器的版本,还需要知道各种特性是在什么版本支持的:
babel 维护了一个数据库,在 @babel/compat-data 这个包里:
这样就能根据目标浏览器的版本,过滤出哪些特性是支持的,哪些是不支持的。然后只对不支持的特性做语法转换和 polyfill 即可。
这就是按需 polyfill 的实现原理。
css 的按需做兼容处理也差不多:
postcss-preset-env
postcss 是通过 postcss-preset-env 来做按需处理的,同样支持配置目标环境,也就是 browsers:
postcssPresetEnv({ browsers: 'last 2 versions' })
同样也是用 browserslist 来把查询字符串转换成对应的浏览器版本。
然后再根据哪些 css 特性是从什么浏览器版本开始支持的来过滤出不支持的 css 特性。
这里用的是 caniuse 的数据,在 cssdb 这个包里:
知道了目标浏览器的版本,知道了这些特性在什么浏览器版本支持,那自然就可以过滤出不支持的 css 特性。然后引入不同的 postcss 插件来处理这些特性的 prefix 等就可以了。
这就是 css 的按需 prefix 等处理的原理。
可以看到 babel 和 potcss 都依赖了 browerslist 这个包来查询目标浏览器版本,那自然可以统一成一个,也就是在根目录下的 .browserslistrc 的配置文件,通过指定同一个的环境来按需做 JS 和 CSS 的兼容处理。
总结
用户的浏览器可能是各种各样的,我们开发时用的 JS 和 CSS 的特性在用户的浏览器不一定支持,为了保证功能正常就要做兼容处理。
JS 的兼容处理就是 polyfill,CSS 的兼容处理就是添加 prefix 等。
babel 是通过 @babel/preset-env 来做按需 polyfill 和转换的,原理是通过 browserslist 来查询出目标浏览器版本,然后根据 @babel/compat-data 的数据库来过滤出这些浏览器版本里哪些特性不支持,之后引入对应的插件处理。
postcss 是通过 postcss-preset-env 来做按需 prefix 等的,原理也是通过 browserslist 来查询出目标浏览器版本,然后根据 cssdb 的数据库(来自 caniuse)来过滤出不支持的 CSS 特性,然后对这些 CSS 做处理即可。
就像 preset-env 的名字一样,它们的意义就是根据目标环境来按需做处理的,也被叫做智能处理,比之前的 es5、es6 这种粗暴的指定目标,确实聪明了很多。
相关文章
- 在 Go 里用 CGO?这 7 个问题你要关注!
- 9款优秀的去中心化通讯软件 Matrix 的客户端
- 求职数据分析,项目经验该怎么写
- 在OKR中,我看到了数据驱动业务的未来
- 火山引擎云原生大数据在金融行业的实践
- OpenHarmony富设备移植指南(二)—从postmarketOS获取移植资源
- 《数据成熟度指数》报告:64%的企业领袖认为大多数员工“不懂数据”
- OpenHarmony 小型系统兼容性测试指南
- 肯睿中国(Cloudera):2023年企业数字战略三大趋势预测
- 适用于 Linux 的十大命令行游戏
- GNOME 截图工具的新旧截图方式
- System76 即将推出的 COSMIC 桌面正在酝酿大变化
- 2GB 内存 8GB 存储即可流畅运行,Windows 11 极致精简版系统 Tiny11 发布
- 迎接 ecode:一个即将推出的具有全新图形用户界面框架的现代、轻量级代码编辑器
- loongarch架构介绍(三)—地址翻译
- Go 语言怎么解决编译器错误“err is shadowed during return”?
- 敏捷:可能被开发人员遗忘的部分
- Denodo预测2023年数据管理和分析的未来
- 利用数据推动可持续发展
- 在 Vue3 中实现 React 原生 Hooks(useState、useEffect),深入理解 React Hooks 的