@babel/plugin-transform-runtime 到底是什么?
1.简单的babel配置以及碰到的问题
首先写一个最简单的 babel 配置文件:
"presets":[["@babel/preset-env"]]
- const 这种语法为 syntax,includes 这种方法为 api。
可以看到,syntax 很轻松就转好了,但是 api 并没有做任何处理。babel 转译后的代码如果在不支持 includes 这个方法的浏览器里运行,就会报错。 - babel 使用 polyfill 来处理 api。
@babel/preset-env 中有一个配置选项 useBuiltIns,用来告诉 babel 如何处理 api。
由于这个选项默认值为 false,即不处理 api,所以上面的代码转译后没有处理 includes 这个方法。 - 设置 useBuiltIns 的值为 "entry",同时在源代码的最上方手动引入 @babel/polyfill 这个库
可以看到,这种模式下,babel 会将所有的 polyfill 全部引入,这样会导致结果的包大小非常大,而我们这里仅仅需要 includes 一个方法而已。
- 正确的做法是使用按需加载,将 useBuiltIns 改为 "usage",babel 就可以按需加载 polyfill,并且不需要手动引入 @babel/polyfill:
2.遗留的两个问题以及解决方案
- 插件直接在global.Array.prototype 上添加了includes方法
- babel 转译 syntax 时,有时候会使用一些辅助的函数来帮忙转。如果有100个文件那么就会创建100个辅助函数
- @babel/plugin-transform-runtime就是解决以上两个问题的
前后对比如下
最终配置:babel.config.json
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"debug": true
}
]
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": 3 // 指定 runtime-corejs 的版本,目前有 2 3 两个版本
}
]
]
}
概念
-
@babel/core babel核心模块
-
@babel/cli 终端运行工具,内置的插件,运行你从终端使用babel的工具.
-
plugins 它的本质就是一个JS程序, 指示着Babel如何对代码进行转换.
-
preset就是一组插件的集合
在不进行任何配置的情况下,@babel/preset-env 所包含的插件将支持所有最新的JS特性(ES2015,ES2016等,不包含 stage 阶段),将其转换成ES5代码。例如,如果你的代码中使用了可选链(目前,仍在 stage 阶段),那么只配置 @babel/preset-env,转换时会抛出错误,需要另外安装相应的插件。
-
Polyfill是对执行环境或者其它功能的一个补充.
@babel/polyfill 模块包括 core-js 和一个自定义的 regenerator runtime 模块,可以模拟完整的 ES2015+ 环境(不包含第4阶段前的提议)。 -
@babel/polyfill用来模拟完成ES6+环境 其包括了core-js和自定义regenerator runtime
对于库/工具来说, 如果你不需要像Array.prototype.includes这样的实例方法, 可以使用transform runtime插件, 而不是使用污染全局的@babel/polyfill
对于应用程序, 我们建议安装使用@babel/polyfill
@babel/polyfill的polypill, 其实它在Babel7.4.0以上已经不被推荐使用了。而是推荐使用core-js@3+@babel/preset-env然后设置@babel/preset-env的corejs选项为3