Preset-Env 按需 Polyfill 是怎么实现的?
发布时间:2022-02-16 14:49 所属栏目:52 来源:互联网
导读:
导读:开发时我们会使用一些新的 api,但用户的浏览器各种版本都有,可能并不支持这些 api,但我们也不能因此就不用了,这时候就可以通过 polyfill 来解决。 polyfill 是垫片的意思,也就是在运行业务代码之前,在全局注入一些 api 的实现,这样之后运行的业务代码
开发时我们会使用一些新的 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' }) 1. 同样也是用 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 这种粗暴的指定目标,确实聪明了很多。 (编辑:ASP站长网) |
相关内容
网友评论
推荐文章
热点阅读