7.14.0版发布——默认启用新的类特性,TypeScript 4.3,以及更好的CommonJS互操作

98 阅读5分钟

7.14.0版发布:默认启用新的类功能,TypeScript 4.3,以及更好的CommonJS互操作

Babel 7.14.0发布了!

这个版本默认启用了类字段和私有方法(它们在最近的4月TC39会议上被提升到了第四阶段!),并在@babel/preset-env'sshippedProposals 选项中增加了对私有字段和静态类块的品牌检查。

我们增加了对第1阶段异步do表达式的支持(使用@babel/plugin-proposal-async-do-expressions ),这扩展了第1阶段do表达式的提议。

感谢Sosuke SuzukiPig Fang,Babel现在可以处理TypeScript 4.3的特性。@babel/parser 也有一个新的选项来正确解析TypeScript声明文件。

最后,我们引入了一个新的importInterop: node 选项,通过编译ECMAScript导入到遵循Node.js语义的CommonJS,使其更容易产生双模块。

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

如果你或你的公司想支持Babel和JavaScript的发展,但不确定如何支持,你可以在我们的开放集体上为我们捐款,更好的是,直接与我们合作实现新的ECMAScript建议作为一个志愿者驱动的项目,我们依靠社区的支持来资助我们支持广大的JavaScript用户。如果你想讨论更多,请联系team@babeljs.io!

亮点

默认启用新的类特性

类的字段和私有方法建议刚刚达到第四阶段,将正式纳入ECMAScript 2022!这更像是一种形式,因为语义已经敲定,而且已经在所有主要浏览器中实现。

你可以在MDN上阅读更多关于这个新语法的细节(公共字段私有字段和方法)。

class Check {
  static className = "Check"; // static public class field
  
  #value = 3; // # means private!
  
  get #double() { // private getter
    return this.#value * 2; // using a private field
  }
}

因此,你可以删除@babel/plugin-proposal-class-properties@babel/plugin-proposal-private-methods ,因为它们现在已经被默认启用在 @babel/preset-env.

⚠️ Webpack从v5.36.0开始就支持这种语法。对于较早的版本,一个适用于较简单的Webpack设置的变通方法是手动启用acorn-stage3 插件,方法是安装acorn-stage3 ,并在你的webpack.config.js 文件的开头添加这些行。

const acorn = require(require.resolve("acorn", { paths: [require.resolve("webpack")] })); // Require webpack's acorn dependency
acorn.Parser = acorn.Parser.extend(require("acorn-stage3")); // Enable the Stage 3 plugin

如果这对你不起作用,或者你使用的是不支持类字段的不同工具,你仍然需要使用Babel插件来转换它们。

如果你正在使用@babel/preset-env's shippedProposals选项,它现在也包括了@babel/plugin-proposal-private-property-in-object7.10中引入)和@babel/plugin-proposal-class-static-block7.12中引入)插件:你可以安全地从你的配置中删除它们。

class Foo {
  #bar = "bar";

  test(obj) {
    return #bar in obj; // private-property-in-object
  }
  
  static #x = 42;
  static y;
  static { // static block
    try {
      this.y = doSomethingWith(this.#x);
    } catch {
      this.y = "unknown";
    }
  }
}

更好的ESM-CJS互操作

当从ECMAScript模块中导入CommonJS文件时,Node.js的语义与JavaScript生态系统中的大多数工具不同。

假设你依赖于以下库。

export default function two() {
  return 2;
}

而这个库的作者并没有按原样发布,而是将其编译成CommonJS。

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.default = two;

function two() {
  return 2;
}

当用Babel(或TypeScript、Rollup或类似的工具)导入这个库,并将你的代码编译到CommonJS时,它看起来就像。

import two from "two";
console.log(two());

有一天,你决定提供两个版本的代码:一个是编译后的CommonJS版本,一个是使用本地ECMAScript模块的版本。

虽然编译后的版本可以工作,但ESM的版本会抛出TypeError: two is not a function 。这是因为在Node.js中,默认导入的不是依赖关系的exports.default ,而是整个module.exports 对象。

你可以把你的代码改成。

import two from "two";
console.log(two.default());

然而,这段新的代码有一个问题:它现在在编译的时候不能工作,因为two.default 不是一个函数。

Babel v7.14.0在插件中增加了一个新的importInterop: "node" 选项。 @babel/plugin-transform-modules-commonjs插件中增加了一个新的选项,允许import 语句与本地Node.js行为相匹配。你可以在文档中阅读更多关于这个选项的内容。

我们团队的Nicolò也为@rollup/plugin-commonjs贡献了一个类似的选项,它将在下一个版本中出现。我们的目标是通过提供一个更简单的迁移路径来帮助生态系统迁移到本地ECMAScript模块。

TypeScript 4.3

新的TypeScript版本将在5月以稳定版发布,支持一些新的功能。

  • override 类元素中的修改器
  • 类中的静态索引签名 ([key: KeyType]: ValueType)
  • get/set 在类型声明中

你可以在TypeScript 4.3的发布帖子中阅读更多关于它们的内容。这是通过@babel/preset-typescript支持的。

async do 表达式

async do 表达式是建立在do 表达式建议之上的第一阶段建议。

它们允许在同步代码中使用异步块,并且这些块被评估为一个承诺。

function sync() {
  let x = async do {
    let res = await Promise.resolve("Third!");
    console.log("Second!");
    res;
  };
  console.log("First!");
  x.then(console.log);
}

console.log(sync());
// Logs:
// - "First!"
// - "Second!"
// - "Third!"

你可以通过在插件中添加以下内容来测试这个建议(并报告反馈!):1. @babel/plugin-proposal-do-expressions@babel/plugin-proposal-async-do-expressions插件加入到你的Babel配置中。

⚠️这些建议是高度实验性的。它们可以,而且可能会继续发展。在它们被标准化之前可能需要几年时间,甚至可能被完全拒绝。我们欢迎你测试它们,但我们不建议在生产中使用它们。