浏览器对新语法的支持总是滞后于标准演进:可选链 ?.、空值合并 ??、箭头函数在老浏览器里是语法错误(不是功能缺失——根本解析不了)。Babel 的 parser 解析源码生成 AST,插件遍历 AST 做语法转换(如把 ?. 转成三元判断),最终输出目标环境的兼容 JS。
区分语法(syntax)与 API/功能(polyfill):Babel 转语法;Object.assign、Array.includes 这类新方法是运行时缺失,要 core-js polyfill 补齐(Babel 7 用 @babel/preset-env 按 browserslist 按需 polyfill)。JSX 与 TS 的处理也走 Babel 插件链(@babel/preset-react/@babel/preset-typescript)。
// .babelrc / babel.config.js { "presets": [ ["@babel/preset-env", { "targets": "> 0.25%, not dead", // ← browserslist 目标 "useBuiltIns": "usage", // 按代码里用到的 API 按需 polyfill "corejs": 3 }], "@babel/preset-react", // JSX "@babel/preset-typescript" // TS(仅去类型,不做类型检查) ] } // 转换示例 // 源码 const x = obj?.a ?? 'default'; // 目标(旧浏览器) var _obj$a; var x = (_obj$a = obj == null ? void 0 : obj.a) != null ? _obj$a : 'default';