Written by on 23 August 2016

How we use Webpack

Last time at the Behind the Scenes @ Coolblue I talked about Webpack and how we use it at Coolblue. I will walk you through the main subjects to give a basic understanding of what Webpack is and how we use it.


CjPMjlvVAAAUrYT

“Building Javascript”

 
In other programming languages like C++, code needs to be compiled to machine code so that a computer can run it. But we as web developers have the privilege of not having to do that. We can just write Javascript to a file and give that file to a browser. The browser will handle the rest. So what do we need to do then, before our code can go to production?
 

Bundling & Minification

 
Modern Javascript applications consist of many script files, which all need to be loaded into the browser (in the correct order) to make the application work. This means we have to do an HTTP request for every file, that can result in tenths or even hundreds of HTTP request for a single app. Because of the overhead of all request combined, our app could take a long time to load.

In the future we can avoid this problem using HTTP2, which can bundle requests. But for now we are stuck with HTTP 1.x. But what we can do, is bundle all our Javascript into one file. This way the user only has to download one file instead of many, which is much faster.

Another great speed improvement is reducing the actual size of the bundle. For that there is the art of minification. A minification tool like UglifyJS, removes all whitespace and unnecessary characters from your code, making it unreadable, but substantially smaller in file size. This greatly reduces the file size, generally 2 – 8 times, thus making the download time itself, 2 – 8 times faster.
 

Transpiling

 
EcmaScript 6 (ES6 or ES2015 for short) is becoming the standard for writing modern Javascript. It adds a lot of features and syntax that make coding Javascript a breeze. Once you get used to it, you don’t want to code without. That’s why at Coolblue we use ES6 by default for our modern Javascript applications.

However, browsers cannot run ES6 yet (check out this compatibility table). Some can run some features in compatibility mode, but that’s about it. And even by the time browsers will support ES6 fully, the next version will be around the corner.

Therefore we need to transpile this ES6 code to good old ES5. The word transpiling means nothing more then converting one language into another. For more info about ES6 check out the website of the most popular transpiler out there, Babel.
 

Using task runners

 
For executing all the build steps I mentioned above (and maybe more), there are a lot of tools out there. To make combining these tools more easy, task runners exist. The most well known ones are Gulp and Grunt.

These task runners provide you with tools to write scripts that execute all the build steps you need. The task runner itself is then able to execute these scripts. This works fine and we even use Gulp for our webshop. The possibilities are endless and you can even do things like moving files around or fetching code from Github.

But the flexibility of these task runners is also their biggest downside. Because you have to script everything yourself, writing and maintaining your build becomes a lot of work. The more you add to your project, the harder it becomes to keep the script running. At at some point it even becomes a project on it’s own.
 

Webpack

 
Webpack is a Javascript module bundler. It makes the assumption that you are trying to build a modern Javascript application. This is unlike the task runners I mentioned earlier, task runners do not assume anything, it’s a DIY solution.

Because Webpack makes this assumption, it is able to do a lot of work for you. No complex scripts to write, just a simple configuration.

module.exports = {
entry: ‘main.js’,
output: {
path: ‘dist’,
filename: ‘bundle.js’
}
};

Above you can see an example configuration for Webpack. We provide it the entry file of our application and the location to output the resulting bundle. In this simple example, we already solved the bundle part of our build process. Let’s continue with minfication.

var webpack = require(‘webpack’);

module.exports = {
entry: ‘main.js’,
output: {
path: ‘dist’,
filename: ‘bundle.js’
},
plugins: [ new webpack.optimize.UglifyJsPlugin() ]
};

Minification is just as easy to add. We use the UglifyJS plugin that’s built into Webpack to do this. Now we need to add the transpilation of ES6 to the configuration, because the current build will fail when our code contains ES6.

var webpack = require(‘webpack’);

module.exports = {
entry: ‘main.js’,
output: {
path: ‘dist’,
filename: ‘bundle.js’
},
loaders: [
{
test: /.js$/,
loader: ‘babel’
}
]
plugins: [ new webpack.optimize.UglifyJsPlugin() ]
};

To add the transpilation step we can use a Loader. A Loader is different from a regular plugin. It is able to “load” a specific file type. In this example we use it to load files that end on “.js”. If the file ends on “.js” we use the babel-loader to load the file. Babel loader will transpile the Javascript to ES6 and then pass it on to Webpack, which on it’s turn continues bundling the application.

A lot of cool things can be achieved using loaders. For instance, instead of loading .js files, we can even load .css files into our application:

// other configuration
loaders: [
{
test: /.css$/,
loader: ‘style!css’
}
]

In this example we use css loader to load all css files as a simple Javascript string and style loader to put those strings into the document in between style tags. This allows us to import css into our Javascript by writing: require(‘filename.css’).
 

Webpack at Coolblue

 
At Coolblue we use Webpack for Edith. Edith is a single page Javascript application we built using React and Redux. The application itself is a content management system used by the backoffice teams. The application features modern technologies like ES6 and React. Webpack works perfect for building these kinds of applications. Some cool plugins and loaders we use:

html-webpack-plugin – Generates the index.html
sass-loader – Compiles sass to css
eslint-loader – Does Javascript code quality checks on the fly
babel-loader – Transpiles ES6 to ES5
extract-text-plugin – Can extract loaded css into a separate file

We have a separate production and development build set up. The production build does minification, while the development watches files and generates source maps. This is how we switch between development and production:

// webpack.config.js
var env = process.env.NODE_ENV;
var config = { … } // the base configuration;

if (env === ‘production’) {
config.plugins.concat([ … ]); // adds plugins unique for production
}

if (env === ‘development’) {
config.devtool = ‘source-maps’;
config.watch === true; // automatically rebuild when files change
}

module.exports = config

You might be curious where the environment variable comes from. We pass this in via the command line, when running webpack:

NODE_ENV=production webpack

This command runs webpack, using webpack.config.js as the configuration. By adding the NODE_ENV statement we set the environment variable.
 

Conclusion

 
Webpack is a very versatile and powerful tool for building Javascript applications. It is however less suitable for building regular, server side dominant, websites. The best way to learn more about web pack is to try it out! That’s why I created a GitHub repository that you can clone and get’s you up and running with Webpack within minutes: Webpack demo.

This blogpost is based on my presentation at the Behind the Scenes of Coolblue. The slides can be foundhere. For more information and to get notified about the upcoming Behind the Scenes visit: Coolblue Behind the Scenes.

Do you like what you see here and like to stay up to date? Register yourself here to receive updates on new devblog posts: Subscribe for devblog updates

COMMENTGive your two cents.

*