Skip to main content

7.25.0 Released: Safari bugfixes and duplicated named capturing groups

· 3 min read

Babel 7.25.0 is out!

@babel/preset-env now supports the duplicated named capturing groups proposal for Regular Expressions by default, as well as a bugfix for class fields when targeting Safari. This version also improves support for compiling JSON module imports to CommonJS, and adds support for config files to @babel/node's --eval mode.

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

Duplicated named capturing groups (#16445)

The duplicated named capturing groups proposal allows re-using the same name for groups in alternative branches within a regular expression. For example, a RegExp that matches dates either in the dd/mm/yyyy or yyyy-mm-dd format could be written as

let re =
/(?<day>\d\d)\/(?<month>\d\d)\/(?<year>\d\d\d\d)|(?<year>\d\d\d\d)-(?<month>\d\d)-(?<day>\d\d)/;

"21/12/2023".match(re).groups.day; // 21
"2023-12-21".match(re).groups.day; // 21

The proposal reached Stage 4 in the April 2024 TC39 meeting, and will be included in the next version of the JavaScript standard. It is thus now enabled by default in @babel/preset-env (when needed based on your targets), and you can safely remove @babel/plugin-proposal-duplicate-named-capturing-groups-regex from your configuration.

If for any reason you still need to explicitly list the plugin, it has now been renamed to @babel/plugin-transform-duplicate-named-capturing-groups-regex as the proposal became a standard language feature.

Simplify JSON modules imports in CommonJS (#16579)

After introducing support for transforming JSON modules imports in Babel 7.24.0, we realized that the generated output was not friendly to CommonJS bundlers.

Given this code:

import myConfig from "./config.json" with { type: "json" };

@babel/plugin-proposal-json-modules would compile it to the following, when targeting CommonJS on Node.js:

const myConfig = JSON.parse(
require("fs").readFileSync(require.resolve("./config.json"))
);

The JSON.parse + readFileSync combination is necessary to ensure that config.json is indeed a JSON file, and not a config.json.js file trying to sneakily execute some code while being loaded.

@babel/plugin-proposal-json-modules has now an uncheckedRequire option to simplify the output, at the cost of less validation. You can enable it in your configuration:

babel.config.json
{
"plugins": [
["@babel/plugin-proposal-json-modules", { "uncheckedRequire": true }]
]
}

and Babel will generate the following code:

const myConfig = require("./config.json");

@babel/plugin-bugfix-safari-class-field-initializer-scope (#16569)

Safari versions older than 16 have a bug when using parentheses around expressions in class fields. For example, the following code would throw an error:

{
let a = [3];
new class {
c = (a)[0];
};
}

This is especially problematic when using Webpack or when compiling to CommonJS, as they add parentheses when transforming imports. For example, this input code:

import { hello } from "./dep";

class A {
prop = hello();
}

would become

var _dep = /* ... */;

class A {
prop = (0, _dep.hello)();
}

David Taylor implemented a fix (thanks!) in the new @babel/plugin-bugfix-safari-class-field-initializer-scope package, which is enabled by default in @babel/preset-env when your targets include Safari versions older than 16.