自 Babel 6 以后,Babel 将语法转换功能全都拆分成了一个个小模块。这些模块让人眼花缭乱,但官方贴心的提供了 Presets,用的最多的大概就是 ES2015 preset 了吧。再加上大多数项目为了减小项目体积,所以差不多都用了 transform-runtime。
大家的 .babelrc 文件可能就跟我下面这个一样:
{
"presets": ["es2015"],
"plugins": ["transform-runtime"]
}
可是,你真的看过 Bebel 处理过的代码吗?
之所以我会关注这个问题,是因为我有一个项目,明明没有用 babel-polyfill,可 Babel 处理后还是加入了 Symbol shim,而我根本没有在代码里使用过它。
我很好奇到底是哪个模块调用了这个函数,于是我在 Babel 生成的 js 文件里顺着模块 id 一路往上找,最后找到了 typeof。
typeof + Symbol,我一下子就想到了 ES2015 preset 里包含的这个插件:ES2015 typeof symbol transform
文档上说,转换后的代码是长这个样子的:
// In
typeof Symbol() === "symbol";
// Out
var _typeof = function (obj) {
return obj && obj.constructor === Symbol ? "symbol" : typeof obj;
};
_typeof(Symbol()) === "symbol";
但事实上,当你结合前面提到的 transform-runtime 一起使用时,它就会把整个 Symbol shim 给打包进去,即使你只是用 typeof 检测一个字符串而已。
transform-runtime 提供了配置可以选择要不要使用 polyfill:
{
"plugins": [
["transform-runtime", {
"polyfill": false,
"regenerator": false
}]
]
}
但是一点用也没有 😂
所以,为了代码里不要带上根本没有用到过的功能,最好的办法就是——不要偷懒使用 Presets,应该挨个评估项目里到底实际用到了哪些插件,并单独安装。