A Comprehensive Overview of WebPack

webpack

As the line between websites and web apps has continued to erode, the possibilities and challenges for developers have subsequently evolved. Since web apps are greatly dependent on JavaScript, the client-side is having to handle more and more. One of the best ways to manage the additional load is to use a module system – such as Webpack. Module systems make it easier for developers to keep things organized, and they ensure that content is delivered quickly and efficiently to users.

The importance of organization can never be understated; not only does it benefit individual programmers, but it also helps everyone else who must use the same codebase in the future. If you decide to manage your code using modules, you need a module bundler, and there’s no better bundler than Webpack.

What is Webpack?

Webpack generates static assets that represent modules with dependencies. There are several popular JavaScript module bundlers including Browserify, rollup, and jspm but Webpack remains a favorite because it treats web assets as modules with dependencies.

webpack workflow

According to Webpack’s website, the creators developed their module bundler with the following goals in mind:

  • To offer unparalleled customization
  • To reduce initial load times
  • To divide dependency trees into chunks that are loaded on demand
  • To allow every static asset to be a module
  • To allow integration of third-party libraries as modules

If you’ve never seen a Webpack config file before, they may appear daunting at first glance; however, once you grasp the syntax and the core philosophies behind the bundler, reading them will feel like second nature. First, you need to understand two basic principles:

  1.  With Webpack, everything can be a module. This includes JS files, CSS, images, and HTML. Consequently, any artifact may be divided into small, manageable chunks for reuse.
  2. Webpack only loads what you need when you need it. Other module bundlers typically combine all of the modules to generate a single, large bundle.js file. Such files can be as large as 15MB for dynamic web apps, which will take ages to load. In contrast, Webpack generates several smaller “bundle” files, which allows it to load parts of an app asynchronously. Therefore, users don’t have to wait for unnecessarily long load times to start using the app.

Version History

A new version, Webpack 2.2.0, was released in early 2017, and the development team is asking for feedback from users on which features they would like to see improved. This guide will focus primarily on the original incarnation of Webpack 2 since the versions are mostly the same. The creators have published an in-depth guide for those wishing to migrate to Webpack 2 if you’re still using version 1 as that has now been deprecated.

Differences in the new version will be addressed at the end of this article or as they arise.

Getting Started

Webpack works best with npm, so this guide will focus on an npm install. You can find more detailed information about setting up Webpack on their website; however, since the examples below will assume an npm install, there may be differences between this guide and other examples you see elsewhere.

Webpack configuration is such a dense subject that one could write an entire book on the subject. In fact, someone has written a book about it. The specific setup you need will depend heavily on your individual project. Therefore, this guide will only cover the basics and point you in the right direction to learn about more technical topics.

Installation

To install Webpack you need to have node.js installed. Once done, simply enter the following into your command line:

npm install -g webpack

Webpack should now be available anywhere. You can check to make it sure it was installed
successfully by opening a terminal and typing webpack.

Setup a Basic Compilation

To demonstrate how Webpack works at a very basic level, you’ll need to create two separate files: entry.js and index.html.

entry.js

document.write("Hello World.");

index.html

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

With these two files created, you can then run the following command in your console: webpack ./entry.js bundle.js. With this command, Webpack references the entry.js file and ends up creating the bundle.js file.

How to Define a Config File

Installation is a mere first step; you’ve got a lot more setting up to do before you can start making complex builds. Once you start piling on JS modules, CSS and the like, running things from the command line will become impractical, which is why we need a config file.

In Webpack, a config file is a common.js module where you can store all of the vital information about your build. To define a basic config file, make a file called webpack.config.js in the root directory and insert the following:

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

In the code above, you need to understand two principles: the entry point and the output location. The entry point is the name of the top level file or array of files that you need for your build. In this case, the entry is your main file, entry.js. The output location is the filename key, in this case bundle.js, for the file you want Webpack to build. Now, return to the command line and enter:

webpack

With the webpack.config file present, the command should now build your application using the information therein.

How to Watch For Changes

Webpack has a lot of convenient shortcuts so that you don’t have to waste your time repeating the same tasks. For example, rather than typing webpack in the command line every time you want to bundle your code, you can tell Webpack to watch for changes so that whenever you change code in the editor it will automatically be compiled.

There are a few ways to set this up. The first option is to type the following into the command line:

webpack --watch

Whenever you make a change, the webpack command should now automatically rerun.

Alternatively, you can configure watch mode. Watch mode monitors the project directory whenever the webpack command is run. You can turn on watch mode by opening your config file and inserting the following:

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

Loaders

By itself, Webpack can only understand .js files. Therefore, we need a way to transform things like images and CSS into JavaScript modules. That’s where loaders come in.

Webpack does not come pre-configured with any loaders, so you have to install the ones you need for your specific project. This may seem inconvenient; however, including all of the loaders by default would result in Webpack being very bloated with dependencies, so cherry picking only what you need makes for more efficient builds.

