Babel 的 useBuiltIns 配置到底该怎么用?

星语 阅读 6

我最近在项目里配置 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 应该支持这个方法的啊?是我漏了什么依赖还是配置写错了?

我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
爱学习的瑞雪
这个问题我之前踩过坑,折腾了大半天才发现原因。

你的配置本身没问题,但漏了一个关键的东西:targets 配置。

useBuiltIns: 'usage' 的工作原理是 Babel 会根据你配置的目标浏览器来决定需要引入哪些 polyfill。你没写 targets,@babel/preset-env 默认会认为你要兼容所有现代浏览器,那自然就不会给 flat 方法注入 polyfill 了,因为它觉得目标浏览器都支持。

修改你的 .babelrc,加上 targets:

{
"presets": [
["@babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3,
"targets": {
"chrome": "60"
}
}]
]
}


或者更好的做法是在 package.json 里配置 browserslist,这样所有工具都能共用:

{
"browserslist": ["Chrome >= 60"]
}


另外还有几个常见的坑要注意一下。

确保你安装了 core-js 依赖,光配置 corejs: 3 是不够的:

npm install core-js


如果你用的是 webpack 配合 babel-loader,改完配置后记得清一下缓存再重新打包,不然可能还是老样子。直接删掉 node_modules/.cache 目录就行。

还有个血泪教训:如果你项目里有些第三方库的代码没用 babel 转译,那那些代码里的新 API 是不会被检测到的。useBuiltIns: 'usage' 只能检测你自己的源码,第三方包里的 API 用法它管不了。这种情况要么换用 useBuiltIns: 'entry',要么手动在入口文件引入需要的 polyfill。
点赞
2026-03-01 12:01