Using ES7 Decorators with Babel 6
When Babel 6 dropped on my birthday I was taken aback by all the breaking changes, disclaimers and continued push to use the .babelrc
file without a lot of justification from the maintainers. Nevertheless I knew Babel 6 was the future, so I went ahead and added support to my React Native Webpack Starter Kit. Everything went smooth given the small scope of the app, but for some app maintainers the Babel 6 upgrade also meant chucking decorators due to an issue in Babel 6.
Add decorator support
But I discovered there’s no need to pull your powerful decorators to upgrade to Babel 6. If you’d like restore legacy support for ES7 decorators in Babel 6 do the following:
npm i -S babel-plugin-transform-decorators-legacy
Then update your .babelrc
file to add the legacy decorator support plug-in like so:
{
"presets": ["es2015", "react", "stage-1"],
"plugins": ["transform-decorators-legacy"]
}
If you’re using Webpack as a transpiler and module bundler, it’s possible to target the plug-in at only desired portions of the codebase by passing the name of the plugin
to the query
of a loader, as shown in the example here:
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules\/(?!(stardust))/,
loader: 'babel',
query: {
cacheDirectory: true,
plugins: [
'transform-runtime',
'add-module-exports',
'transform-decorators-legacy',
],
presets: ['es2015', 'react', 'stage-1'],
},
}
]
}
Decorator usage
Once added, decorators like @autobind
can be used to mitigate the need to override ES6 class constructors, turning this:
class MyClass extends Component {
constructor(props, context) {
this.onChange = this.onChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.state = {isLoading: true}
}
onChange() {}
handleSubmit() {}
}
Into this:
class MyClass extends Component {
state = {isLoading: true}
@autobind
onChange() {}
@autobind
handleSubmit() {}
}
Note that Decorators and the @
operator are an ES7 proposal and are subject to change before the specification is finalized.
Summary
In this post I’ve shown you how to add legacy support for Babel 5 ES7 decorators to your Babel 6 apps using Babel and Webpack. Decorators are declarative and awesome, and provide a great way to mixin behaviors to your ES6 classes. Got an example usage for Browserify? If so, please do share in the comments section below. Thanks!