Webpack Module Bundler

What is Webpack?

Webpack is a module bundler. It takes Modules with dependencies and generates static assets representing those modules.

The official webpack docs are somewhat difficult to process, so give it some time.

Websites are advancing into web applications, so they are depending increasingly on JavaScipt. This outcomes in bigger amounts of code on the customer side. As a rule, using a module framework should enhance not only the development but also the user experience.

Browserify or RequireJS are also popular when it comes to module systems. Both of these are extremely helpful and do a great job but webpack goes a little further.


Why webpack?

With webpack you can easily split your application into multiple files

Your codebase can be split into multiple chunks and those chunks can be loaded on demand reducing the initial loading time of your application. It can also make your chunks cache friendly by using hashes.

It can build and bundle CSS, preprocessed CSS, compile-to-JS languages (like CoffeeScript), images and more by utilising webpack loaders.
Loadders are pieces of code that can be injected in the middle of the compilation stream.
Keep in mind that webpack can only process Javascript natively, but loaders are used to transform other resources into Javascript. By doing so, every resource forms a module.

Another great feature is webpack plugins. Theese have the ability to inject themselves into the build process to do all sorts of crazy stuff.

That said, let's go and create a simple webpack implementation


Prerequisite

You will need to have Node and npm installed on your machine


Install and config

Install webpack through npm:

sudo npm install webpack -g

Add a package.json file to the root of your projects directory with the following npm init command or copy and save the snippet below as your package.json.

{
  "name": "WebpackDonderDemo",
  "author": "Cloudoki",
  "version": "0.0.1",
  "description": "The next big thing!",
  "private": true,
  "scripts": {},
  "dependencies": {},
  "devDependencies": {}
}

Add webpack to the newly created package.json file.

npm install webpack --save-dev

Now the webpack command is available via the CLI. You can find a detailed list of options on the official site or via webpack -h.

Some of the webpack´s configuration options are:

  • webpack – for building once for development
  • webpack -p – for building once for production (minification)
  • webpack --watch – for continuous incremental build
  • webpack -d – to include source maps
  • webpack --colors – for making things pretty

Basic example

Create a webpack.config.js in the root of our projects directory to keep things organised. This file is the heart of your webpack project. Here you will add your loaders, plugins and specify all your other project configurations.

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

Create a simple JavaScript file called main.js with the following contents:

document.write("Webpack is the next big thing!");

Run the webpack command via the CLI you should have a bundle.js. Webpack command found your webpack.config.js file and created the bundle.

To ensure all is working add the following script tag to your index.html:

<script type="text/javascript" src="bundle.js"></script>  

Multiple modules

Create a new file called anotherModule.js with the following contents:

document.write("I am just another Module!");

Require this file in your main.js:

require("./anotherModule.js");

Run the webpack command from the CLI and open up your bundle.js file. You should now see both files there.

Run webpack -p and bundle.js will be minified.

Adding loaders

There is a list of loaders on the webpack site if you are curious. For this demo we are going to set up jquery and exposing it to the browser. For that we will need expose-loader installed and off course the jquery itself.

Add expose-loader and jquery to your package.json like so:

npm install expose-loader jquery --save-dev

Update the loaders section in your webpack.config.js

module: {
    loaders: [
        { test: require.resolve("jquery"), loader: "expose?$!expose?jQuery"}
    ]
}

You can now use jquery inside your modules, without the need to require it in every time, since we exposed it inside the loader. If you open your browser's console you should have it there as well.

Adding CSS and images

Add the following loaders to our package.json.

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

Add these new modules to the loaders section in your webpack.config.js:

{ test: /\.css$/, loader: 'style-loader!css-loader' },
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=6192'}

The limit parameter in the url-loader is for inlining images (base64) if they are equal or under 6kb.

With these new loaders there are a few tweaks we have to do for webpack to do its magic.

Inside the webpack.config.js adjust the output parameter to look something like this:

output: {
    path: './dist', // This is where images, css and js will go
    filename: 'bundle.js'
}

We added the path.

You need to update your script reference in your HTML as your bundle.js is now in the dist directory.

Lets add a new module file called imagesLoader.js and require that (require("./imagesLoader.js");) in the main.js.

Add the following to your imagesLoader.js with the inclusion of two images (under or equal to 6kb if you want to see inline base64 URL being built).

imgOne = document.createElement("img");
imgOne .src = require("./one-small-image.png");
document.body.appendChild(imgOne);

imgTwo = document.createElement("img");
imgTwo.src = require("./one-big-image.png");
document.body.appendChild(imgTwo);

Create a new CSS file called app-styles.css with the following contents:
You can also user sass or less, just add the loader you need.

body {
  background-color: #123456;
}

Require that (require("./app-styles.css");) in the main.js.

Re-run webpack from the command line

Testing

Karma integrates very easily with webpack and allows us to use our same webpack configuration file. By reusing so much of the same config it really does cut down the number of areas something can go wrong.

comments powered by Disqus