A Gentle Introduction to Webpack

In a previous post, we explored how to create a simple build system for typescript using SystemJS. This time, we are going to create a similar build system only this time using webpack.

Modules in NodeJS vs Javascript

Importing modules from our code is nothing new, different approaches exists in different languages and even Node has a method to do that built in the language. To do a quick summary, let’s see how module loading works in Node.

Before we start, let’s create a new folder to work and move into it:

$ mkdir webpack
$ cd webpack

For this example, we are going to create two files: “main.js” and “person.js”.

// person.js

var person = {
  firstName: 'David',
  lastName: 'Barreto'
};

module.exports = person;
// main.js

var person = require('./person.js');

console.log(person.firstName + ' ' + person.lastName);

In this example code, we are using the require syntax created by NodeJS to handle module loading. To prove that this approach works as expected, let’s execute the file “main.js” using Node.

$ node main.js
> David Barreto

Yes, it worked. Node was able to find the “required” file before executing “main.js”. What would happen if we try to execute the same code in the browser using Javascript instead of Node? Let’s create a file called “index.html” and insert the file “main.js” using the <script> tag:

<!-- index.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Webpack</title>
</head>
<body>
    <script src="main.js"></script>
</body>
</html>

When we open this file in a web browser and inspect its console, we would see an error message like the following (Chrome):

main.js:1 Uncaught ReferenceError: require is not defined

Off course the browser is complaining, the “require” syntax is not part of Javascript. Even if we tried to use the “import” syntax defined in ES6 we would get a similar error because no browser is yet able to support this feature natively.

There are two ways to deal with this problem. We could use a Javascript library to handle the module loading for us at runtime in the browser or use a Node library to create a single file with all the dependencies resolved so that a web browser would be able to execute the file. The first approach is the one followed by SystemJS while the latter is the approach of Webpack.

Note: Webpack also allows us to lazy load bundles so it is able to resolve dependencies at runtime if required.

Creating a Simple Bundle File with Webpack

We are now going to use webpack to create a bundle with all the dependencies resolved. The first step would be to install webpack.

$ npm install -g webpack

With the library installed globally, we can go ahead an invoke webpack to solve all the dependencies of the file main.js. The end result of this process will be a new javascript file that we are going to call bundle.js.

$ webpack main.js bundle.js

If we inspect our folder, a new file was created:

.
├── bundle.js
├── index.html
├── main.js
└── person.js

To verify that this new file has all the dependencies resolved, we are going to modify our index.html file to use bundle.js instead of main.js.

<!-- index.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Webpack</title>
</head>
<body>
    <script src="http://bundle.js"></script>
</body>
</html>

Loading the modified version of this file in the browser, we can now see in the browser console the message we expected. Webpack has saved the day.

Controlling Webpack with a Config File

Apparently, good developers are meant to be “lazy” so, instead of typing webpack main.js bundle.js to create the bundle file, we want to only write webpack in the console and get the same result. To do that, we need to create a file named webpack.config.js where we are going to configure webpack to do just that.

// webpack.config.js

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

Done, we can now just write webpack in the console and webpack is going to read the “entry” file main.js, resolve all its dependencies and create an output file called bundle.js. Lazyness level one accomplished.

Using Webpack Locally

It’s almost always a bad practice to rely on a global dependency for a project. So far we used a globally defined webpack library to bundle our project. It’s time to get serious and use a local dependency instead.

We are going to start this process by creating a package.json file with default values.

$ npm init -f

Next, to be thorough, we are going to uninstall our global version of webpack to be completely sure that we are using the local version only.

$ npm uninstall -g webpack

Good, we are ready now to install it again this time locally (avoiding the use of the -g flag) as a development dependency.

$ npm install webpack --save-dev

Because we don’t have webpack globally available, we can’t just write webpack in the console. What we need to do is to add a new “script” in our package.json file to invoke the locally installed version of webpack.

package.json

{
  "name": "webpack",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "dependencies": {},
  "devDependencies": {
    "webpack": "^1.13.1"
  },
  "scripts": {
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

With this configuration for Node, we can run the local version of webpack using the command:

$ npm run build

In a next blog post, we are going to dive deeper into webpack configuration, how to work with Typescript with the “import” syntax and how to lazy load “chunks”.

Until next time.

Update: The following blog post “Configuring Webpack with Typescript” can be found here.

5 thoughts on “A Gentle Introduction to Webpack”

  1. “Latest implementations of Node now support the ES6 import syntax natively. In this example we are going to continue using the “old” syntax to be consistent with webpack which doesn’t yet support ES6 out of the box.”

    Can you exactly mention which version – v6.2 doesn’t support it

    1. You’re right, I wrongly assumed that Node 6 was fully supporting ES6 and thus the import syntax but is not. I will update the blog post, thanks!

  2. This saved me after a couple days of trying to figure out webpack. Thank you! This should be a newcomer’s first location for a tutorial on webpack.

  3. great tutorial for beginners who have zero knowledge of what webpack is …… awesome start up ..perfectly done through step by step explanation. was struggling from 3 days to understand how webpack works 🙂

So, what do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.