7.13.0发布——记录和图元,细化的编译器假设,以及顶级目标

73 阅读6分钟

7.13.0发布:记录和图元,细化的编译器假设,以及顶级目标

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

这个版本包括对@babel/core 的一些重要功能:一个可以在不同插件之间共享的targets 选项(类似于@babel/preset-env's one),一个可以精确调整配置以产生更小的编译输出的assumptions 选项,以及对使用本地ECMAScript模块编写的插件和预置的支持。

Babel现在支持转换Records和TuplesECMAScript提案,该提案为JavaScript带来了不可变的数据结构和结构平等,并支持解析Module Blocks提案。

此外,我们还增加了对一些新的Flow和TypeScript功能的支持。

你可以在GitHub上阅读完整的更新日志。

资助更新

我们已经加入了 "GitHub组织的赞助商 "计划,所以你现在可以直接通过GitHub赞助我们😊。

这些资金将用于支持我们的团队(目前有一名全职和三名兼职维护者)继续努力提高稳定性和开发新功能。

我们的捐款和支出都会通过我们的开放集体页面公开追踪,在这里我们也会追踪来自GitHub赞助商的捐款。

我们欢迎来自个人和公司的捐赠。如果你的公司有兴趣成为黄金级别的赞助商(1千美元/月),并希望讨论更多,请联系team@babeljs.io!

亮点

顶级的targets 选项(#12189,RFC)

@babel/preset-env targets 选项允许用户指定他们的目标环境,自动选择要转换的语法和要注入的polyfills。自从发布了 ,我们了解到插件@babel/preset-env本身也可以从了解你的目标中受益。目前,这可能有点麻烦,因为你必须指定你的目标两次(例如,如果你正在使用我们新的polyfill插件)。通过引入 作为顶级选项,你现在只需要指定一次你的目标。targets

旧配置新配置
{
  "presets": [
    ["@babel/preset-env", {
        "targets": ">1%, not ie 11"
    }]
  ],
  "plugins": [
    ["polyfill-es-shims", {
      "targets": ">1%, not ie 11"
    }]
  ]
}

|

{
  "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 选项

我们的许多插件都有一个loose 选项,它告诉Babel通过对您的代码进行某些假设并忽略JavaScript规范中的某些边缘情况来生成更小/更快的输出。

然而,loose 有一些问题,导致用户的困惑:这个术语本身无助于描述它究竟如何影响编译器的行为,更糟糕的是,有时需要为多个插件设置配置,以确保一切都能编译。

为了帮助解决这些问题,我们增加了一个新的顶层选项,告诉Babel它可以对你的代码做哪些假设。assumptions!与新的targets 选项类似,现在每个插件都会收到你所启用的假设,不需要再单独设置该选项。这真的很有价值,因为一个插件可以受到多个假设的影响,而一个假设可以影响多个插件。

⚠️这是高级功能。和之前的loose 选项一样,在启用假设时请小心,因为它们符合规范,可能会以意想不到的方式破坏你的代码。

例如,在转换类的时候,Babel会默认生成这个输出。

输入输出
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();

|

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 的类,所以你可以不用担心它的编译"。

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

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

|

let Test = function Test() {
  this.x = 2;
};

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

|

我们的文档中查看假设的完整列表,你可以单独启用或禁用它们,看看它们如何影响编译后的输出。

记录和图元支持

由于与彭博社的合作,Babel现在支持转换"记录和图元 "第二阶段的建议

Babel插件使用全局RecordTuple 函数对记录和图元的语法进行转换。

输入输出
let data = #{
  name: "Babel",
  ids: #[1, 2, 3]
};

|

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" />

注意:目前没有引擎支持记录和图元,所以你总是需要加载polyfill。

为了启用这种转换,你需要在你的配置中添加@babel/plugin-proposal-record-and-tuple

新的Flow功能

Babel 7.13.0支持两个新的Flow功能。

  • this 函数中的类型注解,允许你指定 对象的类型,就像它是一个参数一样。this

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

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

支持TypeScript 4.2

TypeScript 4.2支持一些新的语法特征,如抽象构造函数签名。

你可以在TypeScript发布的帖子中阅读更多关于这些变化。

@babel/runtime 中的自动 ES 模块

@babel/runtime 包含了CommonJS和ECMAScript模块格式的所有Babel运行时辅助工具。

到目前为止,你必须手动选择你想使用的模块,指定@babel/plugin-transform-runtimeuseESModules 选项。

我们现在已经重新组织了@babel/runtime 的内部结构,利用Node.js支持的新的 "exports"package.json 字段支持的Node.js和捆绑器,因此它们能够在CJS和ESM之间自动选择。

由于这个原因,useESModules 选项现在已被废弃,并将在Babel 8中被删除。