跳至主内容

7.8.0 版本发布:默认支持 ECMAScript 2020、.mjs 配置文件及 @babel/cli 改进

· 1 分钟阅读
非官方测试版翻译

本页面由 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 AliJack IsherwoodJayen AsharJames BeaversKlaus MeinhardtOleksandr FediashovSiddhant N TrivediTsubasa NakayamaYordis PrietoZYSzys

同时感谢 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 运算符允许在表达式结果为 nullundefined 时提供回退值:

JavaScript
const name = person.fullName ?? "Anonymous";
console.log(`Hello, ${name}!`);

这与逻辑 OR (||) 运算符的工作方式类似。区别在于:|| 检查"假值"(即 undefinednullfalse00n""),而 ?? 仅检查"空值"。这更符合"未提供值"的心智模型,并能更好地处理可能为假值但实际有效的情况:

JavaScript
const element = { index: 0, value: "foo" };

const index = element.index ?? -1; // 0 :D
const index = element.index || -1; // -1 :(

可选链提案采用了相同的"空值"概念,允许对可能为空值的属性进行可选访问。它还支持可选函数调用和计算属性。

JavaScript
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 中启用:如果您直接使用解析器,可以移除 nullishCoalescingOperatoroptionalChaining 解析器插件。我们还启用了动态 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 typebabel.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 typebabel.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.jsonbabel.config.mjs.babelrc.mjs,使 Babel 与 Node.js 原生支持的文件类型保持一致。

Node.js file typebabel.config.__.babelrc.__
.js✔️ Supported✔️ Supported
.json✔️ Supported✔️ Supported
.cjs✔️ Supported✔️ Supported
.mjs✔️ Supported✔️ Supported

请注意 ECMAScript 模块是异步的:这就是为什么您不能使用 require() 加载它们,而必须使用返回 Promise 的 import()

因此,这些配置文件仅能在通过基于 Promise 或回调的入口点调用 Babel 时使用。它们已兼容 @babel/clibabel-loadergulp-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 扩展名:

Shell
$ 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:导出了用于规范化指定目标环境的函数及其他相关工具:

    JavaScript
    import 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@2 polyfill 所需的浏览器版本信息。数据主要生成自 compat-table,未来可能会添加其他数据源。 如果需要 core-js@3 polyfill 的数据,可以使用 core-js-compat

我们计划从 Babel 8 开始禁止使用内部文件。如果你依赖其他内部 API,请告知我们!

引入可选的更严格 AST 验证 (#10917)

@babel/types 已执行多项检查以确保构建的 AST 有效。例如以下代码会报错,因为不能用语句替代表达式:

JavaScript
// 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 的插件。