7.14.0 发布:默认启用新类特性、支持 TypeScript 4.3 及改进 CommonJS 互操作性
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
Babel 7.14.0 正式发布!
本次更新默认启用了类字段和私有方法(它们在四月最近的 TC39 会议中已晋升至 Stage 4!),并在 @babel/preset-env 的 shippedProposals 选项中新增了对私有字段和静态类块的品牌检查支持。
我们新增了对 Stage 1 异步 do 表达式的支持(通过 @babel/plugin-proposal-async-do-expressions 插件),该特性扩展了 Stage 1 do 表达式提案。
感谢 Sosuke Suzuki 和 Pig Fang,Babel 现已支持 TypeScript 4.3 特性。@babel/parser 同时新增了选项以正确解析 TypeScript 声明文件。
最后,我们引入了新的 importInterop: node 选项,通过将 ECMAScript 导入编译为遵循 Node.js 语义的 CommonJS 格式,更轻松地生成双模式模块。
您可在 GitHub 查阅完整更新日志。
若您或公司希望支持 Babel 及 JavaScript 生态发展,可通过 Open Collective 进行捐赠,更可直接参与新 ECMAScript 提案的实现!作为志愿者驱动的项目,我们依赖社区支持来服务广大 JavaScript 用户。欢迎通过 team@babeljs.io 联系我们!
重点更新
默认启用的新类特性
类字段和私有方法提案现已达到 Stage 4 阶段,将正式纳入 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 开始原生支持此语法。
对于旧版本,可通过安装 acorn-stage3 并在 webpack.config.js 文件开头添加以下代码手动启用 acorn-stage3 插件(适用于简单 Webpack 配置):
// Require webpack's acorn dependency
const acorn = require(require.resolve("acorn", {
paths: [require.resolve("webpack")]
}));
// Enable the Stage 3 plugin
acorn.Parser = acorn.Parser.extend(require("acorn-stage3"));
若此方法无效,或您使用的其他工具不支持类字段,则仍需使用 Babel 插件进行转换。
若您使用 @babel/preset-env 的 shippedProposals 选项,现在它已包含 @babel/plugin-proposal-private-property-in-object(在 7.10 引入)和 @babel/plugin-proposal-class-static-block(在 7.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 在 @babel/plugin-transform-modules-commonjs 插件中新增 importInterop: "node" 选项,使 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 表达式提案的 Stage 1 提案。
它允许在同步代码中使用异步块,这些块会被解析为 Promise:
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!"
您可以通过在 Babel 配置中添加 @babel/plugin-proposal-do-expressions 和 @babel/plugin-proposal-async-do-expressions 插件来测试该提案(并反馈意见!)
这些提案处于高度实验阶段,其规范可能且极有可能持续演化。标准化进程可能需要数年时间,甚至可能被完全否决。欢迎进行测试,但我们不建议在生产环境中使用。
有任何意见或疑问?欢迎在 GitHub 上参与讨论!