7.8.0 版本发布:默认支持 ECMAScript 2020、.mjs 配置文件及 @babel/cli 改进
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
这是今年的首个版本!🎉
Babel 7.8.0 现已默认支持新的 ECMAScript 2020 特性:使用 preset-env 时,不再需要单独启用 nullish coalescing (??)、optional chaining (?.) 和 dynamic import() 的插件。
我们还完成了不同配置文件与 Node.js 原生支持格式的对齐工作,这一进程始于 7.7.0 版本。
最后,Babel 的 CLI 新增支持两个选项:--out-file-extension 和 --copy-ignored。
您可以在 GitHub 上查阅完整更新日志。
特别鸣谢首次提交 PR 的贡献者:Abdul Ali、Jack Isherwood、Jayen Ashar、James Beavers、Klaus Meinhardt、Oleksandr Fediashov、Siddhant N Trivedi、Tsubasa Nakayama、Yordis Prieto 和 ZYSzys!
同时感谢 Thomas Smith 志愿维护重要的 babel-sublime 语法高亮插件,并欢迎新成员 Raja Sekar 加入 Babel 组织!
如果您或贵公司希望支持 Babel 和 JavaScript 的发展,可通过 Open Collective 进行捐赠,更可直接参与 新 ECMAScript 提案 的实现!作为志愿者驱动的项目,我们依赖社区支持来服务广大 JavaScript 用户。欢迎邮件联系 team@babeljs.io 进一步探讨!
我们近期发布了详细说明资金计划和目标的 资助方案文章,欢迎查阅!
默认支持 ECMAScript 2020 (#10811, #10817, #10819, #10843)
在最近的 TC39 会议 中,nullish coalescing 和 optional chaining 提案已同时进入 Stage 4!
nullish coalescing 运算符允许在表达式结果为 null 或 undefined 时提供回退值:
const name = person.fullName ?? "Anonymous";
console.log(`Hello, ${name}!`);
这与逻辑 OR (||) 运算符的工作方式类似。区别在于:|| 检查"假值"(即 undefined、null、false、0、0n 和 ""),而 ?? 仅检查"空值"。这更符合"未提供值"的心智模型,并能更好地处理可能为假值但实际有效的情况:
const element = { index: 0, value: "foo" };
const index = element.index ?? -1; // 0 :D
const index = element.index || -1; // -1 :(
可选链提案采用了相同的"空值"概念,允许对可能为空值的属性进行可选访问。它还支持可选函数调用和计算属性。
const city = person.address?.city; // person.address could be not defined
const isNeighbor = person.address?.isCloseTo(me);
person.sayHayUsing?.("Twitter"); // The person.sayHayUsing method could be not defined
现在您可以在代码中安全使用这些新特性!如果您正在使用 @babel/preset-env,您可以直接使用这两个运算符——它们将根据您的目标环境进行编译,就像其他 ECMAScript 特性一样。如果您之前直接使用了 @babel/plugin-proposal-nullish-coalescing-operator 或 @babel/plugin-proposal-optional-chaining,现在可以从配置中移除它们:
{
"presets": [
["@babel/env", { "targets": ["last 2 versions"] }]
],
"plugins": [
- "@babel/proposal-optional-chaining",
- "@babel/proposal-nullish-coalescing-operator"
]
}
这些特性现在也默认在 @babel/parser 中启用:如果您直接使用解析器,可以移除 nullishCoalescingOperator 和 optionalChaining 解析器插件。我们还启用了动态 import() 的解析(该特性自 v7.5.0 起已包含在 @babel/preset-env 中),因此您可以安全移除 dynamicImport 插件。
支持所有配置文件扩展名 (#10783 和 #10903)
Babel 6 仅支持基于 JSON 的单一配置文件:.babelrc。
在 Babel 7.0.0 中,我们引入了 babel.config.js(具有不同的解析逻辑)和 .babelrc.js。JavaScript 配置文件在需要更高灵活性的场景中非常有用。当时的情况如下:
| Node.js file type | babel.config.__ | .babelrc.__ |
|---|---|---|
.js | ✔️ Supported | ✔️ Supported |
.json | ❌ Not supported | ❔ Supported, with implicit extension |
我们强烈建议阅读 babel.config.js 和 .babelrc.js 的区别!
近期 Node.js 13.2.0 发布,新增了对原生 ECMAScript 模块及 .cjs 和 .mjs 文件扩展名的支持。我们在 Babel 7.7.0 中增加了 .cjs 配置文件支持,让用户可以在 package.json 中启用 "type": "module" 而不会破坏 Babel,同时增加了 babel.config.json 支持以实现静态的全项目配置。
| Node.js file type | babel.config.__ | .babelrc.__ |
|---|---|---|
.js | ✔️ Supported when "type": "module" is not enabled | ✔️ Supported when "type": "module" is not enabled |
.json | ✔️ Supported | ❔ Supported, with implicit extension |
.cjs | ✔️ Supported | ✔️ Supported |
.mjs | ❌ Not supported | ❌ Not supported |
本次更新通过支持 .babelrc.json、babel.config.mjs 和 .babelrc.mjs,使 Babel 与 Node.js 原生支持的文件类型保持一致。
| Node.js file type | babel.config.__ | .babelrc.__ |
|---|---|---|
.js | ✔️ Supported | ✔️ Supported |
.json | ✔️ Supported | ✔️ Supported |
.cjs | ✔️ Supported | ✔️ Supported |
.mjs | ✔️ Supported | ✔️ Supported |
请注意 ECMAScript 模块是异步的:这就是为什么您不能使用 require() 加载它们,而必须使用返回 Promise 的 import()。
因此,这些配置文件仅能在通过基于 Promise 或回调的入口点调用 Babel 时使用。它们已兼容 @babel/cli、babel-loader 和 gulp-babel,并将在下一版 rollup-plugin-babel 中支持。请注意目前暂不支持 babel-eslint。
新增 CLI 选项 (#9144 和 #10887)
我们为 @babel/cli 新增了两个标志:--copy-ignored 和 --out-file-extension。
--copy-ignored 用于复制未被 Babel 转译的文件(这些文件可能因使用 --ignore CLI 选项被忽略,或因配置文件中设置了 "ignore" 而被排除)。
为了保持向后兼容性,在 Babel 7.8.4 中 --copy-ignored 选项的默认值已改为 true。如果你想禁用它,可以使用 --no-copy-ignored。
这类似于 --copy-files 选项的工作方式,但 --copy-files 旨在复制未被转译的非 JavaScript 文件(例如 .css 或 .json),而非显式忽略的文件。
--out-file-extension 可用于配置 Babel 生成文件的扩展名。例如,如果你在 Node.js 中转译包含原生 ECMAScript 模块的 .js 文件,并希望生成 CommonJS 文件,可能需要使用 .cjs 扩展名:
$ babel src --out-dir lib-cjs --out-file-extension cjs
为 Babel 8 做准备
我们已开始在总揽 issue #10746 中着手 Babel 8.0.0 版本的开发。
Babel 8 将仅包含破坏性变更:我们会在同一天发布一个次要版本,其中包含原本计划在 8.0.0 中发布的所有错误修复和新功能。
虽然我们预计迁移路径不会很复杂,但有两个问题需要提请各位注意:
从 preset-env 中提取目标解析器和兼容性数据 (#10899)
目前各种第三方预设正在使用 @babel/preset-env 的内部逻辑来解析编译目标,或获取必要插件和 polyfill 的信息。
我们决定通过提供两个新的公共包来正式支持这两种使用场景:
-
@babel/helper-compilation-targets:导出了用于规范化指定目标环境的函数及其他相关工具:JavaScriptimport getTargets from "@babel/helper-compilation-targets";
getTargets({
browsers: ["last 2 chrome versions"],
node: 10,
}) ==
{
chrome: "77.0.0",
node: "10.0.0",
}; -
@babel/compat-data:包含一组 JSON 文件,存储了每个插件或core-js@2polyfill 所需的浏览器版本信息。数据主要生成自compat-table,未来可能会添加其他数据源。 如果需要core-js@3polyfill 的数据,可以使用core-js-compat。
我们计划从 Babel 8 开始禁止使用内部文件。如果你依赖其他内部 API,请告知我们!
引入可选的更严格 AST 验证 (#10917)
@babel/types 已执行多项检查以确保构建的 AST 有效。例如以下代码会报错,因为不能用语句替代表达式:
// foo = if (true) {}
t.assignmentExpression(
"=",
t.identifier("foo"),
t.ifStatement(t.booleanLiteral(true), t.blockStatement([]))
);
我们正在引入更严格的验证机制,不仅从树形结构角度防止无效 AST,还要确保正确位置的节点携带有效信息。例如从 Babel 8 开始,t.identifier("123") 将被禁止,因为 123 不是有效的标识符。
由于破坏现有插件的风险过高,我们无法在 Babel 7.8.0 中启用这些检查。但强烈建议你使用 BABEL_TYPES_8_BREAKING=true 环境变量启用严格检查,并提交 issue(或 PR!)修复你正在使用的、无法兼容 Babel 8 的插件。