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 的查询字符串,它可以解析查询字符串返回对应的浏览器版本:

Preset-Env 按需 Polyfill 是怎么实现的?

有了这些目标浏览器的版本,还需要知道各种特性是在什么版本支持的:

babel 维护了一个数据库,在 @babel/compat-data 这个包里:

Preset-Env 按需 Polyfill 是怎么实现的?

这样就能根据目标浏览器的版本,过滤出哪些特性是支持的,哪些是不支持的。然后只对不支持的特性做语法转换和 polyfill 即可。

Preset-Env 按需 Polyfill 是怎么实现的?

这就是按需 polyfill 的实现原理。

css 的按需做兼容处理也差不多:

postcss-preset-env

postcss 是通过 postcss-preset-env 来做按需处理的,同样支持配置目标环境,也就是 browsers:

postcssPresetEnv({ browsers: 'last 2 versions' })

同样也是用 browserslist 来把查询字符串转换成对应的浏览器版本。

然后再根据哪些 css 特性是从什么浏览器版本开始支持的来过滤出不支持的 css 特性。

这里用的是 caniuse 的数据,在 cssdb 这个包里:

Preset-Env 按需 Polyfill 是怎么实现的?

知道了目标浏览器的版本,知道了这些特性在什么浏览器版本支持,那自然就可以过滤出不支持的 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 这种粗暴的指定目标,确实聪明了很多。

文章版权声明

 1 原创文章作者:1502,如若转载,请注明出处: https://www.52hwl.com/92364.html

 2 温馨提示:软件侵权请联系469472785#qq.com(三天内删除相关链接)资源失效请留言反馈

 3 下载提示:如遇蓝奏云无法访问,请修改lanzous(把s修改成x)

 免责声明:本站为个人博客,所有软件信息均来自网络 修改版软件,加群广告提示为修改者自留,非本站信息,注意鉴别

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2024年1月16日 下午9:14
下一篇 2024年1月16日 下午9:15