plugin-transform-runtime
一、认识
利用 @babel/preset-env
进行了 目标浏览器语法的降级 和 Polyfill
注入,同时用到了 core-js
和regenerator-runtime
两个核心的运行时库。但 @babel/preset-env
的方案也存在一定局限性:
-
如果使用新特性,往往是通过基础库(如
core-js
)往全局环境添加Polyfill
,如果是开发应用没有任何问题,如果是开发第三方工具库,则很可能会对全局空间造成污染。 -
很多工具函数的实现代码(如上面示例中的
_defineProperty
方法),会在许多文件中重现出现,造成文件体积冗余。
plugin-transform-runtime
为了解决 @babel/preset-env
的种种局限性。plugin-transform-runtime
方案可以作为 @babel/preset-env
中 useBuiltIns
配置的替代品,也就是说,一旦使用 plugin-transform-runtime
方案,你应该把 useBuiltIns
属性设为 false
。
二、安装
安装必要编译时依赖:
pnpm install @babel/cli @babel/core @babel/preset-env @babel/plugin-transform-runtime -D
-
@babel/cli
: 为babel
官方的脚手架工具 -
@babel/core
:babel
核心编译库。 -
@babel/preset-env
:babel
的预设工具集,基本为babel
必装的库。 -
@babel/plugin-transform-runtime
: 用来转换语法和添加Polyfill
安装必要运行时依赖:
pnpm i @babel/runtime-corejs3 -S
@babel/runtime-corejs3
: 运行时基础库,封装了core-js
、regenerator-runtime
和各种语法转换用到的工具函数。core-js
有三种产物,分别是core-js
、core-js-pure
和core-js-bundle
。第一种是全局Polyfill
的做法,@babel/preset-env
就是用的这种产物;第二种不会把Polyfill
注入到全局环境,可以按需引入;第三种是打包好的版本,包含所有的Polyfill
,不太常用。@babel/runtime-corejs3
使用的是第二种产物。
三、配置
3.1 .browserslistrc
Browserslist
是一个帮助我们设置目标浏览器的工具,不光是 Babel
用到,其他的编译工具如postcss-preset-env
、autoprefix
中都有所应用。对于 Browserslist
的配置内容,你既可以放到 Babel
这种特定工具当中,也可以在package.json
中通过browserslist
声明:
ie >= 11
3.2 babel.config.js
export default {
presets: [
[
'@babel/preset-env',
{
corejs: 3,
modules: false,
useBuiltIns: false
}
]
],
plugins: [
[
'@babel/plugin-transform-runtime',
{
corejs: 3
}
]
]
};
四、测试
4.1 index.js
const func = async ()=>{
console.log("Hello World!")
}
func();
Promise.resolve().finally();
4.2 命令行输入
npx babel ./index.js --out-dir dist
使用 Babel
进行编译
效果如下:
plugin-transform-runtime
一方面能够让我们在代码中使用非全局版本的 Polyfill
,这样就避免全局空间的污染,这也得益于 core-js
的 pure
版本产物特性;另一方面对于 asyncToGeneator
这类的工具函数,它也将其转换成了一段引入语句,不再将完整的实现放到文件中,节省了编译后文件的体积。
另外,transform-runtime
方案引用的基础库也发生了变化,不再是直接引入core-js
和regenerator-runtime
,而是引入@babel/runtime-corejs3
。