We just released a new minor version of Babel!
This 7.10 release includes:
- Full support for the new Stage 1 proposal,
#prop in obj
checks for private fields proposal. @babel/preset-env
now compiles ES2015-style Unicode escapes (\u{Babe1}
) to the equivalent legacy syntax (\uDAAA\uDFE1
).- Two improvements to the Optional Chaining operator (
?.
) - Parser support for the new Stage 1 Module Attributes proposal (
import a from "./a.json" with type: "json"
). - Better tree-shaking support for React code (i.e.
React.memo
)! - Setting up RFCs repo and GitHub Discussions pages!
You can read the whole changelog on GitHub.
Alongside this Babel release, we are releasing the first experimental version of our new polyfills compatibility architecture (see below for more details), thanks to Nicolò and some awesome folks in the community! We began discussions about this over a year ago in a RFC issue within the Babel repository.
As an aside, we now have an official RFC process for discussing changes that significantly impact our users: please check it out over in the babel/rfcs
repository! In addition, we've enabled GitHub Discussions on our repository if you have feedback or questions!
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!
New features enabled by default
Parsing for import.meta
Now that it has reached Stage 4, parsing for import.meta
is enabled by default, thanks to Kiko. Please note that @babel/preset-env
doesn't have any default support for transforming it, because what that object contains is up to the engine and is not defined in the ECMAScript specification.
console.log(import.meta); // { url: "file:///home/user/my-module.js" }
Transforming ​u{...}
-style Unicode escapes (#11377)
We also discovered that we didn't have support for compiling a 5-year-old ECMAScript feature: \u{...}
-style Unicode escapes! Thanks to Justin, @babel/preset-env
can now compile them in strings and identifiers by default.
var \u{1d49c} = "\u{Babe1}";
console.log(\u{1d49c});
var _ud835_udc9c = "\uDAAA\uDFE1";
console.log(_ud835_udc9c);
Class Properties and Private Methods to shippedProposals
option of @babel/preset-env
(#11451)
Lastly, thanks to Jùnliàng we have added @babel/plugin-proposal-class-properties
and @babel/plugin-proposal-private-methods
to the shippedProposals
option of @babel/preset-env
. These proposals are not Stage 4 (i.e. part of the ECMAScript standard) yet, but they are already enabled by default in many JavaScript engines.
If you aren't familiar:
class Bork {
// Public Fields
instanceProperty = "bork";
static staticProperty = "babelIsCool";
// Private Fields
#xValue = 0;
a() {
this.#xValue++;
}
// Private methods
get #x() { return this.#xValue; }
set #x(value) {
this.#xValue = value;
}
#clicked() {
this.#x++;
}
}
If you missed it from the last release, in 7.9 we added a new option: "bugfixes": true
which can greatly reduce your code output.
{
"presets": [
["@babel/preset-env", {
"targets": { "esmodules": true }, // Use the targets that you was already using
"bugfixes": true // will be default in Babel 8
}]
]
}
Improved optional chaining ?.
ergonomics (#10961, #11248)
In TypeScript 3.9, the interaction between non-null assertions (postfix !
) and optional chaining has been changed to make it more useful.
foo?.bar!.baz
In TypeScript 3.8 and Babel 7.9, the above would be read as (foo?.bar)!.baz
: "If foo
is not nullish, get .bar
from it. Then trust that foo?.bar
is never nullish and always get .bar
from it". This means that when foo
is nullish that code would always throw, because we are trying to get .baz
from undefined
.
In TypeScript 3.9 and Babel 7.10, the code behaves similarly to foo?.bar.baz
: "If foo
is not nullish, get .bar.baz
from it and trust me that foo?.bar
isn't nullish". Thanks to Bruno for helping to implement this!
Additionally, the class fields proposal recently added support for mixing optional chaining ?.
with private fields. This means that the following code is now valid:
obj?.property.#priv;
obj?.#priv;
Note that in the second example, if obj
is not nullish and does not have the #priv
field, it would still throw an error (exactly as obj.#priv
would throw). You can read the next section to see how to avoid it!
Private Fields in in
(#11372)
class Person {
#name;
hug(other) {
if (#name in other) console.log(`${this.#name} 🤗 ${other.#name}`);
else console.log("It's not a person!")
}
}
This Stage 1 proposal allows you to statically check if a given object has a specific private field.
Private fields have a built-in "brand check": if you try to access them in an object where they aren't defined, it will throw an exception. You can determine if an object has a particular private field by leveraging this behavior with a try
/catch
statement, but this proposal gives us a more compact and robust syntax to do so.
You can read more about it in the proposal's description and test this proposal by installing the @babel/plugin-proposal-private-property-in-object
plugin and adding it to your Babel config. Thanks to Justin for the PR!
Module Attributes parser support (#10962)
The Modules Attributes proposal (Stage 1) allows providing the engine, module loader or bundler some additional information about the imported file. For example, you could explicitly specify that it should be parsed as JSON:
import metadata from "./package.json" with type: "json";
Additionally, they can also be used with dynamic import()
. Note the support for trailing commas to make it easier to add or remove the second parameter!
const metadata = await import(
"./package.json",
{ with: { type: "json" } },
);
Thanks to Vivek, Babel now supports parsing these attributes: you can add the @babel/plugin-syntax-module-attributes
plugin to your Babel config or, if you are using @babel/parser
directly, you can enable the moduleAttributes
plugin. Currently, we only accept the type
attribute but we might relax this restriction in the future depending on how the proposal evolves.
Babel doesn't transform these attributes, and they should be handled directly by your bundler or a custom plugin. Currently babel module transformers ignore these attributes. We are discussing whether we should pass through these attributes in the future.