core-js 3 升级避坑指南:包怎么选、Babel 怎么配、polyfill 体积如何压到最小
【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js
core-js 3 升级后core-js/modules/...找不到?@babel/polyfill提示 deprecated?这篇文章一次解决三个决策:选对 core-js 包、选对入口级别、配好 Babel preset-env 与 swc,并给出把 polyfill 体积压到最小的完整方案。
一句话结论:绝大多数项目直接用全局版core-js+ 入口core-js/actual,Babel 侧配useBuiltIns: 'entry'并写出具体小版本号,剩下的是把targets收紧。
| 场景 | 选什么 | 说明 |
|---|---|---|
| 业务应用,愿意 patch 全局原型 | core-js | 全局版,polyfill 后直接调用原生写法 |
| 类库 / 不想污染全局命名空间 | core-js-pure | ponyfill,方法变成静态方法或独立导入 |
| 不想手动挑模块 | core-js-bundle | 预打包好的全局版 |
| 需要按目标引擎出定制包 | core-js-builder | 可排除特性或针对指定引擎生成 |
先做决策:包、入口和 Babel 配置怎么选
📌 这一步回答"我到底该 import 什么、配什么"。
包层面:core-js是全局版(polyfill 直接打到原生对象上);core-js-pure是"不污染全局"版——因为不能改原生原型,原型方法会以静态方法或独立函数形式提供;core-js-bundle就是前两者的打包产物。业务应用默认选全局版即可,库作者选 pure。
入口层面(全局版下,路径第一段就是加载范围):
core-js或core-js/full:一切,含早期 stage 提案,最重;core-js/actual:稳定 ES + Web 标准 + stage 3 提案——官方推荐档,既有"即将入标"的能力,又不掺实验性特性;core-js/stable:只有稳定部分(ES + Web 标准);core-js/es:仅稳定 ES,连 Web 标准都不含;- 单模块,如
core-js/actual/array/flat-map:按需精确加载。
如果团队是从 2 时代迁上来,最容易忽略的一点:入口从stable升到actual,Set方法、Promise.allSettled、Promise.any、String.prototype.replaceAll这类 stage 3 提案会自动进包;而 stage 1/2 的提案(Array.prototype.lastItem、Object.groupBy、iterator helpers 这类)不会,要用得显式引core-js/proposals/xxx。模块内部命名也已规范化:稳定功能es.前缀,提案功能esnext.前缀。
Babel 层面,先换掉已弃用的@babel/polyfill:
// 等价替代 @babel/polyfill import "core-js/stable"; import "regenerator-runtime/runtime"; // 生成器 / async 支持再配 preset-env:
// babel preset-env { targets: "> 0.25%, not dead", useBuiltIns: "entry", corejs: "3.50", }useBuiltIns: 'entry'会把你写的core-js入口自动改写成目标浏览器真正缺的那几个core-js/modules/...(所有入口级别、入口组合都适用);useBuiltIns: 'usage'则改为按文件静态分析、自动在文件顶部插入缺失模块——这种模式下不要再手写 core-js 导入,会重复。默认两者都只补稳定特性,要连提案一起补,加proposals: true(corejs: { version: "3.50", proposals: true })。
哪些是日常会用到的,哪些只是"可选件"
🧩 这一节把 3 时代新增能力分成两层,方便你判断入口档位和 proposals 开关。
日常高频:Array.prototype.flat/flatMap(ES2018)、Object.fromEntries(ES2019)、Symbol.prototype.description(ES2019)、ES2015 补齐的@@isConcatSpreadable与@@species——这些在 stable 里,写core-js/actual就都覆盖了。Web 标准侧则是完整实现的URL/URLSearchParams、queueMicrotask、DOM 集合的迭代器与forEach——跨端项目(尤其 Node + 浏览器同构)最容易在 URL 上踩空。
进阶可选:Array.prototype.lastItem/lastIndex、集合新方法、String.prototype.codePoints、Array.prototype.at的后续提案等 stage 1/2 特性。它们只在显式导入core-js/proposals/xxx或打开proposals: true时进入产物。建议:除非团队在主动跟进提案,否则别开——早期提案的 API 形态可能变,注入进产物等于给自己埋债。
Babel 与 swc 配置避坑:corejs 版本、usage 模式与注入冲突
⚠️ 配置坑比入口选择更致命,以下每一条都有真实翻车案例。
corejs: 3还是corejs: "3.50":必须写具体小版本号。只写大版本3时,小版本新增的模块不会被注入——你会得到"看起来配了、实际漏了"的产物。swc 同理(env: { targets, mode: "entry" | "usage", coreJs: "3.50" },其 usage 模式成熟度略逊于 Babel)。- usage 模式下别手写导入:polyfill 由 Babel 按文件自动注入,手写导入只会造成重复模块。
- preset-env 与 @babel/runtime 二选一配 corejs:两者功能重叠,同时配置会互相打架。
@babel/runtime的corejs: 3会把实例方法调用改写为core-js-pure导入(3 时代补上了实例方法 polyfill 这一历史短板),并同样支持proposals。 - 检测行为过严/过松:core-js 默认做 feature detection,原生实现坏了才 patch。个别环境检测太严(如 Promise 要求 unhandledrejection 支持)或环境有未覆盖的已知 bug 时,可用
core-js/configurator按 API 精细指定useNative/usePolyfill/useFeatureDetection——这是逃生门,不是常规选项。 - 自定义体积上限:要用到
modules内部路径或生成定制 bundle 时走core-js-builder,它依赖 core-js-compat 的目标环境数据;而 preset-env 本身在 3 时代也已把兼容性数据源切到 core-js-compat,不再吃旧的 compat-table。
行动清单
升级或核对 core-js 3 时,按顺序执行这五条:
- 检查依赖树:
core-js@2与@3不能混装;若因间接依赖锁死在 2,先升级依赖,而不是自己再装一份。 - 定包:应用用
core-js,库用core-js-pure;删掉@babel/polyfill,改引core-js/stable+regenerator-runtime/runtime。 - 定入口:业务代码统一
core-js/actual;确需提案再显式引core-js/proposals/xxx,而不是整体开 proposals。 - 定 Babel/swc:
useBuiltIns: 'entry'(或 usage)+ 具体小版本corejs: "3.50";preset-env 与 runtime 的 corejs 只在一处配置。 - 定体积:收紧
targets后核对构建产物,确认只剩目标缺失的模块;极限场景用core-js-builder按引擎出定制包。
参考文档:入口与 Babel 集成说明、项目更新日志。
【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考