Babel 的 useBuiltIns 配置到底该怎么用?
我最近在项目里配置 Babel,想用 useBuiltIns: 'usage' 来按需引入 polyfill,但发现打包后体积还是很大,而且有些新 API(比如 Array.prototype.flat)在低版本浏览器里依然报错。是不是我的配置哪里不对?
我的 .babelrc 是这样写的:
{
"presets": [
["@babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3
}]
]
}
代码里也确实用了 flat,比如:
const arr = [1, [2, [3]]];
console.log(arr.flat(2)); // 期望输出 [1, 2, 3]
但 Chrome 60 下直接报 flat is not a function,明明 core-js 3 应该支持这个方法的啊?是我漏了什么依赖还是配置写错了?
你的配置本身没问题,但漏了一个关键的东西:targets 配置。
useBuiltIns: 'usage' 的工作原理是 Babel 会根据你配置的目标浏览器来决定需要引入哪些 polyfill。你没写 targets,@babel/preset-env 默认会认为你要兼容所有现代浏览器,那自然就不会给 flat 方法注入 polyfill 了,因为它觉得目标浏览器都支持。
修改你的 .babelrc,加上 targets:
或者更好的做法是在 package.json 里配置 browserslist,这样所有工具都能共用:
另外还有几个常见的坑要注意一下。
确保你安装了 core-js 依赖,光配置 corejs: 3 是不够的:
如果你用的是 webpack 配合 babel-loader,改完配置后记得清一下缓存再重新打包,不然可能还是老样子。直接删掉 node_modules/.cache 目录就行。
还有个血泪教训:如果你项目里有些第三方库的代码没用 babel 转译,那那些代码里的新 API 是不会被检测到的。useBuiltIns: 'usage' 只能检测你自己的源码,第三方包里的 API 用法它管不了。这种情况要么换用 useBuiltIns: 'entry',要么手动在入口文件引入需要的 polyfill。