A Mostly Complete Guide To Webpack 5 (2020)
A Mostly Complete Guide To Webpack 5 (2020)
5. Mode
6. Code splitting
VALENTINO GAGLIARDI / GET IN TOUCH
4. Getting started with webpack
5. First steps with webpack
Published: Jun 5, 2020 - Last updated: Dec 1, 2020 6. Configuring webpack
7. Working with HTML
A mostly complete guide to 8. webpack's development
dev server
webpack 5 (2020) 9. Working with webpack's loaders
10. Working with CSS
11. Order of webpack loaders matters!
12. Working with SASS
13. Working with modern JavaScript
14. How to set up React, webpack 5, and Babel from scratch
15. Working with JavaScript's modules in webpack
16. Production mode
17. Code splitting with webpack
1. Code splitting with optimization.splitChunks
Even then, understanding how things work under the hood is beneficial The ultimate goal of webpack is to unify all these different sources and
because sooner or later you'll need to make some adjustment to the module types in a way that's possible to import everything in your
defaults. JavaScript code, and finally produce a shippable output.
In this guide we'll see what webpack can do, and how to configure it to
suit your needs.
Entry point
Disclaimer An entry point for webpack is the starting point from which all the
dependencies of a frontend project are collected. In practice, it's a simple
My tutorials are free, no strings attached. This means I have no obligation JavaScript file.
to keep them constantly updated to the latest releases of the packages.
Keep also in mind, frontend tooling changes so fast that I can't keep These dependencies form a dependency graph.
up updating every single blog post as quickly as $jsTool introduces
breaking changes. But, I try to do my best. If something doesn't work for The default entry point for webpack (since version 4) is src/index.js,
you, drop me a polite email, and I'll try to fix the tutorial if I have time. and it's configurable. webpack can have multiple entry points.
Enjoy!
Getting started with webpack Here webpack is looking for the default entry point, src/index.js.
To start off with webpack create a new folder and move into it to initialize Create the folder, and inside the same folder create a simple JavaScript
an NPM project: file:
https://www.valentinog.com/blog/webpack/ 5/34 https://www.valentinog.com/blog/webpack/ 6/34
30/04/2025, 12:22 A mostly complete guide to webpack 5 (2020) 30/04/2025, 12:22 A mostly complete guide to webpack 5 (2020)
output
mkdir src
loaders
echo 'console.log("Hello webpack!")' > src/index.js plugins
code splitting
Now run again npm run dev and you should see no more errors. The
result of this run is a new folder named dist/, with a JavaScript file in it For example, to change the entry point path we can do:
named main.js:
Configuring webpack Now webpack will look in source/index.js for the first file to load. To
change instead the output of our bundle we can do:
For simpler tasks webpack could work without a configuration, but you'll
hit the limit pretty soon. To configure webpack through a file create a
const path = require("path");
webpack.config.js in the project folder:
module.exports = {
touch webpack.config.js output: {
path: path.resolve(__dirname, "build")
Webpack is written in JavaScript, and runs on top on a headless JavaScript }
environment such as Node.js. In this file you'll need at least a };
module.exports, which is the Common JS export for Node.js:
With this configuration webpack will put the bundle in build instead of
module.exports = { dist. (To keep things simple we'll stick to the default in this guide).
//
}; Working with HTML
In webpack.config.js we can change how webpack behaves by adding A web application without an HTML page is almost useless. To work with
or altering: HTML in webpack we need to install a plugin, html-webpack-plugin:
entry point
https://www.valentinog.com/blog/webpack/ 7/34 https://www.valentinog.com/blog/webpack/ 8/34
30/04/2025, 12:22 A mostly complete guide to webpack 5 (2020) 30/04/2025, 12:22 A mostly complete guide to webpack 5 (2020)
</body>
npm i html-webpack-plugin --save-dev
dev </html>
Once the plugin is installed we can configure it: In a second we'll run this "app" with webpack's dev
development server.
//
};
The relevant configuration starts with the module key. Inside this key we
configure each loaders group, or a single loader, inside rules.
{
test: /\.filename$/,
use: ["loader-b", "loader-a"]
}
test tells webpack "hey, treat this filename as a module". use instead,
defines what loaders are applied to the file.
},
//
};
//
module.exports = {
module: {
rules: [
{
test: /\.css$/,
Once CSS loaders are in place you can extract CSS files with use: ["style-loader", "css-loader"]
MiniCssExtractPlugin. }
]
module.exports = {
Working with SASS
module: { To work with SASS in webpack we need to install at least the
rules: [ appropriate loaders.
{
test: /\.css$/, Loaders here are necessary for helping webpack to understand how to
use: ["css-loader", "style-loader"] deal with .scss files.
}
] To test SASS in webpack create a simple stylesheet in src/style.scss:
https://www.valentinog.com/blog/webpack/ 15/34 https://www.valentinog.com/blog/webpack/ 16/34
30/04/2025, 12:22 A mostly complete guide to webpack 5 (2020) 30/04/2025, 12:22 A mostly complete guide to webpack 5 (2020)
<!DOCTYPE html>
module.exports = {
<html lang="en"> module: {
<head>
rules: [
<meta charset="UTF-8"> {
<title>Webpack tutorial</title>
test: /\.scss$/,
</head>
use: ["style-loader", "css-loader", "sass-loader
<body> }
<h1>Hello webpack!</h1>
]
<p>Hello sass!</p> },
</body>
plugins: [
</html>
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.ht
Finally, load the SASS file in src/index.js: })
]
import "./style.scss"; };
console.log("Hello webpack!");
Again, the relevant configuration starts with the module key:
Before testing the page we need to install the loaders (and the sass
package for Node.js): const HtmlWebpackPlugin = require("html-webpack-plugin")
const path = require("path");
https://www.valentinog.com/blog/webpack/ 17/34 https://www.valentinog.com/blog/webpack/ 18/34
30/04/2025, 12:22 A mostly complete guide to webpack 5 (2020) 30/04/2025, 12:22 A mostly complete guide to webpack 5 (2020)
Once SASS and CSS loaders are in place you can extract CSS files with
module.exports = { MiniCssExtractPlugin.
module: {
rules: [ Working with modern JavaScript
{
test: /\.scss$/, webpack doesn't know on its own how to transform JavaScript code.
use: ["style-loader", "css-loader", "sass-loader This task is outsourced to a third-party loader, specifically babel-loader,
} with babel.
]
}, babel is a JavaScript compiler and "transpiler". Given modern JavaScript
// syntax as input, babel is able to transform it to compatible code that
}; can run in (almost) any browser.
{
"presets": [
"@babel/preset-env"
]
}
},
]
How to set up React, webpack 5, and
plugins: [ Babel from scratch
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.ht To use React components with webpack, alongside with babel loader you
}) should also install the babel preset for React:
]
}; npm i @babel/core babel-loader @babel/preset-env @babel/
To test the transformation, write some modern syntax in src/index.js: Once done, configure babel to use the React preset in
babel.config.json:
import "./style.scss";
console.log("Hello webpack!"); {
"presets": ["@babel/preset-env", "@babel/preset-react"
const fancyFunc = () => { }
return [1, 2];
}; At this point you can install React with:
Finally, you can write your components in the project. To test things out To try out ES modules in webpack let's create a module in a new file at
you can create a component in src/index.js: src/common/usersAPI.js with the following code:
Now when running webpack's dev server with npm start you should Now in src/index.js you can load the module and use the function:
see the component in the browser. (Don't forget to add a <div> in the
page with the relevant id).
import { getUsers } from "./common/usersAPI";
import "./style.scss";
Working with JavaScript's modules in console.log("Hello webpack!");
webpack
getUsers().then(json => console.log(json));
webpack treats a whole range of files as modules. But, let's not forget its
main purpose: loading ES modules. For a refresher on ES modules: All I need to know about ECMAScript
modules.
Up until 2015 JavaScript didn't have a standard mechanism for code
reuse. There had been a lot of attempts to standardize this aspect, which
resulted in a messy fragmentation during the years.
Production mode
As introduced earlier, webpack has two modes of operation:
You might have heard about AMD modules, UMD, or Common JS. There
dev
development and production. So far we worked only in dev
development
was no clear winner. Finally, with ECMAScript 2015, ES modules landed in
mode.
the language. We now have an "official" module system.
https://www.valentinog.com/blog/webpack/ 23/34 https://www.valentinog.com/blog/webpack/ 24/34
30/04/2025, 12:22 A mostly complete guide to webpack 5 (2020) 30/04/2025, 12:22 A mostly complete guide to webpack 5 (2020)
In development
dev mode, webpack takes all the JavaScript code we write, There is a limit that the webpack community considers the maximum size
almost pristine, and loads it in the browser. for the initial bundle of an application: 200KB. To understand why
keeping bundles small is paramount, search for "The Cost of JavaScript"
No minification is applied. This makes reloading the application in on Google.
development faster.
dev
There are three main ways to activate code splitting in webpack:
In production mode instead, webpack applies a number of
optimizations: with multiple entry points
It also set process.env.NODE_ENV to "production". This environment The first technique based on multiple entry points works well for smaller
variable is useful for doing things conditionally in production or in projects, but it's not scalable in the long run. Here we'll focus only on
optimization.splitChunks and dynamic imports.
dev
development.
Now when running npm run build webpack will produce a minified npm i moment
bundle.
Now wipe out the content of src/index.js and import the library
Code splitting with webpack there:
Code splitting refers to an optimization technique aiming at: import moment from "moment";
avoid big bundles Run a build with npm run build and look at the output:
avoid dependencies duplication
export function getUsers() { The problem is that ES modules are static, meaning we cannot change
return fetch(ENDPOINT) imports at runtime.
.then(response => {
if (!response.ok) throw Error(response.statusText) With a dynamic import instead we can choose when to load our code:
return response.json();
})
const getUserModule = () => import("./common/usersAPI");
.then(json => json);
}
const btn = document.getElementById("btn");
Nothing happens if you run npm run start to see and click the button
const getUserModule = () => import("./common/usersAPI");
in the interface.
Now imagine we want to load a list of users after someone clicks the Then in the event listener we chain then() to the dynamic import:
button. A "naive" approach can use a static import to load the function
from src/common/usersAPI.js: btn.addEventListener
dEv ("click", () => {
getUserModule().then(/**/);
import { getUsers } from "./common/usersAPI"; });
const btn = document.getElementById("btn"); This gives the ability to extract our getUsers function with object
destructuring:
btn.addEventListener
dEv ("click", () => {
btn.addEventListener
dEv ("click", () => {
getUserModule().then(({ getUsers }) => {
https://www.valentinog.com/blog/webpack/ 29/34 https://www.valentinog.com/blog/webpack/ 30/34
30/04/2025, 12:22 A mostly complete guide to webpack 5 (2020) 30/04/2025, 12:22 A mostly complete guide to webpack 5 (2020)
//
});
});
//
btn.addEventListener
dEv ("click", () => {
getUserModule().then(({ getUsers }) => {
getUsers().then(json => console.log(json));
});
});
When you now load the page for the first time with npm run start you
see the main bundle loaded in the console:
The lazy "chunk" is 0.js.
btn.addEventListener
dEv ("click", () => {
getUserModule().then(({ getUsers }) => {
getUsers().then(json => console.log(json));
});
});
Further topics
training on JavaScript, testing, and software development.
dev Let's
get in touch!
🦄 🦄
imports
Valentino Gagliardi
caching
is part of
Wrapping up - Resources The Great Django Webring
[Prev] [Random] [Next]
In this post we covered webpack's fundamentals: code splitting,
configuration, loaders, plugins. Of course there's a lot more.
:: All rights reserved 2025, Valentino Gagliardi - Privacy policy - Cookie policy ::
Once reading this introductory guide, check out these great resources:
webpack documentation
Survive JS - webpack