Today we are releasing Babel 7.4.0!
This release includes support for TypeScript 3.4, the proposal for partial application in function calls, and static private methods.
We added support for meaningful parenthesized expressions in @babel/parser
, and also made it more spec compliant than ever!
Last but not least, both @babel/preset-env
and @babel/transform-runtime
now support core-js@3
, and @babel/template
has some sweet new syntax!
You can read the whole changelog on GitHub.
Special thanks to all the new Babel contributors 😊. Since we started generating release changelogs using GitHub actions we hadn't had the chance to thank them in each release, but since Babel 7.3.3 they have been a lot of people!
- Babel 7.3.3: @Alec321, @mhcgrq, @ilyalesik, @yifei-fu
- Babel 7.3.4: @elevatebart, @ian, @imjacobclark, @irohitb
- Babel 7.4.0: @AmirS, @agoldis, @byara, @echenley, @tanohzana, @matt, @penielse, @pnowak
Many features in this release have been developed in collaboration with our sponsors. Bloomberg has contributed support for a new kind of private element in every release since 7.0 (7.1, 7.2, 7.3), and they've now implemented static private methods! This leaves only static private getters and setters remaining.
Similarly, Trivago (a Base Support Sponsor on OpenCollective) took over the implementation of the partial application plugin.
Over the last month, we have been experimenting with working more directly with companies on various features/optimizations that would benefit the community: RunKit has been sponsoring Nicolò to implement placeholder support in @babel/template
.
When managing a big open source project, not everything is code: we need to manage servers, continuous integration, social media accounts and... a lot of passwords! We really appreciate 1Password for accepting us into their open source support program and providing us a free 1Password Teams account!
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 OpenCollective 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 both fund our efforts in supporting the wide range of JavaScript users and taking ownership of the code. Reach out to Henry at henry@babeljs.io if you'd like to talk more!
core-js
3 (#7646)
We've received lots of kudos for our work on @babel/preset-env
, but much of that should really go to the awesome work done by Denis. He maintains core-js
which provides all the polyfills loaded by @babel/polyfill
, @babel/runtime
and @babel/preset-env
.
core-js@3
was just released, and includes a lot of new features: you can read about them at "core-js@3, babel and a look into the future". Other than all the new proposals, it makes it possible to polyfill transform instance methods using @babel/plugin-transform-runtime
so that they can be used in old browsers without polluting the global environment:
// 'foo' could be either a string or an array, or a custom object
foo.includes("a");
// ⮕
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
_includesInstanceProperty(foo).call(foo, "a");
@babel/preset-env
and @babel/plugin-transform-runtime
now support polyfilling proposals: you just need to use corejs: { version: 3, proposals: true }
instead of corejs: 3
in your configuration. Keep in mind that ECMAScript proposals are inherently unstable, and could change in core-js@4
!
Previously, @babel/preset-env
relied entirely on compat-table
data for determining which polyfills needed to be loaded for a particular environment. core-js@3
introduces its own compatibility data set with an exhaustive test suite that should result in much more accurate polyfilling!
Migration from core-js@2
Since versions 2
and 3
of core-js
are incompatible with each other (we don't want to break your code!), it isn't enabled by default.
-
If you are using
@babel/preset-env
, you need to enable thecorejs: 3
option:JavaScriptpresets: [
["@babel/preset-env", {
useBuiltIns: "usage", // or "entry"
corejs: 3,
}]
]Don't forget to update your installed version of
core-js
!npm install --save core-js@3
When using
core-js
3, theuseBuiltIns: "entry"
option not only transformsimport "core-js"
imports, but alsoregenerator-runtime/runtime
and all the nestedcore-js
entry points.For example, when targeting Chrome 72, it will apply this transformation:
Input
JavaScriptimport "core-js/es";
import "core-js/proposals/set-methods";
import "core-js/features/set/map";Output
JavaScriptimport "core-js/modules/es.array.unscopables.flat";
import "core-js/modules/es.array.unscopables.flat-map";
import "core-js/modules/es.object.from-entries";
import "core-js/modules/esnext.set.difference";
import "core-js/modules/esnext.set.intersection";
import "core-js/modules/esnext.set.is-disjoint-from";
import "core-js/modules/esnext.set.is-subset-of";
import "core-js/modules/esnext.set.is-superset-of";
import "core-js/modules/esnext.set.map";
import "core-js/modules/esnext.set.symmetric-difference";
import "core-js/modules/esnext.set.union";Unlike when using
core-js
2, it doesn't transform@babel/polyfill
imports because when used directly that package loads version 2 ofcore-js
. -
If you are using
@babel/plugin-transform-runtime
, you need to use thecorejs: 3
option:JavaScriptplugins: [
["@babel/transform-runtime", {
corejs: 3,
}]
]You can remove
@babel/runtime-corejs2
, but you need to install@babel/runtime-corejs3
!npm remove @babel/runtime-corejs2
npm install --save @babel/runtime-corejs3 -
@babel/polyfill
isn't a plugin or preset, but a runtime package: if we added an option to switch betweencore-js@2
andcore-js@3
, both the package versions would need to be included in your bundle. For this reason, we decided to deprecate it: you now should loadcore-js
for polyfills, andregenerator-runtime/runtime
if you are transforming generators:JavaScript// before
import "@babel/polyfill";
// after
import "core-js/stable";
import "regenerator-runtime/runtime";This gives you the ability to load any version you want, and to update those two package independently.
In case you are interested, you should check the old source of
@babel/polyfill
forcore-js@2
: packages/babel-polyfill/src/index.js.
Partial Application (#9343 and #9474)
This release includes both @babel/parser
and transform support for the partial application proposal, which is currently at Stage 1 (last presented in July 2018). All the implementation work has been done by Behrang Yarahmadi, sponsored by Trivago.
This new feature allows you to bind some arguments and the this
receiver function, similarly to the existing Function#bind
method but with fewer limitations.
const half = divide(?, 2); // half = num => divide(num, 3)
half(6); // 3
element.addEventListener(
"click",
// handleEvent will be called with the correct "this".
this.handleEvent("click", ?) // e => this.handleEvent("click", e)
);
It is also really useful in conjunction with the pipeline operator proposal (especially when using the "minimal" or "F-sharp" variants), since it makes it possible to avoid a lot of arrow functions:
let newScore = player.score
|> add(?, 7)
|> clamp(0, 100, ?);
// Without this proposal:
let newScore = player.score
|> (_ => add(_, 7))
|> (_ => clamp(0, 100, _));
You can test it by adding @babel/plugin-proposal-partial-application
to your config, or by enabling the stage 1
preset in the online repl!
Although the proposal's readme also describes partial application for tagged template literals, it has not been implemented because it will likely be removed.
Static private methods (#9446)
class Person {
static #is(obj) {
return obj instanceof Person;
}
constructor(name) {
if (Person.#is(name)) {
throw "It is already a person!";
}
}
}
Thanks again to Tim (Bloomberg) for implementing this proposal!
If you already use instance private methods you can use this new feature without any additional configuration, otherwise you need to add @babel/plugin-proposal-private-methods
to your plugins list. When using the online repl it is enabled by the stage-3
preset.
Class private features support is only one step away from being complete! 😄
Class Private | Instance | Static |
---|---|---|
Fields class A { #a = 1 } | 7.0.0 | 7.1.0 |
Methods class A { #a() {} } | 7.2.0 | 7.4.0 |
Accessors class A { get #a() {} } | 7.3.0 | ✖️ |
TypeScript 3.4 RC support (#9529 and #9534)
TypeScript 3.4 RC was released a few days ago, and thanks to Tan Li Hau it is already supported by Babel!
There are two new features for type annotations: const
contexts, which mark an object as "deeply frozen", and the readonly
modifier for arrays and tuples.
const student = {
name: "Joe Blogs",
marks: [25, 23, 30]
} as const;
const vowels: readonly string[] = ["a", "e", "i", "o", "u"];