Skip to main content

7.22.0 Released: Explicit Resource Management support and Import Attributes parsing

· 6 min read

Babel 7.22.0 is out, with parsing/transform support for the Explicit Resource Management proposal, including both the sync and async variants, and with parsing support for the Import Attributes (an evolution of the old Import Assertions proposal).

We also updated our implementation of decorators following some changes in the proposal, and added support for the TypeScript import ... = and export ... = statements.

@babel/preset-env now includes transform support for the v regular expressions flag, which was recently approved as part of the ECMAScript standard, by default. Lastly, we renamed all the plugins for stable ECMAScript features from -proposal- to -transform-.

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

Explicit Resource Management (#15633, #15520)

The Explicit Resource Management Stage 3 proposal allows defining variables containing resources that will be "disposed" when exiting the scope where they are declared. This is done through using (for synchronous disposal) and await using (for asynchronous disposal) declarations:

JavaScript
{
using fileHandle = filesystem.open("./my/file.txt");

write(fileHandle, "Hello!");
} // At the end of the block, fileHandle will be automatically closed.
JavaScript
{
await using db = await Database.connect("//my-db.sql");
db.query("INSERT INTO tools (name, version) VALUES ('Babel', '7.22.0')");
} // At the end of the block, the db connection will be closed asynchronously

You can enable support for this proposal by adding @babel/plugin-proposal-explicit-resource-management to your Babel config:

babel.config.json
 {
"plugins": [
"@babel/plugin-proposal-explicit-resource-management"
]
}

You can also try out this proposal in our REPL.

Import Attributes (#15536, #15620)

The "import assertions" proposal's syntax changed to use the with keyword instead of assert, and it has also been renamed to "import attributes":

JavaScript
import json from "./foo.json" with { type: "json" };

import("./foo.json", { with: { type: "json" } });

We've implemented parsing support for this new version of the proposal, which can be enabled using the @babel/plugin-syntax-import-attributes plugin (or, if you are directly using @babel/parser, importAttributes):

babel.config.json
 {
"plugins": [
- "@babel/syntax-import-assertions",
+ "@babel/syntax-import-attributes"
]
}

You can read more about the changes to the proposal in the slides presented at the March TC39 meeting, and about the motivation in the slides presented at the January TC39 meeting.

caution

@babel/plugin-syntax-import-assertions will continue working until we release Babel 8.0.0, but will no longer be maintained, so we highly recommended migrating to the new plugin.

To ease the migration from with to assert, if you run the Babel-compiled code only in tools and runtimes that support the legacy syntax but do not support yet the new one (such as Node.js 20 or Rollup 3.21), you can use the @babel/plugin-proposal-import-attributes-to-assertions:

babel.config.json
 {
"plugins": [
- "@babel/syntax-import-assertions",
+ "@babel/plugin-proposal-import-attributes-to-assertions"
]
}

🛑 Note that this plugin generates deprecated code that will not work in tools and runtimes only supporting the with syntax now described by the proposal.

Decorators updates (#15570)

The TC39 committee received further feedback by JavaScript tools and engines implementing decorators, and refined the proposal, and designed different changes and bugfixes in response to it.

The relevant changes for Babel users are:

  • accessor static fields now work with derived classes:
    JavaScript
    class Base {
    static accessor x = 2;
    }
    class Derived extends Base {}

    Derived.x; // Used to throw, now returns `2`
  • Decorators stored in object properties are now called using the object as this instead of undefined:
    JavaScript
    let MyDecs = {
    dec() {
    console.log(this); // Now logs `MyDecs` instead of `undefined`
    }
    };

    @MyDecs.dec class {}

You can use this new decorators version by passing the version: "2023-05" option to the decorators plugin:

babel.config.json
 {
"plugins": [
["@babel/plugin-proposal-decorators", {
"version": "2023-05"
}]
]
}

You can also try using the new version of the proposal in our REPL, enabling the "Stage 3" preset and choosing the appropriate decorators version.

TypeScript import ... = and export = statements

When using the TypeScript verbatimModuleSyntax option, ESM import/export statements are disallowed in CommonJS files. Instead, developers must use the import ... = and export = statements:

TypeScript
import A = require("./a");

export = { x: 2 };

which desugar to:

JavaScript
const A = require("./a");

module.exports = { x: 2 };

This syntax is only supported in ECMAScript modules, and only when compiling them to CommonJS. Unless you have some custom configuration, this means:

  • in .cts files, when using @babel/preset-typescript
  • in .ts files written as ESM and compiled with @babel/plugin-transform-modules-commonjs

Renamed packages

From now on, we will rename -proposal- plugins to -transform- once they reach Stage 4 in the standardization process and thus become stable. The following packages have been renamed:

Old nameNew nameECMAScript version
@babel/plugin-proposal-unicode-sets-regex@babel/plugin-transform-unicode-sets-regexES2024
@babel/plugin-proposal-class-static-block@babel/plugin-transform-class-static-blockES2022
@babel/plugin-proposal-private-property-in-object@babel/plugin-transform-private-property-in-objectES2022
@babel/plugin-proposal-class-properties@babel/plugin-transform-class-propertiesES2022
@babel/plugin-proposal-private-methods@babel/plugin-transform-private-methods
@babel/plugin-proposal-numeric-separator@babel/plugin-transform-numeric-separatorES2021
@babel/plugin-proposal-logical-assignment-operators@babel/plugin-transform-logical-assignment-operatorsES2021
@babel/plugin-proposal-nullish-coalescing-operator@babel/plugin-transform-nullish-coalescing-operatorES2020
@babel/plugin-proposal-optional-chaining@babel/plugin-transform-optional-chainingES2020
@babel/plugin-proposal-export-namespace-from@babel/plugin-transform-export-namespace-fromES2020
@babel/plugin-proposal-json-strings@babel/plugin-transform-json-stringsES2019
@babel/plugin-proposal-optional-catch-binding@babel/plugin-transform-optional-catch-bindingES2019
@babel/plugin-proposal-async-generator-functions@babel/plugin-transform-async-generator-functionsES2018
@babel/plugin-proposal-object-rest-spread@babel/plugin-transform-object-rest-spreadES2018
@babel/plugin-proposal-unicode-property-regex@babel/plugin-transform-unicode-property-regexES2018

These plugins are all included by default in @babel/preset-env: if you are using the preset, you don't need to explicitly list them in your configuration and thus this change will not affect you. The packages with the old name will no longer be updated.