Quick Guide

Advertisement

Webpack is a module bundler. Its main purpose is to bundle JavaScript, SCSS, CSS, Image, and other file types together for transforming, bundling, or packaging.

We are going to see:

Webpack is a module bundler. Its main purpose is to bundle JavaScript, SCSS, CSS, Image, and other file types together for transforming, bundling, or packaging.

We are going to see:

[table-of-content]

Create a Project

First create a directory webpack-tutorial and execute npm init -y to create a package.json file.

E.g.

c:\xampp\htdocs\tutorials
位 mkdir webpack-tutorial

c:\xampp\htdocs\tutorials
位 cd webpack-tutorial\

c:\xampp\htdocs\tutorials\webpack-tutorial
位 npm init -y
Wrote to c:\xampp\htdocs\tutorials\webpack-tutorial\package.json:

{
  "name": "webpack-tutorial",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

See creating a sample project for webpack.

Install Webpack

To use the webpack, we need NPM and Node.js pre-installed. If you don鈥檛 have them then see聽Installing NPM and Node.js

c:\xampp\htdocs\tutorials\webpack-tutorial  (webpack-tutorial@1.0.0)
位 npm i webpack --save-dev
...
+ webpack@4.44.1
added 572 packages from 358 contributors and audited 575 packages in 176.855s

21 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

See installing webpack with npm command.

Install Webpack-cli

Install webpack-cli with command:

npm install webpack-cli --save-dev

E.g.

c:\xampp\htdocs\tutorials\webpack-tutorial  (webpack-tutorial@1.0.0)
位 npm i webpack-cli --save-dev
...
+ webpack-cli@3.3.12
added 572 packages from 358 contributors and audited 575 packages in 176.855s

21 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

See installing webpack-cli with npm command.

Create index.js

  • Create a聽src聽directory, and create a file聽index.js聽within it.
  • Add below code into our聽src/index.js聽file:
console.log("Hello webpack!")
  • Open package.json and replace:
    "test": "echo \"Error: no test specified\" && exit 1",
    with:
    "dev": "webpack --mode development"
  • Then execute npm run dev
    E.g.
位 npm run dev

> webpack-tutorial@1.0.0 dev c:\xampp\htdocs\tutorials\webpack-tutorial
> webpack --mode development

Hash: c51c08e1dfa5845fe276
Version: webpack 4.44.1
Time: 110ms
Built at: 09/01/2020 11:01:36 AM
  Asset      Size  Chunks             Chunk Names
main.js  3.81 KiB    main  [emitted]  main
Entrypoint main = main.js
[./src/index.js] 34 bytes {main} [built]

You can see the new file聽main.js聽generated into the聽dist聽directory.

/dist/main.js file

Here, We can see the un-minified JS bundle file.

Webpack Configuration

Create file聽webpack.config.js聽and add below code within it.

const path = require('path');
module.exports = {
     鈥
},

WebPack + HTML

Setup the plugin html-webpack-plugin with npm i html-webpack-plugin --save-dev.

c:\xampp\htdocs\tutorials\webpack-tutorial  (webpack-tutorial@1.0.0)
位 npm i html-webpack-plugin --save-dev
npm WARN webpack-tutorial@1.0.0 No description
npm WARN webpack-tutorial@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\webpack-dev-server\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ html-webpack-plugin@4.4.1
added 44 packages from 77 contributors and audited 619 packages in 23.857s

22 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Create file src/index.html and add below code within it:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Webpack tutorial</title>
</head>
<body>

</body>
</html>
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "src", "index.html")
    })
  ]
};

Install npm i webpack-dev-server --save-dev