Loaders can be chained together. Among other things, this allows you to convert SCSS files to CSS before converting CSS to JavaScript. You can also create your own loaders; however, anything you need has likely already been taken care of by the Webpack community, so check the comprehensive list of loaders before attempting to make your own.

How to Chain Loaders

Chaining multiple loaders together to operate on the same file can be accomplished in two ways. The first method is to separate loaders with an exclamation mark. Alternatively, you can pass an array of loaders. Keep in mind that loaders are processed from right to left.

Before you can even load CSS, you need two loaders: css-loader and style-loader. The former loads the file’s content while the latter inserts it. If you’ve been following this guide, you can set these up entering the following in the command line:

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

Now that the loaders are installed, you can process your CSS file with the following code:

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

Plugins

Loaders are not the same thing as plugins. While loaders operate at the individual file level during or before bundle generation, plugins operate at the chunk level at the end of the process. A particularly useful plugin is uglifyJSPlugin, which lowers file size by obfuscating the contents of your bundle.js. Another pivotal plugin is the extract-text-webpack-plugin, which gathers all CSS into a single location and then extracts it into an external styles.css file. GitHub has an exhaustive list of them all.

Support for ES6

If you’re still using Webpack 1 and you’re coding with the ES6 standards, then you need a transpiler tool, such as babel, to ensure that your code works in most browsers. Webpack 2 supports ES6 transpilation out of the box, so you can skip this step if you’re using the latest version.

To enable Webpack to convert ES6 to ES5 with babel, you need three things: babel-loader, babel-core, and babel-preset-2015. Install these dependencies using the following command:

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

You can now add the module loader in your config file with the following code:

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

The module loader is an array that searches for specified files to run through a loader.
In the above code, you’re telling Webpack to look for files outside of the node_modules directory that end in .js, and then run them through the babel loader, which should use the es2015 preset.

Your Own Personal Development Server

While you’re working, Webpack can create a handy dev server so that you can review your code. The server automatically recognizes changes and updates the browser whenever a bundle is compiled. To install it, execute the following from the terminal:

npm install webpack-dev-server -g

After installing the server, run the webpack-dev-server command from the project directory. It should run continuously. Your project should then be viewable at http://localhost:8080/webpack-dev-server/.

Optimizing Your Output

Before your scripts and styles are ready for production, you need to minify your bundles. This can be accomplished with a very simple command. From the project root, run:

webpack -p

Minification gets rid of unnecessary characters in your source code to make things run more efficiently.

How Does Webpack Stack Up?

You may naturally be wondering how Webpack compares to other module bundlers. Fortunately, the developers have made a chart detailing the differences between Webpack and similar tools.

webpack comparison

Below are some additional observations:

Webpack vs Gulp

Comparing Webpack vs Gulp is like comparing apples and oranges. Gulp is not a module bundler like Webpack; it is a task runner. They can be used together, but you don’t really need Gulp if you know how to use Webpack. Other than unit tests and linting, Webpack can handle pretty much any task that Gulp can perform, which is why many developers choose to forgo using a task runner at all.

Of course, sometimes you’re on a deadline, and you don’t have time to learn the ins-and-outs the tools you’re forced to work with. If you’re new to Webpack but are familiar with Gulp, feel free to keep using both while you learn to maximize Webpack’s potential. Since Webpack takes time to configure, using a task runner like Gulp can help you out in a crunch; it will just make your project bulkier.

Webpack vs Browserify

Developers who have run various tests pitting Webpack vs Browserify found that Webpack is by far the faster bundler. In fact, Webpack can re-build pre-existing bundles about 40 percent quicker than Browserify. This is particularly helpful since you don’t have to keep refreshing the page multiple times to view changes as you make them.

On the other hand, when it comes to delivering an optimized final bundle, Browserify has the advantage. Once minified, a Browserify bundle can be about 40 percent smaller than a similar Webpack bundle. Therefore, some developer use Webpack as their default for development environments while keeping Browserify as their default for production builds.

What’s in Webpack 2?

The newly released Webpack 2 boasts some significant improvements, which the developers have described in great detail.

Most notably, babel is no longer necessary for transpiling import and export statements. You may now parse these statements, which enables you to take advantage of a new tree shaking feature. Also known as dead code elimination, this feature identifies unused code and gets rid of it, which results in more compact bundles.

In Summary – Webpack

If you plan on working with big teams of developers to create web apps for thousands of users, then you should get comfortable with Webpack. Even if you mostly work alone on personal projects, you can benefit greatly by embracing the powerful module bundler. Webpack has grown immensely since its inception and is growing faster in terms of popularity than the alternatives as can be seen by the trend chart below.

webpack trends

If you don’t have any current experience in Webpack but recognize the importance of module bundlers, try setting up the basic Webpack configuration as outlined in the guide.

Related Articles

A Comprehensive Overview of WebPack was last modified: January 23rd, 2018 by Cody Arsenault
Share This