@babel/polyfill
更多内容参见: babeljs.io/docs/en/bab…
Babel 7.4.0 开始,这个包已经过时了,源码直接引入了 corejs 和 regenerator
图片源地址: github.com/babel/babel…
- 应用代码里可以使用,工具库就不应该使用(下文会介绍@babel/plugin-transform-runtime)
- 模拟了 ES6+ 环境(不包括:Stage 0/1/2/3)
- 在程序的入口处添加,一劳永逸
- 因为是在各 prototype 上添加 poliyfill 方法,会导致全局污染
进化方案
- @babel/preset-env + useBuiltIns (下文会介绍)
- 你自己手动单独导入你需要的 polyfill 子包
共有 2 个替代方案,推荐使用第1个,第1个方案其实就是第二个方案的自动化版本。怎么自动化呢?根据运行目标环境自动选择需要哪些 polyfill 子包。具体见下。
@babel/preset-env
@babel/preset-env 基于一些牛逼的项目:browserslist,compat-table,electron-to-chromium,......
@babel/preset-env 自动适配设定的目标环境需要的 js 特性,Babel 转换插件(不包含 stage-0/1/2/3的插件),corejs 的 poliyfill。自动适配可以有选择性的污染全局,当然也可以不分青红皂白全部转换到ES5,具体参见:babeljs.io/docs/en/bab…
你需要掌握在 webpack 中如何自定义配置 @babel/preset-env,掌握 @babel/preset-env + useBuiltIns 替代 @babel/polyfill 的配置。
方案1
方案2
方案3
- 安装 @babel/polyfill
- 在 .babelrc 中配置
useBuiltIns: 'false'
,这是默认行为 - 在 webpack 配置的入口处添加 @babel/polyfill
@babel/plugin-transform-runtime
术语解释
helper:比如 Babel 使用 _extend 函数把一个对象的属性复制到另一个对象上,这里的 _extend 就是 helper
有了前两个技术方案,为什么还会出个 @babel/plugin-transform-runtime 呢?
- 你不想污染全局
- 你想在一个工具库中使用
- 默认 helper 函数会在需要的文件中都被声明或定义一次,不仅浪费而且没法跨文件支持
@babel/plugin-transform-runtime 提供了一个沙盒环境,使用一些高版本 js 特性时会指向到 corejs,没有污染全局,但是因为没有在 prototype 上做 polyfill,一些高版本 js 的实例方法就没法使用了,比如:Array.prototype.includes
。
@babel/plugin-transform-runtime 让所有的 helper 函数都指向 @babel/runtime 组件,这样节省空间还能跨文件支持,方便统一管理。这也就要求 @babel/runtime 需要预先安装。
配置
在 .babelrc 配置文件里,带着默认参数的配置
{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": false,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
复制代码
corejs
从 "corejs": false
这个默认参数可以看出,@babel/plugin-transform-runtime 假定所有的 polyfill 需要用户自己提供:
图片来源: github.com/babel/babel…
总结下:
- 配置 corejs 为 3,需要预先安装 @babel/runtime-corejs3
- 配置 corejs 为 2,需要预先安装 @babel/runtime-corejs2
- 配置 corejs 为 false,需要预先安装 @babel/runtime
absoluteRuntime
Babel 默认会从 node_modules 加载已经配置安装的 @babel/runtime 某个版本。absoluteRuntime 参数就是修改这个默认行为的,可以具体指定从哪里加载相应的 @babel/runtime。
其他配置项的解释参见:babeljs.io/docs/en/bab…