c:\xampp\htdocs\tutorials\webpack-tutorial\src
位 npm i webpack-dev-server --save-dev
npm WARN deprecated chokidar@2.1.8: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.
npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.2.7 (node_modules\webpack-dev-server\node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN webpack-tutorial@1.0.0 No description
npm WARN webpack-tutorial@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ webpack-dev-server@3.11.0
updated 1 package and audited 619 packages in 15.884s

17 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Open the package.json.

You can see the webpack-dev-server with latest version in devDependencies as below:

"devDependencies": {
  ..
  "webpack-dev-server": "^3.11.0"
  ..
}

Now add "start": "webpack-dev-server --mode development --open", into the scripts.

See:

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

Type command npm start you can see in console - https://i.imgur.com/1u6f8tV.png

The chrome open the tab with URL: http://localhost:8080/.

If not then you can open the chrome and tyep the http://localhost:8080/.

you can see something https://i.imgur.com/B0DUZXp.png

webpack's loaders

Loaders are third-party extensions that help webpack deal with various file extensions. For example there are loaders for CSS, for images, or for txt files.

module.exports = {
  module: {
    rules: [
      {
        test: /\.filename$/,
        use: ["loader-b", "loader-a"]
      }
    ]
  },
  //
};

Working with CSS

Install npm i css-loader style-loader --save-dev

c:\xampp\htdocs\tutorials\webpack-tutorial\src
位 npm i css-loader style-loader --save-dev
npm WARN webpack-tutorial@1.0.0 No description
npm WARN webpack-tutorial@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\webpack-dev-server\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ style-loader@1.2.1
+ css-loader@4.2.2
added 23 packages from 57 contributors and audited 642 packages in 12.919s

27 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Open the package.json.

You can see the css-loader and style-loader with their latest version in devDependencies as below:

"devDependencies": {
  ..
  "css-loader": "^4.2.2",
  "style-loader": "^1.2.1",
  ..
}

Create src/style.css and add below code:

body {
  background: #161928;
  padding: 100px 0;
}

h1 {
    color: #ffffff;
    text-align: center;
    font-size: 50px;
}

Add the <h1>Webpack is Awesome!</h1> into the HTML file as below:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Webpack</title>
</head>
<body>
  <h1>Webpack is Awesome!</h1>
</body>
</html>

Add import "./style.css"; in our src/index.js file as below:

import "./style.css";
console.log("Hello webpack!");

Add our CSS Loader in Webpack module as below:

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

See complete webpack.config.js file code as below:

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

module.exports = {
    module: {
        rules: [{
            test: /\.css$/,
            use: ["style-loader", "css-loader"]
        }]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "src", "index.html")
        })
    ]
};

Now type the npm start.

You can see something like https://i.imgur.com/obrkot6.png

NOTE: If you already started the server with npm start then you can close it by pressing keys CTRL + C.

Working with SASS

Install npm i css-loader style-loader sass-loader sass --save-dev as:

c:\xampp\htdocs\tutorials\webpack-tutorial\src
位 npm i css-loader style-loader sass-loader sass --save-dev
npm WARN webpack-tutorial@1.0.0 No description
npm WARN webpack-tutorial@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\webpack-dev-server\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ css-loader@4.2.2
+ sass@1.26.10
+ style-loader@1.2.1
+ sass-loader@10.0.1
added 7 packages from 9 contributors, updated 2 packages and audited 649 packages in 11.456s

25 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Create src/style.scss file and add below code within it.

$body-bg-color: #158bad;
$h1-color: #fff;

body {
  background: $body-bg-color;
  padding: 100px 0;
}

h1 {
    color: $h1-color;
    text-align: center;
    font-size: 50px;
}

Open the file /src/index.js

Remove :

import "./style.css";
console.log("Hello webpack!");

And add

import "./style.scss";
console.log("Hello webpack!");

Open the webpack.config.js file and add remove our old code.

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

And add new code

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

Complete code webpack.config.js file as below:

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

module.exports = {
    module: {
        rules: [{
            test: /\.scss$/,
            use: ["style-loader", "css-loader", "sass-loader"]
        }]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "src", "index.html")
        })
    ]
};

Type npm start to see the changes.

You can see somehting like https://i.imgur.com/rLlw7g8.png

NOTE: If you already started the server with npm start then you can close it by pressing keys CTRL + C.

Working with modern JavaScript

webpack doesn't know on its own how to transform JavaScript code. This task is outsourced to a third-party loader, specifically babel-loader, with babel.

