Image for post
Image for post
Photo by Bernice Tong on Unsplash

If you write JavaScript, then you must heard of Webpack. Even if you don’t use it personally, you will still see it in your team’s project highly likely. I’m always resistant to learn it, probably because subconsiously I think it’s too complex to learn. But once I understand that it is just a module bundler and what a bundler is, everything becomes smooth and easy.

So what is Webpack?

In brief, Webpack scans through all your files (JS, TS, image, css …) and transform them into one big file. How does it achieve that? It creates a dependency graph which maps every module your project needs. Then, depending on this graph, it creates a new package which consists of the very bare minimum number of files required, often just a single bundle.js file which can be plugged in to the html file easily and used for the application.

To break down, it does the following:

  1. find the entry file and load its contents into memory
  2. match certain text within the content and evaluate those (for e.g. @import)
  3. find the dependencies based on previous evaluation and do the same with them
  4. stitch them all into a bundle in memory
  5. write the results to file system

Note that for Webpack, the module contains more than just JS ES or Common JS modules. They can be as inclusive as: Common JS modules, AMD modules, ES modules, CSS import, Images assets.

There are several ways to use Webpack:

  • Config
  • Webpack cli
  • Node api

But the Config file is the most common ways.

Run below command to install webpack relevant packages.

npm i webpack webpack-cli webpack-dev-server --save-dev

In your package.json, as the following script:

“webpack-dev-server”: “webpack-dev-server”,
“webpack”: “webpack”,
“prod”: “npm run webpack — — env.mode production”,
“dev”: “npm run webpack-dev-server — — env.mode development — hot”,

When you run above command, you need to make sure the default entry point src/index.js is there. For example when you run npm run dev and you should see a new folder named dist/, with a JavaScript file in it named main.js:

└── main.js

Create a webpack.config.js file with a Common JS module export:

module.exports = {

A config file can contain below properties which we can alter:

  • entry point
  • output
  • loaders
  • plugins

Entry point

An entry point is the starting point from which all the dependencies of a project are digested. The default entry point for webpack is src/index.js, and it's configurable. Note that webpack can have multiple entry points.


The output is where the resulting files are outputted. The default output for webpack is indist/. To change the output default we can do:

const path = require("path");module.exports = {
output: {
path: path.resolve(__dirname, "build")

Now webpack will put the bundle file in build folder.


Loaders are third-party extensions that help Webpack transform files that are not straightforward javascripts in modules.

Loaders work at the individual file level during or before the bundle is generated.


Plugins are third-party extensions that can alter how webpack works.

Plugins work at bundle level. Plugins can also modify how the bundles themselves are created. because they can register hooks within webpacks build system and access/modify the compiler, and how it works, as well as the compilation. Therefore, they are more powerful, but also harder to maintain.


Webpack has two modes of operations: development and production. The main difference between them is that production mode auto magically applies minification and other optimisations (e.g. scope hoisting with ModuleConcatenationPlugin) to your JavaScript code.

To configure webpack in production mode, inpackage.json add

"scripts": {
“prod”: “npm run webpack — — env.mode production”,
“dev”: “npm run webpack — — env.mode development”,

Development server

Webpack has a convenient package called webpack-dev-server for development. It helps launch a local server to serve our files.

In package.json script:

"scripts": {
"start": "webpack-dev-server --mode development --open",

Now run:npm start .

Your browser will open a tab containing your webpack bundle files in the script tag.

Modern JavaScript

To transform JavaScript code.we use babel-loader. Babel is a JavaScript compiler and “transpiler”. With modern JavaScript syntax as input, babel can transform it to compatible code that can run in nearly any browser. There are a few packages required to get this working:

  • babel core is the engine;
  • babel preset env for compiling lately Javascript down to ES5;
  • babel loader for webpack loader;

To configure babel, we create a babel.config.json. Here we configure babel to use preset-env:

{"presets": ["@babel/preset-env"]}

In webpack.config.js :

module.exports = {
module: {
rules: [
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"]


To work with HTML in Webpack we need html-webpack-plugin:

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html")

Then Webpack will load index.html file and bundle it.


To work with CSS in webpack we need

  • css-loader for loading CSS files with import
  • style-loader for loading the stylesheet in the DOM

Then in webpack.config.js:

module.exports = {
module: {
rules: [
test: /\.css$/,
use: ["style-loader", "css-loader"]

Note the sequence of the loader is from left to right. So we will load "css-loader" first and then "style-loader" . This is called loader chaining.


We need a file loader to handle files like images.

rules: [
test: /\.(png|jpe?g|gif|svg)$/,
use: [
loader: "file-loader",
options: { //set a separate folder for output
outputPath: 'images'

So that’s so much of it!

Happy Reading!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store