Webpack: the module bundler for Javascript

0
331

Webpack is a module bundler for Javascript, today a fundamental tool for developers: this is what it is and how it works.

Webpack is defined by its own developers as a static module bundler for JavaScript applications. Its purpose is therefore to create a package of assets that can be used directly in the browser starting from a set of source files structured on different files and with complex dependency schemes.

To better understand how Webpack works, you need to understand some key concepts.

  • An entry point represents the starting point to be used during the building process. By default the entry point is src / index.js.
  • The output represents the opposite of the entry point, that is the folder where the resource pack that can be used by the browser will be generated. By default the output folder is dist.
  • The loaders are the true heart of webpack; they represent the various engines that will allow to generate the final package. By default Webpack uses only a loader for .js files but through this option we have the possibility to define others (for example for .sass or .less files ).
  • The plugins are similar to the loaders but deal with more general aspects of the build process while the loaders are dedicated to certain types of files: we can for example have plugins reporting or auto-install the dependencies required by the sources.
  • The mode represents the environment on which the webpack is launched. By default it is valued as <code>production</code>.

Installation

Webpack is a traditional Node package , which can then be installed via npm . You can install it locally within a single project (via <code>npm install webpack</code>) or globally between the system executables (via <code>npm -g install webpack</code>). Our suggestion is to always install it locally and use it through the npm scripts so you can change versions between projects without risk of backward compatibility.

The current version is 4.19.1 .

Configurability

Despite the convention over configuration approach and therefore the ability to run the build without any particular configuration, Webpack still allows you to customize any aspect.

At startup, Webpack searches for a file called webpack.config.js in the project root . If it is present, it will be used as a configuration file. However, you can change the file name using the option <code>–config</code>.

The webpack.config.js configuration file is all made of a standard NodeJS module whose job is to export a configuration object.

Let’s look at an example of configuration, based on the key concepts highlighted earlier:

module.exports = {
    mode: 'production',
    entry: './src/app.js',
    output: {
        path: require('path').resolve(__dirname, 'build'),
        filename: 'app.js'
    },
    module: [{
        test: /\.scss$/,
        use: [{
            loader: 'sass-loader'
        }]
    }]
}

In this simple example we have set up a production build process, whose entry point is in src / app.js and the output will be generated inside the folder build (the path must always be absolute, so the module was used path). Also included was a custom loader, called <code>sass-loader</code> able to compile .scss files .

There are many options available in webpack.config.js . Those interested in examining all the options, even those not detailed in this article, can consult the official documentation.

Asset management

One of the main differences between Webpack and its ancestors ( grunt and gulp in particular) is the possibility of considering all assets as addictions.

In the “traditional” approach, each type of asset (Javascript, style sheets, images, fonts …) was managed autonomously: packages were downloaded dedicated to code enhancements, CSS preprocessors, image optimizers and different “tasks” were configured. dedicated to each aspect of the application.

In Webpack, however, everything becomes addictive to something else. The entry point includes all the dependencies: CSS files, images, fonts … Webpack will be responsible for managing the various types of files, thanks to the many available loaders. Let’s deepen this concept with an example.

Sample project

In this chapter we will create a new project step by step using Webpack as a dependency builder.

First we initialize the project with npm and download the first dependencies:

<pre class=”brush: php; html-script: true”>
mkdir webpack-demo
cd webpack-demo
npm init
npm install webpack webpack-cli
</pre>

We create our entry point, for now empty, respecting the src / index.js convention and add a custom script inside our package.json :

"scripts": {
        "webpack": "./node_modules/webpack/bin/webpack.js"
    }

If everything was done correctly, launching the script with <code>npm run webpack</code> we should be able (in addition to display a warning because the mode is missing ) to generate a file dist / main.js with a little ‘minified Javascript code. The content of the file is a sort of default Webpack code, the one used to manage the inclusion at runtime of the various dependencies.

We download other dependencies:

<pre class=”brush: php; html-script: true”>
npm install jquery popper.js bootstrap
</pre>

We create the webpack configuration file in order to avoid warnings and modify our index.js :

module.exports = {
    mode: 'development'
};
window.jQuery = require('jquery');
require('bootstrap');

By launching again <code>npm run webpack</code>, we should now find a file no longer minimized (thanks to <code>mode: development</code>) and more full-bodied, as it also includes jQuery and Boostrap .

Before continuing, we introduce another concept, fundamental to optimize development time: the dev-server , or the possibility of having a web server dedicated to our application and that proceeds autonomously with the code builds. Download the dependency, add the script to package.json and edit the webpack.config.js file :

<pre class=”brush: php; html-script: true”>
npm install –save-dev webpack-dev-server
</pre>

[...]
    "webpack-dev-server": "./node_modules/webpack-dev-server/bin/webpack-dev-server.js"
[...]
devServer: {
        contentBase: require('path').join(__dirname, 'dist'),
        compress: true,
        port: 9000
}

Now launching <code>npm run webpack-dev-server</code>, we start a web server on port 9000 and a watcher that will change the build script every time a file is modified.

We now include Boostrap’s CSS. To do this we need two dedicated loaders:

<pre class=”brush: php; html-script: true”>
npm install css-loader style-loader
</pre>

So we modify our webpack.config.js to instruct webpack that the new modules must deal with files with the extension .css .

module: {
        rules: [{
            test: /\.css$/,
            use: ['style-loader', 'css-loader']
        }]
    },

We also create an index.html file inside our dist folder :

<pre class=”brush: php; html-script: true”>
<!doctype html>
<html>
<head>
<title>Webpack demo</title>
</head>
<body>
<h1>Hello from Webpack and Bootstrap!</h1>
<script src=”main.js”></script>
</body>
</html>
</pre>

If everything is correct, we should display the page title formatted with the default Bootstrap style.

As a last step in this mini-guide, we will include the FontAwesome iconset within our small project. We install the required dependencies: the icon set and a new Webpack loader.

<pre class=”brush: php; html-script: true”>
npm install file-loader font-awesome
</pre>

We then configure the loader and include the dependency within our entry point:

module: {
        rules: [{
            test: /\.(woff|woff2|eot|ttf|otf|svg)$/,
            use: 'file-loader'
        }]
    },

<pre class=”brush: php; html-script: true”>
require(‘font-awesome/css/font-awesome.css’);
</pre>

Now launching the webpack command (or via the webpack-dev-server ), and within the dist folder we should find new files, or the newly included webfonts. Webpack has renamed them with hashes, but this is not a problem, because internally it has also taken care of modifying the CSS fragment that includes them. To make a test, just add an icon in our HTML file:

<pre class=”brush: php; html-script: true”>
<h2>
<i class=”fa fa-android”></i>
<i class=”fa fa-apple”></i>
</h2>
</pre>

If everything is correct, we should see two icons: the Android robot and Apple’s biting apple.

Conclusions

Webpack is a very complex tool, and in this article we have scratched only a part of this complexity, but it allows us to learn the key concepts that allow then to deepen the required areas.

The documentation of Webpack is very well done, but also particularly large, and this may be dispersive: the advice is therefore to approach it in small steps, devoting time only to the sections that actually serve.

LEAVE A REPLY

Please enter your comment!
Please enter your name here