Install npm i @babel/core babel-loader @babel/preset-env --save-dev

c:\xampp\htdocs\tutorials\webpack-tutorial\src
位 npm i @babel/core babel-loader @babel/preset-env --save-dev
npm WARN webpack-tutorial@1.0.0 No description
npm WARN webpack-tutorial@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\webpack-dev-server\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ @babel/core@7.11.5
+ babel-loader@8.1.0
+ @babel/preset-env@7.11.5
added 135 packages from 68 contributors and audited 784 packages in 44.232s

32 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Babel need some configuration file babel.config.json. So create it and add blow code within it.

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

Add webpack module as below:

{
  test: /\.js$/,
  exclude: /node_modules/,
  use: ["babel-loader"]
}

Compelte code

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

module.exports = {
    module: {
        rules: [{
                test: /\.scss$/,
                use: ["style-loader", "css-loader", "sass-loader"]
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: ["babel-loader"]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "src", "index.html")
        })
    ]
};

Open the src/index.js file add add below code:

import "./style.scss";
console.log("Hello World!");

const sum = () => {
  console.log( 'Called!' );
};

sum();

Type npm start to see the changes.

You can see somehting like https://i.imgur.com/UGihwMu.png

NOTE: If you already started the server with npm start then you can close it by pressing keys CTRL + C.

JS Import & Export

We have a below code:

import "./style.scss";
console.log("Hello World!");

const sum = () => {
  console.log( 'Called!' );
};

sum();

Create new file scr/sum.js and add below code within it.

const sum = () => {
  console.log( 'Called!' );
};

export default sum;

Open the src/index.js and add below code:

// Import function sum from sum.js.
import sum from "./sum";

import "./style.scss";
console.log("Hello World!");

// Call sum.
sum();

There is no deference in old ocde. We have just create a sepereate JS file and export the sum() funciton.

And import it into the index.js file.

Type npm start to see the changes.

You can see somehting like https://i.imgur.com/UGihwMu.png

NOTE: If you already started the server with npm start then you can close it by pressing keys CTRL + C.

development mode vs production mode

As introduced earlier, webpack has two modes of operation: development and production. So far we worked only in development mode.

In development mode, webpack takes all the JavaScript code we write, almost pristine, and loads it in the browser.

No minification is applied. This makes reloading the application in development faster.

In production mode instead, webpack applies a number of optimizations:

  • minification with TerserWebpackPlugin to reduce the bundle size
  • scope hoisting with ModuleConcatenationPlugin

Add build command "build": "webpack --mode production"

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

Run npm run build

c:\xampp\htdocs\tutorials\webpack-tutorial  (webpack-tutorial@1.0.0)
位 npm run build

> webpack-tutorial@1.0.0 build c:\xampp\htdocs\tutorials\webpack-tutorial
> webpack --mode production

Hash: 9a02e1c3917fac845f1b
Version: webpack 4.44.1
Time: 2753ms
Built at: 09/01/2020 12:18:57 PM
     Asset       Size  Chunks             Chunk Names
index.html  167 bytes          [emitted]
   main.js   4.76 KiB       0  [emitted]  main
Entrypoint main = main.js
[1] ./src/style.scss 560 bytes {0} [built]
[3] ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/style.scss 366 bytes {0} [built]
[4] ./src/index.js + 1 modules 207 bytes {0} [built]
    | ./src/index.js 133 bytes [built]
    | ./src/sum.js 69 bytes [built]
    + 2 hidden modules
Child HtmlWebpackCompiler:
     1 asset
    Entrypoint HtmlWebpackPlugin_0 = __child-HtmlWebpackPlugin_0
    [0] ./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html 435 bytes {0} [built]

We can see the HTML and JS files are created in dist directory

  • /dist/index.html
  • /dist/main.js

Open the /dist/index.html file. You can see something as https://i.imgur.com/FUbsQ8f.png

Also If we see the /dist/main.js the file is genereated as minified file as https://i.imgur.com/uy0XHCb.png

Optimization

splitChunks

