We just released Babel 7.23.0! 🎉
It includes transform support for the Decorator Metadata, Source Phase Import, Deferred Import Evaluation, and Optional Chaining Assignment proposals. We also updated our parser to support the new TypeScript 5.2 version, and added a transform option to let you use the .ts
extension within TypeScript imports.
In addition to releasing version 7.23.0, we also recently published the first Babel 8 alpha release!
You can read the whole changelog on GitHub.
If you or your company want to support Babel and the evolution of JavaScript, but aren't sure how, you can donate to us on our Open Collective and, better yet, work with us on the implementation of new ECMAScript proposals directly! As a volunteer-driven project, we rely on the community's support to fund our efforts in supporting the wide range of JavaScript users. Reach out at team@babeljs.io if you'd like to discuss more!
Highlights
Decorator Metadata (#15895)
The decorator metadata Stage 3 proposal extends the Decorator proposal, allowing decorators to communicate with each other by sharing some metadata.
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;
}
While we usually have one plugin per proposal, these two proposals are so closely related that we decided to include support for Decorator Metadata directly in @babel/plugin-proposal-decorators
. If you are on the latest version of Babel and you are already using standard-track decorators, this proposal is enabled by default.
Source Phase Imports for WebAssembly modules (#15829, #15870)
The Source Phase Import Stage 3 proposal allows importing an object representation of the source of a module, without evaluating it and without loading its dependencies. You can load module sources using the import source
syntax, for languages that have a defined source representation:
import source fooSource from "foo";
The motivating use case is to have static syntax to load WebAssembly.Module
objects, rather than being forced to do so dynamically:
// 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 now supports transforming source imports for WebAssembly modules targeting Node.js, Web-compatible environments (browsers and Deno), or both, depending on your configured targets
.
You can transform it using the @babel/plugin-proposal-import-wasm-source
plugin:
{
"targets": ["chrome 90", "firefox 90", "node 20.6"],
"plugins": ["@babel/plugin-proposal-import-wasm-source"]
}
Deferred Import Evaluation (#15845, #15878)
The Deferred Import Evaluation Stage 2 proposal allows deferring the (synchronous) evaluation of imported modules until they are used. This can greatly improve the startup performance of your code when using modules that have a significant initialization cost.
You can use the new import defer
syntax to defer your imports:
// this line does not evaluate ./mod
import defer * as myMod from "./mod";
later(() => {
// this one evaluates it!
use(myMod.foo);
})
The import defer
syntax only support namespace imports, so the following is not valid:
import defer modDefault from "./mod";
import defer { named } from "./mod";
Babel only supports compiling import defer
when compiling ECMAScript modules to CommonJS, using the @babel/plugin-proposal-import-defer
plugin:
// babel.config.json
{
"plugins": [
"@babel/plugin-transform-modules-commonjs",
"@babel/plugin-proposal-import-defer"
]
}
If you are using Babel with a bundler and thus you are not compiling modules via Babel, if your bundler supports import defer
you can use @babel/plugin-syntax-import-defer
to allow parsing the new syntax.
Optional Chaining Assignment (#15751)
The Optional Chaining Assignment Stage 1 proposal allows using optional chaining on the left side of assignment operators:
maybeAnObj?.prop = theValue;
// Equivalent to
if (maybeAnObj != null) maybeAnObj.prop = theValue;