跳到主要内容

plugin-transform-runtime

2023年12月21日
柏拉文
越努力,越幸运

一、认识


利用 @babel/preset-env 进行了 目标浏览器语法的降级Polyfill 注入,同时用到了 core-jsregenerator-runtime两个核心的运行时库。但 @babel/preset-env 的方案也存在一定局限性:

  • 如果使用新特性,往往是通过基础库(如 core-js)往全局环境添加 Polyfill,如果是开发应用没有任何问题,如果是开发第三方工具库,则很可能会对全局空间造成污染。

  • 很多工具函数的实现代码(如上面示例中的_defineProperty方法),会在许多文件中重现出现,造成文件体积冗余。

plugin-transform-runtime 为了解决 @babel/preset-env 的种种局限性。plugin-transform-runtime 方案可以作为 @babel/preset-envuseBuiltIns 配置的替代品,也就是说,一旦使用 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-jsregenerator-runtime和各种语法转换用到的工具函数。 core-js 有三种产物,分别是core-jscore-js-purecore-js-bundle。第一种是全局 Polyfill 的做法,@babel/preset-env 就是用的这种产物;第二种不会把 Polyfill 注入到全局环境,可以按需引入;第三种是打包好的版本,包含所有的 Polyfill,不太常用。@babel/runtime-corejs3 使用的是第二种产物。

三、配置


3.1 .browserslistrc

Browserslist 是一个帮助我们设置目标浏览器的工具,不光是 Babel 用到,其他的编译工具如postcss-preset-envautoprefix中都有所应用。对于 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 进行编译

效果如下:

Preview

plugin-transform-runtime 一方面能够让我们在代码中使用非全局版本的 Polyfill,这样就避免全局空间的污染,这也得益于 core-jspure 版本产物特性;另一方面对于 asyncToGeneator 这类的工具函数,它也将其转换成了一段引入语句,不再将完整的实现放到文件中,节省了编译后文件的体积。

另外,transform-runtime方案引用的基础库也发生了变化,不再是直接引入core-jsregenerator-runtime,而是引入@babel/runtime-corejs3