Getting Started with Webpack: Module Bundling Magic

Learn to use Webpack to bundle all your modules and static assets quickly and easily.

Related Course

Get Started with JavaScript for Web Development

JavaScript is the language on fire. Build an app for any platform you want including website, server, mobile, and desktop.

During application development, building parts of your application as modules helps improve reusability, and readability. With the rise of frontend frameworks like React, Angular 2, and Vue that hit on the point of building modules, compiling these modules has become quite essential too.

What is Webpack?

Webpack in it's simplest form is a module bundler. This means that webpack takes modules with dependencies and generates static assets representing those modules.

Still on the topic of bundling, here on Scotch, Peleke wrote an article on browserify — another module bundler.

What makes webpack so different from other module bundlers is the fact that it has watched other module bundlers and seen areas that needed improvements.

Webpack understands that CSS and images are also dependencies and treats them as such. To that end, WebPack is not just another module bundler — but offers a plethora of features we use as developers.

Goals of Webpack

As stated from the main webpack site, the main goals of creating another module bundler are the abilities to:

  • Split the dependency tree into chunks loaded on demand
  • Keep initial loading time low
  • Every static asset should be able to be a module
  • Ability to integrate 3rd-party libraries as modules
  • Ability to customize nearly every part of the module bundler
  • Suited for big projects

Installing Webpack

As an npm dependency, we can install webpack using npm. So from the command line install webpack using this command.

npm install -g webpack

This will install webpack on your command line and make it available anywhere. To test if webpack was successfully installed, open a terminal and type webpack. You should get something like this.

webpack 1.13.2

First run with Webpack

Let's create a working directory named webpack. In our project folder, we create an index.html and add this little boilerplate.

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>Getting Started with Webpack</title>
    <h1>WebPack is fun</h1>

Next, we create a main.js file, and we can add a simple console.log statement to our newly created file.

console.log('Hello from Webpack');

From the root of our working directory, run.

webpack main.js bundle.js

When it is done, you should see a message like this in the command line.

Hash: b882f8dcc15e61b5124e
Version: webpack 1.13.2
Time: 75ms
    Asset     Size  Chunks             Chunk Names
bundle.js  1.42 kB       0  [emitted]  main
   [0] ./main.js 34 bytes {0} [built]

If you check out the newly created bundle.js, you will see that webpack has created some wrapper around our own code. Because of this inclusion, we can use AMD syntax or requirejs to load javascript files.

Defining a Config File

While we could go ahead and keep running things from the command line, our builds are going to become more and more complex. As we bring in more JS modules, CSS, and things like TypeScript/ES6 and Sass, we'll want a more robust way of running Webpack.

This is where a config file comes into play.

Before we create a config file, you need to understand that webpack operates on the principle of an entry point and an output location, just like the command we ran above.

The webpack command line option takes in two params: the entry and the output.

To create a config file, in the root of our working directory, we create a webpack.config.js. This file exports our project's webpack configuration object.

