Babel 如何玩转 core-js@3?终极指南
【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js
还在为 build 产物里塞满用不上的 polyfill 头疼?花 10 分钟读完,咱们把 core-js@3 和 Babel 的配合一次讲透:entry 还是 usage、全局还是纯函数,选完直接动手。
先定位问题:polyfill 到底在替你扛什么
新代码爱用新 API:Object.fromEntries、Set的求并求差、structuredClone,换到老浏览器一跑,页面直接白屏 🤯。自己手写兜底?那是在重复造轮子。
core-js 就是干这个的:JavaScript 标准库的 polyfill 集合。三个特质决定了你怎么用它:
- 模块化:一个功能一个模块,要哪个引哪个,不用整包吞下
- 可纯函数化:不想污染全局命名空间?有专门版本,一个全局变量都不碰
- 覆盖广:最新 ECMAScript 标准、还在讨论的提案,以及
URL、queueMicrotask这类 WHATWG/W3C 相关 API 都能补
你可能早就在用它了——不少框架和构建工具内部就在悄悄注入 core-js,只是没人告诉你怎么选包、怎么配。下面逐个拆。
core-js 三个包到底怎么选
v3 把代码库拆成了三个包,对应三种诉求:
| 包 | 干什么的 | 碰全局吗 | 什么时候选它 |
|---|---|---|---|
core-js | 全局 polyfill,总量约 500KB | 是 | 应用入口,一次性补全 |
core-js-pure | 独立模块版 | 否 | 写库/组件,配合@babel/runtime-corejs3 |
core-js-bundle | 预打包好的全局版 | 是 | 不想自己管依赖,直接引 |
📦 命名上也有讲究:稳定标准的功能用es.前缀,比如es.promise.any;讨论中的提案用esnext.前缀,比如esnext.array.group-by。引的时候一眼能看出这个 API 是板上钉钉,还是还在路上。
另外 v3 把过时和非标准的功能清掉了,不再用 LiveScript,代码全部用现代 ES 语法重写,polyfill 的侵入等级还能配置——polyfill 本身也变干净了。
useBuiltIns 模式配置实战
corejs 选项:默认 2,记得改成 3
@babel/preset-env有个corejs选项,指定你用的 core-js 大版本。它的默认值还是 2。如果你升到了 v3 却忘了改它,生成的模块映射就是错的,这基本是迁移时必踩的坑 ⚠️。
{ "presets": [ ["@babel/preset-env", { "corejs": 3, "useBuiltIns": "usage" }] ] }配好之后,preset-env 的数据源也从旧的 compat-table 切到了core-js-compat。它直接读 core-js 自带的模块元数据加特性兼容表,判断某个 API 在目标环境里缺不缺。补什么、补多少,全靠真实数据,不再拍脑袋。polyfill 的注入顺序也重新排过,依赖更稳。
entry 还是 usage:一张表说清
| 模式 | 你的动作 | 适合谁 |
|---|---|---|
entry | 入口文件手写总 import,Babel 按 targets 裁剪 | 想可控、方便排查依赖的团队 |
usage | 什么都不写,Babel 扫代码按需注入 | 想省心、体积自动最优的项目 |
// entry 模式:入口文件写全量入口即可 import "core-js/es"; import "core-js/proposals/set-methods";entry 模式下,这种"全量写法"会被 Babel 根据 browserslist 优化成真正缺的那几个模块。大胆写全,体积它兜底。usage 模式从 Babel 7.4 起变得相当可靠:polyfill 检测更准,语法特性相关的也能跟着注入,proposals选项还能把提案功能纳入统计。
还有个历史遗留:@babel/polyfill已经弃用,别再引了。手动引入的话,换成这两行:
import "core-js/stable"; import "regenerator-runtime/runtime";@babel/runtime-corejs3:实例方法 polyfill 的归宿
再解决一个隐形痛点。默认配置下,@babel/plugin-transform-runtime把arr.map(...)这类实例方法编译成共享 helper 时,会动到原型链。多个库同时注入,就可能互相踩。
@babel/runtime-corejs3就是解药 💊:它底层用的是core-js-pure,每个方法独立成模块,不碰全局原型。你只需要在 transform-runtime 里声明 corejs 版本:
{ "plugins": [ ["@babel/plugin-transform-runtime", { "corejs": 3 }] ] }它还支持proposals选项把提案 API 也纳入转写,顺带修掉了Symbol.iterator提取这类历史 bug。分工很清楚:全局补全交给core-js,实例方法交给@babel/runtime-corejs3,两边互不干扰。
迁移 Checklist(照着勾就行)
- 检查
@babel/preset-env的corejs已设为 3,别让它停在默认值 2 - 删掉
@babel/polyfill引用,改用core-js/stable或 usage 模式 - 写库/组件的项目换用
core-js-pure+@babel/runtime-corejs3,守住全局命名空间 - 配好 browserslist,跑一次构建,确认 usage 模式下的产物确实变小了
- 提案功能用
core-js/proposals/*按个引入,别整个吞esnext
【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考