babel 7+ 配置必须用 exports.default;targets 需明确指定浏览器版本;react 17+ 需 preset-react 启用 automatic runtime;避免 loose 全局启用和插件重复;现代 node_modules 包需显式转译。

babel.config.js 配置必须用 exports.default 而不是 module.exports
很多人在 babel.config.js 里写 module.exports = { presets: [...] },结果 Babel 完全不生效——尤其在 monorepo 或使用 @babel/cli 时。Babel 7+ 默认只认 exports.default,这是它读取配置的约定,不是可选项。
实操建议:
- 始终用
module.exports = { presets: [...] }是错的;正确写法是exports.default = { presets: [...] } - 如果项目用了 TypeScript,别在
babel.config.js里 import 类型,Babel 不执行 TS 编译;类型注解会直接报错SyntaxError: Unexpected token 'export' - 配置里加
sourceType: 'unambiguous'可避免 ES 模块识别失败,尤其处理无import/export但含async/await的文件时
@babel/preset-env 的 targets 必须明确指定浏览器范围
只写 { "presets": ["@babel/preset-env"] },Babel 默认按 targets: { node: "current" } 处理,结果代码完全没降级,Chrome 90+ 的特性原样输出,IE11 或 Safari 12 直接报错 SyntaxError: Invalid regular expression flag 'd'(因为 /d 标志未被转译)。
实操建议:
- 用
targets: { chrome: "58", safari: "12", ie: "11" }这类具体版本,而不是"last 2 versions"(后者对旧版浏览器覆盖不可靠) - 配合
core-js时,useBuiltIns: "usage"必须搭配corejs: 3,否则Array.from等新 API 不注入 polyfill - 若用 Webpack,确保
babel-loader的exclude没误排除node_modules中需转译的依赖(比如某些现代 UI 库)
JSX 和 React 用户必须配 @babel/preset-react,且注意 runtime 区别
React 17+ 默认启用新的 JSX 转换,但 Babel 不自动适配:没配 @babel/preset-react 时,<div></div> 会变成 React.createElement("div"),而新 runtime 要求 jsx 函数调用;结果运行时报错 ReferenceError: jsx is not defined。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
实操建议:
- React 17+ 必须加
{ runtime: "automatic" }到@babel/preset-react配置里,否则降级回 classic 模式,失去 fragment 和 props 透传优化 - 不要同时在
babel.config.js和.babelrc里定义 preset-react,Babel 会合并而非覆盖,导致 runtime 冲突 - SSR 场景下,服务端 Node 版本若低于 14.18,
runtime: "automatic"可能因缺少globalThis报错,需额外垫片或降级为classic
转译后代码体积暴增?检查 loose 模式和 plugin 重复
开启 loose: true 看似能减小体积,但会导致语义偏差:比如 class 转译后失去 new.target 支持,for...of 不再检查迭代器合法性,上线后偶发 TypeError: undefined is not a function。
实操建议:
- 禁用全局
loose: true;仅对确认安全的插件单独设,如@babel/plugin-proposal-class-properties可设{ loose: true } - 检查是否重复引入相同功能的 plugin:比如
@babel/preset-env已含transform-arrow-functions,再手动加该 plugin 会导致两次转译,生成冗余_this绑定 - 用
@babel/plugin-transform-runtime替代useBuiltIns: "usage"时,注意它默认不处理实例方法(如[].includes()),需额外配corejs: { version: 3, proposals: true }
最常被忽略的是 node_modules 中现代包的处理——你以为只转译自己代码就够了,但一旦用了 zod 或 valibot 这类零依赖、ESM-only 的库,它们的源码会直接进 bundle,浏览器一跑就挂。得在 babel-loader 或 swc 配置里显式 include 这些包。