module.exports = {
    entry: './main.js',
    output: {
        filename: './bundle.js'

Now from the root of our application, we can just run webpack and still have the same result.

Watching For Changes

One thing we developers hate is to do the same task over and over again. So, we tend to create shortcuts for ourselves. Instead of typing webpack in the command line whenever we bundle our code, we can instead watch for changes. This allows us to change a piece of code in our editor and automatically have it compiled.

Webpack provides two methods for watching for a file change. The first one is using the command line.

webpack --watch


webpack -w

As soon as you run this command, webpack will watch your project for any change, and when a change happens it basically reruns the webpack command.

Configuring "watchmode"

This is the second method that tells webpack to watch for the code for change. You can configure webpack to automatically watch the project directory whenever webpack is run. To do this, open your configuration file and set a new config attribute named watch to true.

module.exports = {
    entry: './main.js',
    output: {
        filename: './bundle.js'
    watch: true


Out of the box, webpack only knows how to read and understand .js files. Since webpack only knows how to speak .js, we need loaders to teach webpack some new tricks.

Loaders teach webpack how to load files for bundling. Let me explain, if you use a preprocessor like SASS, webpack needs to be taught how to convert SASS code to CSS, and this is where a loader comes in. We'll also need a loader for CSS.

This also allows for a lot of flexibility in webpack, as we can also create our own loaders. The community has already gone ahead and created a long list of loaders.

Since loaders are not added to webpack by default as it will make webpack bloated with a lot of dependencies, we need to npm install any loader required by our project.

NOTE: Make sure your project has a package.json file, if you don't have one or don't know how to create one, just run npm init from the root of the project.

Loading JavaScript

Nowadays, a lot of people are beginning to write javascript using es6 standard(ES2015). Since browser support is still low, we use third party transpiler like babel to convert our code to old JavaScript syntax.

So for us to be able to use webpack to convert our code, we need to install babel-loader. In this case, the babel loader depends on babel-core. Finally, since we want to convert from ES2015 or es6 to plain old es5 we need to tell babel what preset to use. For this, we also need a babel-preset-2015.

So we can install these dependencies using:

npm install --save-dev babel-loader babel-core babel-preset-es2015

Now in our webpack config file, we can add our module loader.

module.exports = {
    // ...
    module: {
        loaders: [
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel',
                query: {
                    presets: ['es2015']

As you can see, the module/loaders is an array of objects that test for a particular file and runs it through a loader. In this case, we checked for any file that ends with .js, we excluded any file in node_modules directory, any matched file should be run through the babel loader, and finally, tell babel to use es2015 preset.

So, we can change our main.js file to look like this:

const name = '';

setTimeout(() => alert(`Hello there from ${name}`), 300);

Then we run our webpack command again. After running this command, we link to the bundle.js file in our index.html. We open our index file in the browser, and after 300ms, we get an alert with the message "Hello there from".

Loading CSS

Loaders can be chained. This means we can use more than one loader on a particular file. There are two ways we can chain webpack loaders: the first is using an exclamation mark to separate loaders, while the other method is passing an array of loaders.

NOTE: Loaders are processed RTL (right to left).

Using webpack to load CSS requires two loaders: css-loader and style-loader. The first loader loads the content of a CSS file, whilst the second loader injects the CSS into the page.

npm install --save-dev css-loader style-loader

After installing the loaders, we can then tell webpack to process our css file like this.

module.exports = {
    // ...
    module: {
        loaders: [
                test: /\.css$/,
                exclude: /node_modules/,
                loader: 'style!css'

As usual, any file that ends with .css and is not in node_modules directory should be processed. To actually get our css to the page, we need to require it.

Our CSS main.css file looks like this.

h1 {
    color: red;

Edit main.js to look like this.


const name = '';

setTimeout(() => console.log(`Hello there from ${name}`), 300);

From the root of our project, run webpack, and it should compile without any error.

NOTE: css-loader can go as far as to get the content from css files in @import statements.

Development Server

Similar to browsersync's live reload, webpack creates a dev server to easily check our code. The server listens for any change in your project and then injects that change into the browser. No more ctrl+r.

To install the server, from the terminal execute:

npm install webpack-dev-server -g

Now that it is installed, go to your project directory and run webpack-dev-server command.

You should notice that the command doesn't stop running, it creates a buffer that waits for a user to change a piece of code. Also, the project will be available at http://localhost:8080/webpack-dev-server/.

Optimizing Webpack Output

Our final webpack bundle is not suitable for production, it has a lot of gunk comments and spaces. We all know that minification is good for getting scripts and styles ready for production. Don't worry, we won' t be installing another loader. For this particular reason, it makes more sense to use a webpack command to make our bundles production ready. Webpack went ahead and did just that. To get our bundle ready for production, from the root of our project, we can run:

webpack -p

This command is short for webpack --optimize-minimize. After running this command, all our bundles will be minified.

Problems with WebPack

IMHO, the only problem I see with webpack is the fact that trying to change your module bundler will definitely break your code. You will have to go into your project and change each place where you required a module.

This is not a big issue, more like a flimsy excuse as there is hardly any reason you might want to change an existing project's module bundler.


Is webpack a replacement for module bundlers? The answer is yes and no. As we always say, "it boils down to personal preference". Use the right tool for the right job, if you prefer other module bundlers to webpack, stick with that.

If you want to automatically load CSS in addition to JS, have code splitting features, and an easy to setup config file, Webpack may be the right tool for your job.

Samuel Oloruntoba

Hi there, I lead and build websites over @Rafdel. Reach out