跳至主内容

7.23.0 版本发布:装饰器元数据及多项 `import` 新特性!

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

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

我们刚刚发布了 Babel 7.23.0!🎉

该版本包含对装饰器元数据源阶段导入延迟导入求值以及可选链赋值提案的转换支持。同时我们更新了解析器以支持 TypeScript 5.2 版本,并新增转换选项支持在 TypeScript 导入中使用 .ts 扩展名。

除了发布 7.23.0 版本外,我们近期还推出了首个 Babel 8 alpha 版本!

您可以在 GitHub 查看完整更新日志。

如果您或您的公司希望支持 Babel 和 JavaScript 的发展,但不确定如何操作,您可以通过 Open Collective 向我们捐款,或者更好的是,直接与我们合作实现新的 ECMAScript 提案!作为志愿者驱动的项目,我们依赖社区支持来资助为广泛 JavaScript 用户提供帮助的工作。如需进一步讨论,请通过 team@babeljs.io 联系我们!

重点更新

装饰器元数据 (#15895)

处于 Stage 3 阶段的装饰器元数据提案扩展了装饰器功能,允许装饰器通过共享元数据进行相互通信。

function write(_, context) {
context.metadata.message = "Hello from writer!";
}
function read(_, context) {
console.log(context.metadata.message);
}

@read // Logs "Hello from writer!"
class A {
@write x;
}

虽然我们通常为每个提案提供独立插件,但这两个提案紧密关联,因此我们决定直接在 @babel/plugin-proposal-decorators 中支持装饰器元数据。如果您已在使用最新版 Babel 的标准装饰器功能,该提案将默认启用。

WebAssembly 模块的源阶段导入 (#15829, #15870)

处于 Stage 3 阶段的源阶段导入提案支持导入模块的源码对象表示,无需执行求值或加载依赖项。对于已定义源码表示的语言,您可使用 import source 语法加载模块源码:

import source fooSource from "foo";

该功能的核心应用场景是为加载 WebAssembly.Module 对象提供静态语法支持,替代动态加载方式:

// Before
const url = import.meta.resolve("./my-wasm/module.wasm");
const responsePromise = fetch(url);
const mod = await WebAssembly.compileStreaming(responsePromise);

// After
import source mod from "./my-wasm/module.wasm";

Babel 现支持针对 Node.js、Web 兼容环境(浏览器和 Deno)或两者同时转换 WebAssembly 模块的源阶段导入,具体取决于您配置的 targets

可通过 @babel/plugin-proposal-import-wasm-source 插件实现转换:

{
"targets": ["chrome 90", "firefox 90", "node 20.6"],
"plugins": ["@babel/plugin-proposal-import-wasm-source"]
}

延迟导入求值 (#15845, #15878)

处于 Stage 2 阶段的延迟导入求值提案允许将导入模块的(同步)求值操作延迟到实际使用时进行,可显著提升初始化开销较大模块的启动性能。

您可使用新的 import defer 语法延迟导入:

// this line does not evaluate ./mod
import defer * as myMod from "./mod";


later(() => {
// this one evaluates it!
use(myMod.foo);
})

import defer 语法仅支持命名空间导入,因此以下写法无效:

import defer modDefault from "./mod";
import defer { named } from "./mod";

Babel 仅支持在将 ECMAScript 模块编译为 CommonJS 时转换 import defer,需使用 @babel/plugin-proposal-import-defer 插件:

// babel.config.json
{
"plugins": [
"@babel/plugin-transform-modules-commonjs",
"@babel/plugin-proposal-import-defer"
]
}

若您将 Babel 与打包器配合使用(即不由 Babel 编译模块),且打包器支持 import defer,则可使用 @babel/plugin-syntax-import-defer 插件解析新语法。

可选链式赋值 (#15751)

可选链式赋值 Stage 1 提案允许在赋值运算符左侧使用可选链式操作:

maybeAnObj?.prop = theValue;

// Equivalent to

if (maybeAnObj != null) maybeAnObj.prop = theValue;

该提案由 Babel 团队核心成员 Nicolò Ribaudo 牵头推进,目前我们已在 Stage 1 阶段实施该提案以收集反馈,助力 TC39 的设计流程。如果您有任何建议,或能提供实际应用场景和使用案例,请提交至提案讨论区

你可以使用 @babel/plugin-proposal-optional-chaining-assign 插件来尝试此提案。鉴于该提案处于早期阶段,因此存在较高的破坏性变更可能性,你必须指定要使用的版本(目前仅支持 2023-07):

// babel.config.json
{
"plugins": [
["@babel/plugin-proposal-optional-chaining-assign", {
"version": "2023-07"
}]
]
}

TypeScript 更新 (#15896, #15913)

Babel 7.23.0 现在支持解析 TypeScript 5.2,其唯一的语法新增是引入了同时具有带标签和不带标签的元组类型。

此外,@babel/preset-typescript 现在新增了一个 rewriteImportExtensions 选项,当启用时,会将导入声明中的 .ts/.mts/.cts 扩展名重写为 .js/.mjs/.cjs。结合 TypeScript 的 allowImportingTsExtension 选项,这使您可以在编写导入语句时使用与源文件相同的扩展名来编写完整的相对路径说明符。

例如,给定以下项目结构(其中 src 包含源文件,dist 包含编译后的文件):

.
├── src
│ ├── main.ts
│ └── dep.ts
├── dist
│ ├── main.js
│ └── dep.js
├── babel.config.json
└── tsconfig.json

以及以下配置文件:

babel.config.jsontsconfig.json
{
"presets": [
["@babel/preset-typescript", {
"rewriteImportExtensions": true
}]
]
}
{
"compilerOptions": {
"lib": ["esnext"],
"noEmit": true,
"isolatedModules": true,
"moduleResolution": "nodenext",
"allowImportingTsExtensions": true
}
}

您将能够在 main.ts 中编写 import x from "./dep.ts",而 Babel 在将 main.ts 编译为 main.js 时,会将其转换为 import x from "./dep.js"

Babel 8 alpha

Babel 8 alpha 版本

历经多年开发,我们终于发布 Babel 8.0.0 alpha 版本!🥳

  • 你可以使用 npm install -D @babel/core@next(或使用你的包管理器的等效命令)进行安装,并验证它是否已在你的项目中正常工作。请确保你 package.json 中所有的 @babel/* 包都具有完全相同的版本(例如 8.0.0-alpha.2)。

  • 您可以阅读用户迁移指南:许多在 Babel 8 中引入的破坏性变更已经在 Babel 7 中可启用,而 Babel 8 将直接移除相关选项,使其成为默认行为。

  • 如果你是 Babel 插件作者,或直接使用 Babel 的编程式 API,请阅读集成作者迁移指南以确保你的库与 Babel 8 兼容。

除了迁移指南之外,您还可以在 GitHub 上阅读各个 Babel 8 预发布版本的完整变更日志。