Webpack Optimizing Production Build

Webpack Optimizing Production Build

Providing the mode configuration option tells webpack to use its built-in optimizations accordingly.

You just set the mode object in webpack.config.js file

mode:"development"

If you want to change the behavior according to the mode variable inside the webpack.config.js, you have to export a function instead of an object:

Insert the code into your  webpack.config.js file

module.exports = (env, argv) => {
 if (argv.mode === "development") {
   …
 }
 if (argv.mode === "production") {
   …
}

Insert the below code into your package.json file:

"scripts": {
   "dev": "webpack-dev-server --mode development",
   "prod": "webpack --mode production"
 },

In optimizing production build you must have to enable hot module replacement only when production is disabled.

So to enable hot module replacement when production is disabled here is the code:

document.addEventListener("DOMContentLoaded", async function() {
 const ReactApp = process.env.NODE_ENV === "development" ? hot(App) : App;
 ReactDOM.render(<ReactApp />, document.getElementById("root"));
});

Here you must have to install two dependencies to enable hot module replacement

npm install core-js regenerator-runtime --save

For More detail about these two dependencies here is the link:

core-js

https://www.npmjs.com/package/core-js

regenerator-runtime

https://www.npmjs.com/package/regenerator-runtime

Then our index.js file will look like:

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { hot } from "react-hot-loader/root";

document.addEventListener("DOMContentLoaded", async function() {
 const ReactApp = process.env.NODE_ENV === "development" ? hot(App) : App;
 ReactDOM.render(<ReactApp />, document.getElementById("root"));
});

Terser Webpack Plugin

This plugin uses terser to minify your javascript.

npm install terser-webpack-plugin --save-dev

Then add below code into your webpack.config,js file:

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin()],
  },
};

So, your webpack.config.js file look like

const webpack = require("webpack");
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const Dotenv = require("dotenv-webpack");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");

const BUILD_DIR = path.join(__dirname, "dist");
const APP_DIR = path.join(__dirname, "src");

const VENDOR_LIBS = ["react", "react-dom", "react-hot-loader"];

const config = {
 //Entry Point
 entry: {
   app: APP_DIR + "/index.js",
   vendor: VENDOR_LIBS
 },
 //Output
 output: {
   path: path.resolve(__dirname + "/dist"),
   filename: "[name].[hash].js",
   publicPath: "/"
 },
 resolve: {
   alias: {
     "react-dom": "@hot-loader/react-dom"
   }
 },
 //Loader
 module: {
   rules: [
     {
       test: /\.(js|jsx)$/,
       exclude: /node_modules/,
       use: {
         loader: "babel-loader"
       }
     },
     {
       test: /\.css$/i,
       use: ["style-loader", "css-loader"]
     },
     {
       test: /\.scss$/,
       use: [
         {
           loader: MiniCssExtractPlugin.loader
         }
       ][("css-loader", "sass-loader")]
     },
     {
       // For images
       test: /\.(png|jpe?g|gif|svg)$/,
       use: [
         {
           //Using File-loader for these files
           loader: "file-loader",
           /*In options we can set different things like format
            and directory to save*/
           options: {
             outputPath: "images"
           }
         }
       ]
     },
     {
       //For fonts
       test: /\.(woff|woff2|ttf|otf|eot)$/,
       use: [
         {
           //using file-loader too
           loader: "file-loader",
           options: {
             outputPath: "fonts"
           }
         }
       ]
     },
     {
       test: /\.html$/,
       use: "html-loader"
     }
   ]
 },
 //plugin
 plugins: [
   new Dotenv(),
   new HtmlWebPackPlugin({
     template: "./src/index.html",
     filename: "./index.html",
     publicPath: "/"
   }),
   new MiniCssExtractPlugin({
     filename: "app.css",
     disable: false,
     allChunks: true
   }),
   new CleanWebpackPlugin({
     cleanOnceBeforeBuildPatterns: ["dist"]
   })
 ]
};
module.exports = (env, argv) => {
 if (argv.mode === "development") {
   config.devtool = "inline-source-map";
   config.mode = "development";
   //webpack dev server
   config.devServer = {
     contentBase: BUILD_DIR,
     compress: true,
     port: 3000,
     stats: "errors-only",
     open: true,
     /* Don't refresh if hot loading fails. Good while implementing the       client interface*/
     hotOnly: true
     /* If you want to refresh on errors too , set hot:true */
   };
 }
 if (argv.mode === "production") {
   config.mode = "production";
   config.optimization = {
     splitChunks: {
       chunks: "all"
     },
     minimize: true,
     minimizer: [
       new TerserPlugin({
         cache: true
       })
     ]
   };
 }
 return config;
};

For more detail about Mode:

https://webpack.js.org/configuration/mode/

If You are new to Webpack then you must have to see our first article.

Get up and running with webpack and react

You also have to see our Hot module replacement article:

Webpack with Hot Module Replacement

You also have to see ourWebpack with Code Splitting article:

https://blog.carbonteq.com/webpack-with-code-splitting/