Consider a JavaScript application using Moment.js, the popular JS library for times and dates. There are better alternatives to it, but for a moment (no pun intended) let's prove my point.

Install the library in your project folder:

npm i moment

Now wipe out the content of src/index.js and import the library there:

import moment from "moment";

Run a build with npm run build and look at the output:

main.js 350 KiB 0 [emitted] [big] main

The whole library is bundled in the main entry point of our app. Not good. With optimization.splitChunks we can move out moment.js from the main bundle.

To configure code splitting open up webpack.config.js and add the optimization key to your configuration, configured as follows:

module.exports = {
  ...
  optimization: {
    splitChunks: { chunks: "all" }
  },
  ...
};
`

Run a build with npm run build and look at the output:

        main.js   5.05 KiB       0  [emitted]         main
vendors~main.js    346 KiB       1  [emitted]  [big]  vendors~main

BrowserSync

npm install --save-dev browser-sync-webpack-plugin
npm i -D browser-sync browser-sync-webpack-plugin webpack-dev-server
ADMIN@ADMIN-PC MINGW64 /c/xampp/htdocs/dev/wp-content/plugins/astra-pro-sites/admin/uag-templates (next-release)
$ npm install --save-dev browser-sync-webpack-plugin
npm WARN browser-sync-webpack-plugin@2.2.2 requires a peer of browser-sync@^2 but none is installed. You must install peer dependencies yourself.
npm WARN uag-templates@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\webpack-dev-server\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ browser-sync-webpack-plugin@2.2.2
added 1 package from 1 contributor and audited 785 packages in 12.296s

32 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

JSX

Install:

npm install --save-dev @babel/preset-react

Updated babel.config.json

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

webpack.config.js

// const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

module.exports = {
    module: {
        rules: [{
                test: /\.s[ac]ss$/i,
                use: [
                  // Creates `style` nodes from JS strings
                  'style-loader',
                  // Translates CSS into CommonJS
                  'css-loader',
                  // Compiles Sass to CSS
                  'sass-loader',
                ],
            },
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: ["babel-loader"]
            }
        ]
    },
    resolve: {
        extensions: ['*', '.js', '.jsx']
    }/*,
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "src", "index.html")
        })
    ]*/
};

Create a Project

First create a directory webpack-tutorial and execute npm init -y to create a package.json file.

E.g.

c:\xampp\htdocs\tutorials
位 mkdir webpack-tutorial

c:\xampp\htdocs\tutorials
位 cd webpack-tutorial\

c:\xampp\htdocs\tutorials\webpack-tutorial
位 npm init -y
Wrote to c:\xampp\htdocs\tutorials\webpack-tutorial\package.json:

{
  "name": "webpack-tutorial",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

See creating a sample project for webpack.

Install Webpack

To use the webpack, we need NPM and Node.js pre-installed. If you don鈥檛 have them then see聽Installing NPM and Node.js

c:\xampp\htdocs\tutorials\webpack-tutorial  (webpack-tutorial@1.0.0)
位 npm i webpack --save-dev
...
+ webpack@4.44.1
added 572 packages from 358 contributors and audited 575 packages in 176.855s

21 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

See installing webpack with npm command.

Install Webpack-cli

Install webpack-cli with command:

npm install webpack-cli --save-dev

E.g.

c:\xampp\htdocs\tutorials\webpack-tutorial  (webpack-tutorial@1.0.0)
位 npm i webpack-cli --save-dev
...
+ webpack-cli@3.3.12
added 572 packages from 358 contributors and audited 575 packages in 176.855s

21 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

See installing webpack-cli with npm command.

Create index.js

  • Create a聽src聽directory, and create a file聽index.js聽within it.
  • Add below code into our聽src/index.js聽file:
console.log("Hello webpack!")
  • Open package.json and replace:
    "test": "echo \"Error: no test specified\" && exit 1",
    with:
    "dev": "webpack --mode development"
  • Then execute npm run dev
    E.g.
位 npm run dev

> webpack-tutorial@1.0.0 dev c:\xampp\htdocs\tutorials\webpack-tutorial
> webpack --mode development

Hash: c51c08e1dfa5845fe276
Version: webpack 4.44.1
Time: 110ms
Built at: 09/01/2020 11:01:36 AM
  Asset      Size  Chunks             Chunk Names
main.js  3.81 KiB    main  [emitted]  main
Entrypoint main = main.js
[./src/index.js] 34 bytes {main} [built]

You can see the new file聽main.js聽generated into the聽dist聽directory.

/dist/main.js file

Here, We can see the un-minified JS bundle file.

Webpack Configuration

Create file聽webpack.config.js聽and add below code within it.

const path = require('path');
module.exports = {
     鈥
},

WebPack + HTML

Setup the plugin html-webpack-plugin with npm i html-webpack-plugin --save-dev.

c:\xampp\htdocs\tutorials\webpack-tutorial  (webpack-tutorial@1.0.0)
位 npm i html-webpack-plugin --save-dev
npm WARN webpack-tutorial@1.0.0 No description
npm WARN webpack-tutorial@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\webpack-dev-server\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ html-webpack-plugin@4.4.1
added 44 packages from 77 contributors and audited 619 packages in 23.857s

22 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Create file src/index.html and add below code within it:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Webpack tutorial</title>
</head>
<body>

</body>
</html>
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "src", "index.html")
    })
  ]
};

Install npm i webpack-dev-server --save-dev

c:\xampp\htdocs\tutorials\webpack-tutorial\src
位 npm i webpack-dev-server --save-dev
npm WARN deprecated chokidar@2.1.8: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.
npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.2.7 (node_modules\webpack-dev-server\node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN webpack-tutorial@1.0.0 No description
npm WARN webpack-tutorial@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ webpack-dev-server@3.11.0
updated 1 package and audited 619 packages in 15.884s

17 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Open the package.json.

You can see the webpack-dev-server with latest version in devDependencies as below:

"devDependencies": {
  ..
  "webpack-dev-server": "^3.11.0"
  ..
}

Now add "start": "webpack-dev-server --mode development --open", into the scripts.

See:

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

Type command npm start you can see in console – https://i.imgur.com/1u6f8tV.png

The chrome open the tab with URL: http://localhost:8080/.

If not then you can open the chrome and tyep the http://localhost:8080/.

you can see something https://i.imgur.com/B0DUZXp.png

webpack’s loaders

Loaders are third-party extensions that help webpack deal with various file extensions. For example there are loaders for CSS, for images, or for txt files.

module.exports = {
  module: {
    rules: [
      {
        test: /\.filename$/,
        use: ["loader-b", "loader-a"]
      }
    ]
  },
  //
};

Working with CSS

Install npm i css-loader style-loader --save-dev

c:\xampp\htdocs\tutorials\webpack-tutorial\src
位 npm i css-loader style-loader --save-dev
npm WARN webpack-tutorial@1.0.0 No description
npm WARN webpack-tutorial@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\webpack-dev-server\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ style-loader@1.2.1
+ css-loader@4.2.2
added 23 packages from 57 contributors and audited 642 packages in 12.919s

27 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Open the package.json.

You can see the css-loader and style-loader with their latest version in devDependencies as below:

"devDependencies": {
  ..
  "css-loader": "^4.2.2",
  "style-loader": "^1.2.1",
  ..
}

Create src/style.css and add below code:

body {
  background: #161928;
  padding: 100px 0;
}

h1 {
    color: #ffffff;
    text-align: center;
    font-size: 50px;
}

Add the <h1>Webpack is Awesome!</h1> into the HTML file as below:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Webpack</title>
</head>
<body>
  <h1>Webpack is Awesome!</h1>
</body>
</html>

Add import "./style.css"; in our src/index.js file as below:

import "./style.css";
console.log("Hello webpack!");

Add our CSS Loader in Webpack module as below:

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

See complete webpack.config.js file code as below:

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

module.exports = {
    module: {
        rules: [{
            test: /\.css$/,
            use: ["style-loader", "css-loader"]
        }]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "src", "index.html")
        })
    ]
};

Now type the npm start.

You can see something like https://i.imgur.com/obrkot6.png

NOTE: If you already started the server with npm start then you can close it by pressing keys CTRL + C.

Working with SASS

Install npm i css-loader style-loader sass-loader sass --save-dev as:

c:\xampp\htdocs\tutorials\webpack-tutorial\src
位 npm i css-loader style-loader sass-loader sass --save-dev
npm WARN webpack-tutorial@1.0.0 No description
npm WARN webpack-tutorial@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\webpack-dev-server\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ css-loader@4.2.2
+ sass@1.26.10
+ style-loader@1.2.1
+ sass-loader@10.0.1
added 7 packages from 9 contributors, updated 2 packages and audited 649 packages in 11.456s

25 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Create src/style.scss file and add below code within it.

$body-bg-color: #158bad;
$h1-color: #fff;

body {
  background: $body-bg-color;
  padding: 100px 0;
}

h1 {
    color: $h1-color;
    text-align: center;
    font-size: 50px;
}

Open the file /src/index.js

Remove :

import "./style.css";
console.log("Hello webpack!");

And add

import "./style.scss";
console.log("Hello webpack!");

Open the webpack.config.js file and add remove our old code.

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

And add new code

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

Complete code webpack.config.js file as below:

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

module.exports = {
    module: {
        rules: [{
            test: /\.scss$/,
            use: ["style-loader", "css-loader", "sass-loader"]
        }]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "src", "index.html")
        })
    ]
};

Type npm start to see the changes.

You can see somehting like https://i.imgur.com/rLlw7g8.png

NOTE: If you already started the server with npm start then you can close it by pressing keys CTRL + C.

Working with modern JavaScript

webpack doesn’t know on its own how to transform JavaScript code. This task is outsourced to a third-party loader, specifically babel-loader, with babel.

Install npm i @babel/core babel-loader @babel/preset-env --save-dev

c:\xampp\htdocs\tutorials\webpack-tutorial\src
位 npm i @babel/core babel-loader @babel/preset-env --save-dev
npm WARN webpack-tutorial@1.0.0 No description
npm WARN webpack-tutorial@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\webpack-dev-server\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ @babel/core@7.11.5
+ babel-loader@8.1.0
+ @babel/preset-env@7.11.5
added 135 packages from 68 contributors and audited 784 packages in 44.232s

32 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Babel need some configuration file babel.config.json. So create it and add blow code within it.

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

Add webpack module as below:

{
  test: /\.js$/,
  exclude: /node_modules/,
  use: ["babel-loader"]
}

Compelte code

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

module.exports = {
    module: {
        rules: [{
                test: /\.scss$/,
                use: ["style-loader", "css-loader", "sass-loader"]
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: ["babel-loader"]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "src", "index.html")
        })
    ]
};

Open the src/index.js file add add below code:

import "./style.scss";
console.log("Hello World!");

const sum = () => {
  console.log( 'Called!' );
};

sum();

Type npm start to see the changes.

You can see somehting like https://i.imgur.com/UGihwMu.png

NOTE: If you already started the server with npm start then you can close it by pressing keys CTRL + C.

JS Import & Export

We have a below code:

import "./style.scss";
console.log("Hello World!");

const sum = () => {
  console.log( 'Called!' );
};

sum();

Create new file scr/sum.js and add below code within it.

const sum = () => {
  console.log( 'Called!' );
};

export default sum;

Open the src/index.js and add below code:

// Import function sum from sum.js.
import sum from "./sum";

import "./style.scss";
console.log("Hello World!");

// Call sum.
sum();

There is no deference in old ocde. We have just create a sepereate JS file and export the sum() funciton.

And import it into the index.js file.

Type npm start to see the changes.

You can see somehting like https://i.imgur.com/UGihwMu.png

NOTE: If you already started the server with npm start then you can close it by pressing keys CTRL + C.

development mode vs production mode

As introduced earlier, webpack has two modes of operation: development and production. So far we worked only in development mode.

In development mode, webpack takes all the JavaScript code we write, almost pristine, and loads it in the browser.

No minification is applied. This makes reloading the application in development faster.

In production mode instead, webpack applies a number of optimizations:

  • minification with TerserWebpackPlugin to reduce the bundle size
  • scope hoisting with ModuleConcatenationPlugin

Add build command "build": "webpack --mode production"

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

Run npm run build

c:\xampp\htdocs\tutorials\webpack-tutorial  (webpack-tutorial@1.0.0)
位 npm run build

> webpack-tutorial@1.0.0 build c:\xampp\htdocs\tutorials\webpack-tutorial
> webpack --mode production

Hash: 9a02e1c3917fac845f1b
Version: webpack 4.44.1
Time: 2753ms
Built at: 09/01/2020 12:18:57 PM
     Asset       Size  Chunks             Chunk Names
index.html  167 bytes          [emitted]
   main.js   4.76 KiB       0  [emitted]  main
Entrypoint main = main.js
[1] ./src/style.scss 560 bytes {0} [built]
[3] ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/style.scss 366 bytes {0} [built]
[4] ./src/index.js + 1 modules 207 bytes {0} [built]
    | ./src/index.js 133 bytes [built]
    | ./src/sum.js 69 bytes [built]
    + 2 hidden modules
Child HtmlWebpackCompiler:
     1 asset
    Entrypoint HtmlWebpackPlugin_0 = __child-HtmlWebpackPlugin_0
    [0] ./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html 435 bytes {0} [built]

We can see the HTML and JS files are created in dist directory

  • /dist/index.html
  • /dist/main.js

Open the /dist/index.html file. You can see something as https://i.imgur.com/FUbsQ8f.png

Also If we see the /dist/main.js the file is genereated as minified file as https://i.imgur.com/uy0XHCb.png

Optimization

splitChunks

Consider a JavaScript application using Moment.js, the popular JS library for times and dates. There are better alternatives to it, but for a moment (no pun intended) let’s prove my point.

Install the library in your project folder:

npm i moment

Now wipe out the content of src/index.js and import the library there:

import moment from "moment";

Run a build with npm run build and look at the output:

main.js 350 KiB 0 [emitted] [big] main

The whole library is bundled in the main entry point of our app. Not good. With optimization.splitChunks we can move out moment.js from the main bundle.

To configure code splitting open up webpack.config.js and add the optimization key to your configuration, configured as follows:

module.exports = {
  ...
  optimization: {
    splitChunks: { chunks: "all" }
  },
  ...
};
`

