Blog

Unlocking ES2015 features with Webpack and Babel

31 Aug, 2015
Xebia Background Header Wave

This post is part of a series of ES2015 posts. We’ll be covering new JavaScript functionality every week for the coming two months.
After being in the working draft state for a long time, the ES2015 (formerly known as ECMAScript 6 or ES6 shorthand) specification has reached a definitive state a while ago. For a long time now, BabelJS, a Javascript transpiler, formerly known as 6to5, has been available for developers that would already like to use ES2015 features in their projects.
In this blog post I will show you how you can integrate Webpack, a Javascript module builder/loader, with Babel to automate the transpiling of ES2015 code to ES5. Besides that I’ll also explain you how to automatically generate source maps to ease development and debugging.

Webpack

Introduction

Webpack is a Javascript module builder and module loader. With Webpack you can pack a variety of different modules (AMD, CommonJS, ES2015, …) with their dependencies into static file bundles. Webpack provides you with loaders which essentially allow you to pre-process your source files before requiring or loading them. If you are familiar with tools like Grunt or Gulp you can think of loaders as tasks to be executed before bundling sources. To make your life even easier, Webpack also comes with a development server with file watch support and browser reloading.

Installation

In order to use Webpack all you need is npm, the Node Package Manager, available by downloading either Node or io.js. Once you’ve got npm up and running all you need to do to setup Webpack globally is install it using npm:
npm install -g webpack
Alternatively, you can include it just in the projects of your preference using the following command:
npm install --save-dev webpack

Babel

Introduction

With Babel, a Javascript transpiler, you can write your code using ES2015 (and even some ES7 features) and convert it to ES5 so that well-known browsers will be able to interpret it. On the Babel website you can find a list of supported features and how you can use these in your project today. For the React developers among us, Babel also comes with JSX support out of the box.
Alternatively, there is the Google Traceur compiler which essentially solves the same problem as Babel. There are multiple Webpack loaders available for Traceur of which traceur-loader seems to be the most popular one.

Installation

Assuming you already have npm installed, installing Babel is as easy as running:
npm install --save-dev babel-loader
This command will add babel-loader to your project’s package.json. Run the following command if you prefer installing it globally:
npm install -g babel-loader

Project structure

webpack-babel-integration-example/
  src/
    DateTime.js
    Greeting.js
    main.js
  index.html
  package.json
  webpack.config.js

Webpack’s configuration can be found in the root directory of the project, named webpack.config.js. The ES6 Javascript sources that I wish to transpile to ES5 will be located under the src/ folder.

Webpack configuration

The Webpack configuration file that is required is a very straightforward configuration or a few aspects:

  • my main source entry
  • the output path and bundle name
  • the development tools that I would like to use
  • a list of module loaders that I would like to apply to my source

[javascript]
var path = require(‘path’);
module.exports = {
entry: ‘./src/main.js’,
output: {
path: path.join(dirname, ‘build’),
filename: ‘bundle.js’
},
devtool: ‘inline-source-map’,
module: {
loaders: [
{
test: path.join(
dirname, ‘src’),
loader: ‘babel-loader’
}
]
}
};
[/javascript]
The snippet above shows you that my source entry is set to src/main.js, the output is set to create a build/bundle.js, I would like Webpack to generate inline source maps and I would like to run the babel-loader for all files located in src/.

ES6 sources

A simple ES6 class

Greeting.js contains a simple class with only the toString method implemented to return a String that will greet the user:
[javascript]
class Greeting {
toString() {
return ‘Hello visitor’;
}
}
export default Greeting
[/javascript]

Using packages in your ES2015 code

Often enough, you rely on a bunch of different packages that you include in your project using npm. In my example, I’ll use the popular date time library called Moment.js. In this example, I’ll use Moment.js to display the current date and time to the user.
Run the following command to install Moment.js as a local dependency in your project:
npm install --save-dev moment
I have created the DateTime.js class which again only implements the toString method to return the current date and time in the default date format.
[javascript]
import moment from ‘moment’;
class DateTime {
toString() {
return ‘The current date time is: ‘ + moment().format();
}
}
export default DateTime
[/javascript]
After importing the package using the import statement you can use it anywhere within the source file.

Your main entry

In the Webpack configuration I specified a src/main.js file to be my source entry. In this file I simply import both classes that I created, I target different DOM elements and output the toString implementations from both classes into these DOM objects.
[javascript]
import Greeting from ‘./Greeting.js’;
import DateTime from ‘./DateTime.js’;
var h1 = document.querySelector(‘h1’);
h1.textContent = new Greeting();
var h2 = document.querySelector(‘h2’);
h2.textContent = new DateTime();
[/javascript]

HTML

After setting up my ES2015 sources that will display the greeting in an h1 tag and the current date time in an h2 tag it is time to setup my index.html. Being a straightforward HTML-file, the only thing that is really important is that you point the script tag to the transpiled bundle file, in this example being build/bundle.js.
[html]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webpack and Babel integration example</title>
</head>
<body>
<h1></h1>
<h2></h2>
<script src="build/bundle.js"></script>
</body>
</html>
[/html]

Running the application

In this example project, running my application is as simple as opening the index.html in your favorite browser. However, before doing this you will need to instruct Webpack to actually run the loaders and thus transpile your sources into the build/bundle.js required by the index.html.
You can run Webpack in watch mode, meaning that it will monitor your source files for changes and automatically run the module loaders defined in your configuration. Execute the following command to run in watch mode:
webpack --watch
If you are using my example project from Github (link at the bottom), you can also use the following script which I’ve set up in the package.json:
npm run watch

Easier debugging using source maps

Debugging transpiled ES5 is a huge pain which will make you want to go back to writing ES5 without thinking. To ease development and debugging of ES2015 I can rely on source maps generated by Webpack. While running Webpack (normal or in watch mode) with the devtool property set to inline-source-map you can view the ES2015 source files and actually place breakpoints in them using your browser’s development tools.
Debugging ES6 with source maps
Running the example project with a breakpoint inside the DateTime.js toString method using the Chrome developer tools.

Conclusion

As you’ve just seen, setting up everything you need to get started with ES2015 is extremely easy. Webpack is a great utility that will allow you to easily set up your complete front-end build pipeline and seamlessly integrates with Babel to include code transpiling into the build pipeline. With the help of source maps even debugging becomes easy again.

Sample project

The entire sample project as introduced above can be found on Github.

Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts