In the past few months Babel has been welcomed into several major communities such as Node, React, Ember, Backbone, Angular, Rails, and many others. We launched the Users page only a few weeks ago and it's really cool to see everyone that is using it. Companies like CloudFlare, Netflix, Mozilla, and Yahoo!. Projects like Ghost, Atom, Mapbox, and so many more.
We've seen tons of blog posts, talks, events, courses all about ES6+ using Babel, and official Babel tools have been downloaded nearly 2 million times.
Today we are making by far the largest release of Babel ever.
If you're upgrading from Babel 4.x please see the breaking changes.
This release includes the new ES7 proposals:
The entire internal traversal and transformation pipeline has undergone a rewrite that substantially increases flexibility and will allow many future pipeline performance optimisations.
This release also brings a plugin API, this allows consumers to plug in their own custom transformers to utilise the powerful transformation mechanisms that Babel has to offer.
You can view the complete CHANGELOG here.
And as usual if you run into any regressions please report them immediately.
TC39 Process
In this release you'll start to see us aligned with the TC39 process. The TC39 is the technical committee from ECMA that writes the ECMAScript standard. Their process is categorised into 5 stages:
- Stage 0 - Strawman
- Stage 1 - Proposal
- Stage 2 - Draft
- Stage 3 - Candidate
- Stage 4 - Finished
Proposals that are stage 2 or above are enabled in Babel by default. Now this does not mean that they're guaranteed to be included in future ECMAScript specifications or even Babel itself. Stage 2 is considered a good point for inclusion by default in Babel due to their relative maturity and need for critical proposal feedback.
Now let's dive into the changes we made to 5.0.
Contents:
New Features
New Proposals
Stage 0: Class Properties
Jeff Morrison's stage 0 class property initializers proposal fills the void of property composition on classes. These are analogous with the class properties example listed in the React 0.13 beta announcement.
Example:
class Person {
firstName = "Sebastian";
static lastName = "McKenzie";
}
assert(new Person().firstName, "Sebastian");
assert(Person.lastName, "McKenzie");
Usage:
require("babel").transform("code", {
optional: ["es7.classProperties"]
});
// or
require("babel").transform("code", { stage: 0 });
$ babel --optional es7.classProperties script.js
# or
$ babel --stage 0 script.js
Stage 1: Decorators
Yehuda Katz' stage 1 decorators proposal allows you to elegantly compose property descriptors and metadata decoration. In the future this will allow the powerful Ember Object Model to easily be represented with native classes.
Example:
function concat(...args) {
let sep = args.pop();
return function(target, key, descriptor) {
descriptor.initializer = function() {
return args.map(arg => this[arg]).join(sep);
}
}
}
function autobind(target, key, descriptor) {
var fn = descriptor.value;
delete descriptor.value;
delete descriptor.writable;
descriptor.get = function () {
var bound = fn.bind(this);
Object.defineProperty(this, key, {
configurable: true,
writable: true,
value: bound
});
return bound;
};
}
class Person {
firstName = "Sebastian";
lastName = "McKenzie";
@concat("firstName", "lastName", " ") fullName;
@concat("lastName", "firstName", ", ") formalName;
@autobind
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
assert(new Person().fullName, "Sebastian McKenzie");
assert(new Person().formalName, "McKenzie, Sebastian");
assert(new Person().getFullName.call(null), "Sebastian McKenzie");
Usage:
require("babel").transform("code", {
optional: ["es7.decorators"]
});
// or
require("babel").transform("code", { stage: 1 });
$ babel --optional es7.decorators script.js
# or
$ babel --stage 1 script.js
Stage 1: Export Extensions
Lee Byron's stage 1 additional export-from statements proposal completes the symmetry between import and export statement, allowing you to easily export namespaces and defaults from external modules without modifying the local scope.
Exporting a default
export foo from "bar";
equivalent to:
import _foo from "bar";
export { _foo as foo };
Exporting a namespace
export * as ns from "mod";
equivalent to:
import * as _ns from "mod";
export { _ns as ns };
Usage:
require("babel").transform("code", {
optional: ["es7.exportExtensions"]
});
// or
require("babel").transform("code", { stage: 1 });
$ babel --optional es7.exportExtensions script.js
# or
$ babel --stage 1 script.js
React Optimisations
In preparation for React 0.14, Babel supports some optimisation transformers for JSX.
Constant Elements
Starting with 0.14 ReactElements and their props objects can be treated as value types. i.e. any instance is conceptually equivalent if all their values are the same.
Take this function for example:
import React from "react";
function render() {
return <div className="foo" />;
}
This can be optimized by moving the JSX out of the function body so that each time it is called the same instance is returned:
import React from "react";
var _ref = <div className="foo" />;
function render() {
return _ref;
}
Not only does it allow us to reuse the same objects, React will automatically
bail out any reconciliation of constant components - without a manual
shouldComponentUpdate
.
Usage:
require("babel").transform("code", {
optional: ["optimisation.react.constantElements"]
});