npm装了八年Babel,今天终于把8.0的迁移账算清楚了——官方这四个改动最大
npm装了八年Babel,今天终于把8.0的迁移账算清楚了——官方这四个改动最大,动手之前先把配置改好。
先搞清楚这次升级的核心逻辑
Babel 8 正式发布了(2026年6月16日)。八年了,Babel 7 一直是大多数前端项目的转译底座,这次 8.0 不是功能大升级,是核心假设变了:Babel 认为你的代码不需要再默认编译到 ES5 了。
这个判断合理吗?合理。IE11 死了,主流浏览器全部支持 ES6+,Node.js 22+ 全面支持 ESM。Babel 官方数据显示每周下载量从 2018 年的 170 万增长到 2026 年的 6.51 亿,翻了 380 倍——生态已经足够成熟,是时候推一把了。
但这个判断带来的迁移工作量,一点都不小。
改动一:ESM-only,Node.js 版本门槛
Babel 8 现在只以 ESM 形式发布,依赖 Node.js ^22.18.0 或 >=24.11.0。Node.js 20 和 25 已经 EOL(end-of-life)。
这意味着:只要你的 CI/CD、构建机器、本地开发环境里有任何一台跑着 Node 20 或更早版本,Babel 8 在那台机器上就跑不起来。
迁移步骤:
# 先检查当前 Node 版本
node -v
# 推荐统一升级到 Node 24 (Active LTS)
# nvm install 24 && nvm use 24
升级之后,你的 CI 配置文件(.github/workflows/*.yml、GitLab CI 的 image 字段、Dockerfile 的 FROM node:…)全部要同步更新。如果你在公司内网用 Yarn Berry 或 pnpm 的指定 Node 版本策略,也要相应调整。
改动二:不再默认编译到 ES5——targets 行为变了
这是影响最广的 breaking change。
Babel 7 的默认行为:所有代码都会被编译到 ES5,除非你手动配置 targets。
Babel 8 的默认行为:不再主动降级,转而使用 Browserslist 的 defaults 查询——当前默认值约等于 ES2023,也就是目标浏览器是所有「默认」浏览器的新版本。
这带来的实际影响:如果你之前没有配置过 @babel/preset-env 的 targets,你的构建产物会从「全部转译为 ES5」变成「保持 ES2023 语法」。bundle 体积可能会显著减小,但如果你的产品需要支持老版本 Chrome/Safari,代码可能直接报错。
官方推荐的迁移动作:
第一步,在项目根目录新建或更新 .browserslistrc:
# .browserslistrc
defaults
# 或者如果你需要兼容具体版本
ie > 10
chrome >= 60
第二步,检查你现有的 Babel 配置:
// babel.config.js 或 babel.config.json
module.exports = {
// Babel 7: 默认 targets: ">= 0.5%"
// Babel 8: 默认 targets: "defaults" (约等于 ES2023)
// 如果你之前在 preset-env 里写了 targets,要把它挪到顶层
targets: "> 0.25%, not dead",
// 或者从 .browserslistrc 读取,不需要在这里重复写
presets: [
["@babel/preset-env", {
// 开启 bugfixes,编译更精确
bugfixes: true,
}]
]
}
关键原则:把 targets 放在顶层配置,而不是 preset-env 里面。这样所有插件都能共享同一份目标环境定义。
改动三:loose/spec 选项 → assumptions
Babel 7 时代,很多项目会这样配置:
preset-env: {
loose: true, // 输出更小,但可能不符合规范
spec: false
}
Babel 8 把这两个选项删了。替代方案是 assumptions——更细粒度,更精确。
// Babel 8
module.exports = {
// assumptions 是顶层选项,所有插件共享
assumptions: {
setPublicClassFields: true,
privateFieldsAsProperties: true,
constantSuper: true,
noDocumentAll: true,
// ...按需开启
},
presets: ["@babel/preset-env"]
}
官方文档里有一张完整的对照表(babeljs.io/docs/assumptions#migrating-from-babelpreset-envs-loose-and-spec-modes),建议你迁移前先对着表把自己的 loose/spec 配置翻译成 assumptions。
改动四:corejs/useBuiltIns 迁移路径变了
Babel 7 时代,很多项目用这个方式引入 polyfill:
preset-env: {
useBuiltIns: "entry", // 或 "usage"
corejs: 3
}
Babel 8 把这个路径废弃了,改用独立插件 babel-plugin-polyfill-corejs3。
npm install babel-plugin-polyfill-corejs3 --save-dev
// babel.config.js
module.exports = {
plugins: [
// 在所有 transform 插件之后引入
"babel-plugin-polyfill-corejs3"
]
}
这个改动稍微麻烦一些,因为原来在 preset-env 里一行配置搞定的事,现在要单独装插件并在 plugins 数组里正确排序。如果你用 @babel/preset-env 的 useBuiltIns 已经有稳定产出,建议在升级 Babel 8 之前先把这一步迁移完,避免两个迁移叠加排查困难。
迁移建议的优先级
按影响面和风险从大到小排序:
- 先升级 Node.js 到 22+——这是门槛,不过这关后面所有事情都跑不了
- 检查 targets 配置,补上 .browserslistrc——决定你输出代码的语法级别,最影响线上行为
- 把 loose/spec 迁到 assumptions——如果你的项目没用到这两个选项,跳过即可
- 处理 corejs polyfill——如果没有 polyfill 需求,跳过
- React JSX runtime 切换——Babel 8 默认用 automatic runtime 而不是 classic,如果你的项目是 React 17+ 且还没迁移到新的 JSX transform,需要注意这个选项
最后
Babel 8 的迁移没有 Babel 5→6 或 6→7 那么剧烈,但涉及面广:Node 版本门槛、默认编译目标的根本性改变、polyfill 注入方式的替换,每一项单独看都不复杂,叠加在一起容易踩坑。
建议的策略:不要一口气升级。先在 dev 分支把所有配置改好,跑通构建,再合并回主分支。Babel 官方也给了一年的安全支持周期(Babel 7 到 2027 年 6 月),时间窗口是够的。
评论区
登录后可评论。