这几天又在折腾项目脚手架,看到之前的配置里用到 transform-runtime
,于是就想研究下。找了半天,发现现有的文章、讨论都没有准确、合理的说明,所以写篇博客介绍一下。
定位
@babel/preset-env
@babel/preset-env
是一大堆插件的集合,包含了当前浏览器环境下,所有语言特性的插件,可以根据 browserslist 的结果,选择合适的插件将新语言特性转译成旧浏览器可以支持的表达方式。
官方推荐使用预制件(preset),可以大大节省配置时间,提高开发效率。
@babel/plugin-transform-runtime
babel 转译时,往往需要用到一些工具函数,比如 _extend
。转译以文件为单位,意味着每个文件里都可能有重复的 babel 工具函数。现代化项目常有大量的文件,就可能产生重复和浪费。
@babel/plugin-transform-runtime
可以帮我们把直接写入文件里工具函数变成对 core-js
的引用,可以减少转译后的文件大小。
使用场景
从上面的定位可以看出,@babel/plugin-transform-runtime
跟 @babel/preset-env
并不重合,两者的功能没有交集。
对于任何需要考虑兼容性的项目,我们都应该使用 babel 进行转译,并使用 @babel/preset-env
降低配置的复杂度,大部分通用的配置如下:
module.exports = {
'presets': [
[
'@babel/preset-env',
{
'corejs': 3, // 使用 core-js@3 版本,core-js@2 从 ES2017 之后就没再更新了,不推荐使用
'useBuiltIns': 'usage', // 只转译用到的新语言元素
'bugfix': true, // v7.9 之后引入的新选项,尽量减小转译后的代码体积,v8 之后会变成默认选项
},
],
],
};
小型项目可以到此为止,中大型项目、文件数量比较多的,可以引入 @babel/plugin-transform-transform
。此时我们需要先安装两个依赖——注意,这俩依赖都要装:
# 用来开发、debug 和编译
npm i @babel/plugin-transform-runtime -D
# 用来在生产环境中使用
npm i @babel/runtime
# 如果要使用特定的 core-js 版本,也可以安装特定的 runtime
npm install --save @babel/runtime-corejs2
npm install --save @babel/runtime-corejs3
接下来,修改上面的 babel.config.js
,加入插件配置:
module.exports = {
// 重复上面的配置
"plugins": [
// 其它插件
[
"@babel/plugin-transform-runtime",
// 一般情况下我们使用默认配置即可
],
],
};
完成。
库项目
库类项目也推荐使用 @babel/plugin-transform-runtime
,因为库项目通常会面临另一个问题。如果我们直接导入 core-js 作 polyfill 的话,像 Promise
,Set
,Map
这样的全局对象就会被覆盖。对于一般的应用而言,问题不大;但如果是库,你无法预期其它开发者会在什么情况下使用你的库,很可能他的目标平台都支持这些新语法元素,不希望转译污染。
此时,使用 @babel/plugin-transform-runtime
可以让 babel 在转译时使用沙箱包装 polyfill,避免污染全局。
欢迎吐槽,共同进步