BABEL & WEBPACK
- development
- javascript
Babel provides support for certain experimental features from ES7 beyond standard ES6. Some of these might make it to the core language while some might be dropped altogether.
The language proposals
The core language proposals for JavaScript have been categorized within stages:
- Stage 0 - Strawman
- Stage 1 - Proposal
- Stage 2 - Draft
- Stage 3 - Candidate
- Stage 4 - Finished
You have to be very careful with stage 0 features - if a feature changes/removed your code will end up broken. But it's alright for smaller experimental projects.
Stage 2 - Draft
Configuring babel-loader
The easiest way of using Babel with Webpack is via babel-loader. It takes our ES6 module definition based code and turn it into ES5 bundles.
Installing babel-loader
As usual with any node package, use NPM to install babel-loader, and babel-core, which contains core logic of Babel.
npm install babel-loader babel-core --save-dev
Now we need to add a loader declaration for babel-loader to the loaders section of the config. It matches both .js and .jsx using regular expression /\.jsx?$/.
Configuring Webpack
Let's restrict the loader to operate only within ./app directory by adding include rule. This way, it won't traverse through directories like node_modules. Another way of doing this is by adding an exclude rule against node_modules.
var webpack = require('webpack');
var path = require('path');
const config = {
context: __dirname + '/src',
entry: './app.js',
resolve: {
extensions: ['', '.js', '.jsx'],
},
output: {
path: __dirname + 'build',
filename: 'bundle.js',
},
module: {
loaders: [
{
test: /\.css$/,
loaders: ['style', 'css'],
include: path.join(__dirname, 'src'),
},
{
test: /\.jsx?$/,
loaders: ['babel?cacheDirectory'],
include: path.join(__dirname, 'src'),
},
],
},
};
module.exports = config;
Line 8 - Add resolve.extensions. '' is needed to allow imports without an extension. Note the .'s before extensions, the matching will fail without those.
Line 24 - This accepts jsx and js thanks to Regular Expressions.
Line 25 - Enable caching for improved performance during development. It uses default OS directory by default. If you need something more custom, pass a path to it. i.e., babel?cacheDirectory=<path>.
resolve.extensions
Setting up .babelrc
We can pass Babel settings through Webpack, for instance babel?presets=react,presets=es2015, but doing so it will only work for Wepback.
For Babel settings to be accessed by anything, not just Webpack, we are going to create .babelrc.
Plugins
Babel 6 relies on plugins. There are two types of them: syntax and transform.
- Syntax - Allows Babel to parse additional syntax
- Transform - Applies transformation
This helps code that is using future syntax can get transformed back to JavaScript older environments can understand.
Presets
To make it easier to consume plugins, Babel supports the concept of presets.
Each preset comes with a set of plugins so, you don't have to wire them up separately. In this case, we'll be relying on ES2015 and JSX presets:
npm i babel-preset-es2015 babel-preset-react --save-dev
Now let's set up a .babelrc file.
{
"presets": ["es2015", "react"]
}
Babel provides stage-specific presets. This documents your project well and keeps it maintainable.
resolve.extensions
Alternative Loader Declarations
Webpack's loader declaration allows passing parameters to a loader through a query string.
{
test: /\.jsx?$/,
loader: 'babel',
query: {
cacheDirectory: true,
presets: ['react', 'es2015']
},
include: path.join(__dirname, 'src')
}
Note the loader and query fields. It can be alternatively declared as:
loader: 'babel?cacheDirectory,pesets[]=react,presets[]=es2015';
This is a bit hard to read, so the former is better for readability.
It's a good idea to keep in mind that Webpack loaders are always evaluated from right to left and from bottom to top (separate definitions). The following two declarations are equivalent based on this rule:
{
test: /\.css$/,
loaders: ['style', 'css'],
},
And
{
test: /\.css$/,
loaders: ['style'],
},
{
test: /\.css$/,
loaders: ['css'],
},
Conclusion
This tutorial will provide you with a good understanding of how Webpack and Babel play together, when it comes to building an application from the ground up and you will find it will be great for React apps.