Run a build with npm run build and look at the output:

        main.js   5.05 KiB       0  [emitted]         main
vendors~main.js    346 KiB       1  [emitted]  [big]  vendors~main

BrowserSync

npm install --save-dev browser-sync-webpack-plugin
npm i -D browser-sync browser-sync-webpack-plugin webpack-dev-server
ADMIN@ADMIN-PC MINGW64 /c/xampp/htdocs/dev/wp-content/plugins/astra-pro-sites/admin/uag-templates (next-release)
$ npm install --save-dev browser-sync-webpack-plugin
npm WARN browser-sync-webpack-plugin@2.2.2 requires a peer of browser-sync@^2 but none is installed. You must install peer dependencies yourself.
npm WARN uag-templates@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\webpack-dev-server\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ browser-sync-webpack-plugin@2.2.2
added 1 package from 1 contributor and audited 785 packages in 12.296s

32 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

JSX

Install:

npm install --save-dev @babel/preset-react

Updated babel.config.json

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

webpack.config.js

// const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

module.exports = {
    module: {
        rules: [{
                test: /\.s[ac]ss$/i,
                use: [
                  // Creates `style` nodes from JS strings
                  'style-loader',
                  // Translates CSS into CommonJS
                  'css-loader',
                  // Compiles Sass to CSS
                  'sass-loader',
                ],
            },
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: ["babel-loader"]
            }
        ]
    },
    resolve: {
        extensions: ['*', '.js', '.jsx']
    }/*,
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "src", "index.html")
        })
    ]*/
};
%d bloggers like this: