Webpack ≥ v4 — The Complete Guide

Anass Daoudi
5 min readOct 16, 2018

--

Part1: Introduction — Overview

Before bundling vegetables
After bundling vegetables

What is webpack?

Webpack is a static module bundler for modern JavaScript applications.

Why using webpack?

Before webpack, we can run JavaScript on browser using one of the two ways below:

  • The first way consists on writing all JavaScript code in one file, and call it in a script tag in the HTML file. This choice causes scope, size(the browser will always reload all the file when a small piece change in it, so, it results on a loss of bandwidth), readability and fragility problems.
  • The other way consists on splitting JavaScript code using functionality cut concerns over multiple files and calling them in multiple script tags. This method ends to a solution that is hard to scale when many scripts are loaded at the same time which causes a network bottleneck.

So what solution was taken from the two ways?
Emmm, combining the two was the taken solution. The idea is simply giving the developer the good experience of splitting its functionalities over multiple files(so that they will be easy to maintain later) and bundling all of them into one script (to overcome network bottleneck as explained above).

In fact this concept is implemented by many tools like Gulp …etc.

But wait! There were not any scope collisions led by combining all files into one?
Absolutely yeah, if IIFE’s(Immediately Invoked Function ExpressionS) were not here! Wrapping script files in IIFE makes combing safe from scope collision.

Emmm, until here it’s ok. But what if I change a small piece of code in one script file?
The answer is you have to rebuild all script files to generate the bundle. That impacts performance negatively the way that browsers have to reload all bundle file again even for a little code changes(loss of bandwidth).

Also there are other performance problems related to this solution that I will list below:

  • When using a functionality from a library, like lodash may be, this solution integrates all code of this library into your bundle. That results in a huge file, hard to be covered, loss of bandwidth when browser reloading…etc.
  • This solution makes code splitting hard to do.
  • This solution makes lazy loading chunks of code hard to achieve and suppose lot of manual work from the developer.

So, how to overcome all these problems?
Let’s begin with resolving the first performance problem.

— Worth to be mentioned —

Node.js which is a JavaScript runtime that can be used in computers and servers outside browsers.
CommonJS comes and introduces require method, which makes loading modules in the Node.js script files simple, solves scope collisions problems and makes code clean since only the needed code is imported.

— Bad to announce —

Sadly, CommonJS is not available for browsers!
Fortunately, tools and bundlers like Browserify, RequireJS and SystemJS were created to make possible using modules in browsers.

— The Big good news —

Using JavaScript modules in browsers becomes an official feature of ECMAScript standard.

So why always webpack(until now at least)?
Bundlers like webpack, still recommended today, as first it’s faster and then not all browsers yet support this ESM (ECMAScript modules) new feature. Furthermore, webpack supports not only JavaScript modules but also any other modules format (CSS, fonts and images).
Also, I can add that webpack cares a lot about loading time and performance so as to deliver the best possible version of your project to the users. That’s why it is always adding and improving features like async chunks loading, bundle splitting, lazy chunk loading.

Finally, webpack maps every module(JavaScript, CSS, Node.js,…) and every assets(images, fonts,…) your project needs and generates one or more bundles based on an internal dependency graph that it builds.

Core concepts:

Webpack builds internally a dependency graph for bundling your project.
Webpack v4.0.0 and more does not require a configuration file to bundle your project, nevertheless it is incredibly configurable to better fit any kind of projects complexities.
Webpack is configured through the next properties :

  • Entry: webpack starts building its dependency graph from the entry point(s), then webpack will figure out which other modules that the entry depends on (directly or indirectly) and add them to the graph. Based on that graph, webpack will bundle your project.
  • Output: tells webpack where to emit the bundles it creates, and how to name them.
  • Loaders: let webpack convert any type of files into a valid webpack module that can be consumed by other modules in your application.
    (e.g.) The style-loader and css-loader loaders let webpack load CSS files as modules so that they can be imported by other ones in your application using this syntax: import ‘./filename.css';. That is to say, without these two loaders you can’t import CSS as modules in your application.
    Converting files into module using loaders is a feature specific webpack, and may not be supported by other bundlers tools.
    Only JavaScript and JSON files are understood by webpack without loaders out of the box.
    Technically, at a high level, in order to configure loaders in webpack, you have to manage two properties:
    test: regular expression used to specify file or files to be converted into webpack modules.
    use: indicates which loader should be used to do the transforming.

Example:
(e.g.) To configure loaders for CSS files, we do as below:
First, indicate which files are concerned (in our case, files which end with .css extension):
test:/\.css$/
Then, indicate loaders for that type of files, like below:
use:['style-loader','css-loader']

  • Plugins: webpack uses plugins to perform wide range of tasks like:
    Bundle optimization: e.g. Minifying CSS output files with a specific webpack plugin (e.g. removing all white spaces).
    Asset management: e.g. Customizing HTML output file with a specific webpack plugin (e.g. injecting bundles into the HTML outputted file in addition to what is set in the source one).
    We can use both built-in plugins and third party ones.
  • Mode: The mode parameter can be set to either development, production or none.
    Setting the mode lets webpack enable built-in optimization.
    You can override this built-in optimization and setting your own configuration based on the mode parameter value.
  • Browser Compatibility: webpack supports all browsers that are ES5-compliant (IE8 and below are not supported).
    If you want to support older browsers, you will need to load a polyfill to them (on demand loading, that is to say, the polyfill will be loaded just to these older browsers and not for those ES5-compliant ones).

Can’t wait to see you in the next parts of this webpack4 series.

Link To Part2

--

--

Anass Daoudi

full stack web developer / software and computer science engineer www.anass-daoudi.com