跳至主内容

7.13.0 版本发布:记录与元组、细粒度编译器假设及顶层 targets 选项

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

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

我们刚刚发布了 Babel 7.13.0,这是 2021 年的首个次要版本!

本次更新为 @babel/core 带来多项重要特性:可在不同插件间共享的 targets 选项(类似于 @babel/preset-env 的对应功能)、用于精确调整配置以生成更小编译产物的 assumptions 选项,以及对原生 ECMAScript 模块编写的插件和预设的支持。

Babel 现已支持转换 记录与元组 ECMAScript 提案(该提案为 JavaScript 带来不可变数据结构和结构相等性),并支持解析模块块提案。

此外,我们还新增了对部分 Flow 和 TypeScript 新特性的支持。

完整更新日志请参阅 GitHub

资金更新

我们已加入 "GitHub Sponsors for organizations" 计划,现在您可以直接通过 GitHub 赞助我们 😊。

这些资金将用于支持团队(目前含一名全职和三名兼职维护者)持续改进稳定性和开发新功能。

所有捐款与支出均通过 Open Collective 页面公开追踪,我们也将在此记录来自 GitHub Sponsors 的捐款。

欢迎个人和企业捐赠。若贵公司有意成为黄金级赞助商(每月 $1k)并希望进一步沟通,请联系 team@babeljs.io

重点更新

顶层 targets 选项 (#12189, RFC)

@babel/preset-envtargets 选项允许用户指定目标环境,自动选择需转换的语法和需注入的 polyfill。自 @babel/preset-env 发布以来,我们发现插件本身也能从获知目标环境中获益。目前这存在重复配置问题(例如使用新版 polyfill 插件时需两次指定目标)。通过引入顶层 targets 选项,现在只需配置一次:

Old configurationNew configuration
babel.config.json
{
"presets": [
["@babel/preset-env", {
"targets": ">1%, not ie 11"
}]
],
"plugins": [
["polyfill-es-shims", {
"targets": ">1%, not ie 11"
}]
]
}
JSON
{
"targets": ">1%, not ie 11",
"presets": ["@babel/preset-env"],
"plugins": ["polyfill-es-shims"]
}

建议您将 Babel 配置迁移至新的顶层 targets 选项,其额外优势包括:

  1. 更完善地处理 esmodules: true 目标(会与其他目标取交集而非替换)

  2. 当我们在插件中引入更多 targets 相关优化时,您将自动获得更精简的编译产物!

此新选项的详细说明请参阅其 RFC

🔮 未来我们可能将 @babel/preset-env 整合进 @babel/core,让您无需额外安装包即可使用 Babel。此新选项可视为该方向的第一步!

顶层 assumptions 选项 (#12219, RFC)

我们许多插件都提供了 loose 选项,它通过让 Babel 对您的代码做出某些假设并忽略 JavaScript 规范中的特定边界情况,从而生成更小更快的输出。

然而 loose 存在一些问题导致用户困惑:这个术语本身无法准确描述它对编译行为的实际影响,更糟的是有时需要为多个插件单独设置配置才能确保正常编译。

为解决这些问题,我们新增了顶层选项 assumptions 来告诉 Babel 可以对代码做出哪些假设!类似新的 targets 选项,所有插件现在都能接收您启用的假设,无需再单独配置选项。这非常实用,因为单个插件可能受多个假设影响,而单个假设也可能影响多个插件。

注意

这是高级功能。与之前的 loose 选项类似,启用假设时请务必谨慎,因为它们不符合规范要求,可能导致代码出现意外错误。

例如在转换类时,Babel 默认会生成以下输出:

InputOutput
JavaScript
class Test {
constructor() {
this.x = 2;
}
}

// You can test the thrown error in the console:
// Uncaught TypeError: class constructors must be invoked with 'new'
Test();
JavaScript
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}

let Test = function Test() {
_classCallCheck(this, Test);

this.x = 2;
};

// You can test the thrown error in the console:
// Uncaught TypeError: class constructors must be invoked with 'new'
Test();

但启用 noClassCalls 假设后,相当于告诉 Babel "我永远不会尝试不用 new 调用类",因此可以简化编译:

JSON
{
"targets": "firefox 30",
"assumptions": { "noClassCalls": true },
"presets": ["@babel/preset-env"]
}
InputOutput
JavaScript
class Test {
constructor() {
this.x = 2;
}
}

// Won't throw since we violated the assumption
Test();
JavaScript
let Test = function Test() {
this.x = 2;
};

// Won't throw since we violated the assumption
Test();

请查阅文档中的完整假设列表,您可以单独启用或禁用它们,查看对编译输出的具体影响。

Records 和 Tuples 支持 (#12145)

通过与彭博社的合作,Babel 现已支持转换"Records 和 Tuples"第二阶段提案

Babel 插件通过全局 RecordTuple 函数转换 records/tuples 语法:

InputOutput
JavaScript
let data = #{
name: "Babel",
ids: #[1, 2, 3]
};
JavaScript
let data = Record({
name: "Babel",
ids: Tuple(1, 2, 3),
});

这意味着您需要加载这些全局函数的 polyfill,例如 @bloomberg/record-tuple-polyfill,可通过代码导入或 <script> 标签引入:

<script src="https://unpkg.com/@bloomberg/record-tuple-polyfill@0.0.3/lib/index.umd.js" />

注意:目前尚无引擎原生支持 records/tuples,因此必须加载 polyfill。

要启用此转换,请在配置中添加 @babel/plugin-proposal-record-and-tuple

Flow 新特性支持 (#12193, #12234)

Babel 7.13.0 支持两项 Flow 新特性:

  • 函数中的 this 类型注解,可像参数一样指定 this 对象的类型

    JavaScript
    function getPerson(this: Database, id: string): Person {
    this instanceof Database; // true
    }
  • 包含未知成员的 enum 声明

    JavaScript
    enum PetKind {
    Dog,
    Cat,
    Snake,
    ...
    }

TypeScript 4.2 支持 (#12628)

TypeScript 4.2 新增支持抽象构造函数签名等语法特性。

详见 TypeScript 发布说明了解具体变更。

@babel/runtime 自动支持 ES 模块 (#12632)

@babel/runtime 包含了所有 Babel 运行时辅助函数,同时提供 CommonJS 和 ECMAScript 模块两种格式。

在此之前,您必须通过指定 @babel/plugin-transform-runtimeuseESModules 选项来手动选择要使用的格式。

现在,我们已重组 @babel/runtime 的内部结构,利用 Node.js 和打包器支持的 "exports" package.json 字段,使其能够自动在 CJS 和 ESM 之间进行选择。

因此,useESModules 选项现已弃用,并将在 Babel 8 中移除。