Babel 是现代 JavaScript 工程的必需工具,用于将新语法转为旧环境兼容代码;默认不转换需显式配置 presets(如 @babel/preset-env)或 plugins,且需注意模块处理、polyfill 注入等关键细节。

Babel 不是“可选工具”,而是现代 JavaScript 工程的呼吸阀——没有它,const、async/await、class 甚至 ?. 都可能在 IE11 或旧版 Node.js 中直接报 SyntaxError: Unexpected token。
为什么 npx babel src --out-dir dist 默认不生效?
刚装完 @babel/core 和 @babel/cli,执行命令却原样输出代码,不是 Babel 失灵,是你没告诉它“要转什么”。Babel 默认不做任何转换,必须显式指定 --presets 或 --plugins。
- 只装
@babel/core不够,@babel/cli才提供命令行入口 - 不加
--presets=@babel/preset-env,箭头函数、解构赋值等一个都不会动 -
.babelrc和babel.config.js不能混用:项目根目录优先读babel.config.js,而.babelrc只对当前及子目录生效,单页应用里容易漏配
@babel/preset-env 怎么自动判断该转哪些语法?
它不是靠猜,而是查你配置的 targets(比如 {"chrome": "58", "ie": "11"}),再对照 ECMAScript compatibility table,只启用真正需要的插件。例如 Chrome 58 已原生支持 Promise,preset-env 就不会注入 core-js 的 polyfill。
- 别写死
{"ie": "11"}却忘了配useBuiltIns: 'usage'—— 否则Array.from()这类 API 仍会运行时报错 -
targets.node = "current"表示按当前node -v版本裁剪,适合纯 Node 服务端项目 - 用
debug: true可打印出实际启用的插件列表,排查“为什么这个语法没转”时极有用
为什么 import 没报错,但运行时提示 ReferenceError: exports is not defined?
这是典型的模块系统错配:@babel/preset-env 默认只转语法,不处理模块。ES6 import/export 在浏览器里根本无法原生执行,必须配合打包器(如 Webpack)或额外配置。
立即学习“Java免费学习笔记(深入)”;
- 单独用 Babel 编译时,需加
modules: 'commonjs'(默认值),否则输出仍是import,浏览器直接拒收 - 若目标是浏览器且不用打包器,得换用
modules: 'umd'或'systemjs',并手动引入模块加载器 -
export default转成module.exports =后,Node.js 才能require();但反过来,ESM 环境下require()会失效——环境和输出格式必须对齐
最常被忽略的一点:Babel 只管语法转换,不负责运行时补丁。Array.prototype.flatMap 这种新增 API,即使语法合法,旧环境仍会 undefined is not a function。这时候必须搭配 @babel/plugin-transform-runtime 或按需引入 core-js,且注意 polyfill 的注入时机——放在所有业务代码之前,否则白加。











