webpack introduction

Webpack: An Introduction

Javascript development has come to a stage today that it is fairly common to have a build process in place for carrying out various tasks. Webpack is one such module bundler which solves this problem of transpiling files along with many other module loading capabilities. It has become fairly popular these days and provides us with a lot of neat features such as bundling, hot module replacement, converting/transpiling files from one format to another, linting files etc. The only downside being that you have to know a fair bit of configuration in order to use Webpack to its full potential. Also you need to use NPM and not bower, and also a module system must be used (all three  AMD, common js and ES6 modules are supported, but you need to choose one).

The need for using Webpack can be more clearly understood when one writes modular javascript code. That is when you separate your code into modules which can then be used as dependencies in other modules. As more and more websites are turning into web apps, the complexity of javascript that is written in one keeps increasing with time. And hence arise different problems related to performance, maintenance, and security. To solve these, one resorts to using different tools for injecting dependencies in modules and managing them. Webpack manages all the dependencies for you, without the need to worry about the order of loading dependencies. It also manages other things such as concatenation, minification and other pre-processing related stuff. And with Webpack, modules are not just javascript files, they can be HTML, CSS and static assets such as images as well!

Webpack can be considered as a specialized task runner which optimally processes input files into output files. It does so by using making use of components called loaders. For installing Webpack, you need to have NPM installed. After that, as with all node modules, you do a npm install webpack -g for installing it globally. You can then use the CLI for transpiling files, but since projects are more complex than just putting files together and passing them as parameters in the command line, we would mostly use a config file for running Webpack. For doing so, we need to create a webpack.config.js file in our project’s root directory. A configuration file in itself is a module, so it needs to have a module.exports statement. The object being returned should have two important keys for a basic build, namely the entry key which is a string or array of strings that point to the file(s) that we need to include in our build. The other key which we need to specify is the output key which is an object that can contain the directory to output to, the filename etc. So a basic configuration file which converts a single app.js file to a bundle.js file would like the following:

module.exports = {
    entry : "./app.js",
    output: {
        filename: "bundle.js"
    }
}

The above file seems like not much is happening, and that we are just converting one app.js file to another bundle.js file which is meaningless. But even this basic configuration will make Webpack look inside the app.js files, and if you have required or imported other modules inside it, then Webpack will go and fetch those dependencies as well. All this is done with Webpack maintaining a dependency graph for the developer so that they do not focus on maintaining the order of importing modules. So a lot will be happening in this scenario if you have referenced other modules in your app.js file. But many times, you need to process multiple files. In that case, the entry key will have an array of files as its value. That is, the line will now become

entry: ["./app.js","./file.js"]

Using the above configuration, you can create a very basic build for your project. But what makes Webpack a flexible build tool is the capability of extending it by making use of loaders. By using loaders, you can go beyond the processing, minification and concatenation of javascript files of the build tool. I’ll take the example of babel loader which is the most common transpiler for converting ES6 (or ES2015) code into ES5. I already assume you have the babel cli, babel preset es2015 installed. If not, install them using NPM using the command npm install babel-cli babel-preset-es2015 babel-loader --save .You also need to install babel loader which plugs babel in as a loader for Webpack. Also, for transpiling, you need a .babelrc file in your project directory with an object containing the presets key and its value set to an array containing an item value es2015. Now, for the configuration of Webpack, we will add a module key in the config which will have the following object:

module.exports = {
    entry : "./app.js",
    output: {
        filename: "bundle.js"
    },
    module: {
        loaders: [
            {
                test: /\.js/,
                exclude: /node_modules/,
                loader: "babel-loader"
            }
        ]
    }
}

Update: Webpack 2 has been released and although there are not many breaking changes. They have kept the API backwards compatible, but one of the keys (module loaders has been renamed to rules) has been changed for better readability but it still is backwards compatible.

The above configuration adds the babel loader to our build pipeline. The babel loader runs on all javascript files except for those that are present in the node_modules folder (as specified in the RegEx in the test and exclude sections). And this is all you need to do to add a loader to Webpack! Similarly, you can add a preloaders key in the module object to add preloaders to your build. They can be useful for linting purposes and jshint is usually used for this purpose. After creating your configuration file, all you need to do is type in “webpack” in your command line and the tool will do everything that you specify in the config file. You can also run it in watch mode by using “webpack -w” which will re run the build everytime you make changes to a file in the directory. And if you wish to serve your files over HTTP using webpack, you can install webpack-dev-server for doing so. There are a lot of other nice features in Webpack such as hot module replacement, adding CSS to modules, building multiple bundles, chaining loaders, adding plugins etc. but this post should be enough to get you started and you can play with other features. If you want a more detailed post, do let me know in the comments section below and I will write another one with some advanced builds!