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: