Build a front-end engineering environment based on webpack4 from scratch

Time:2022-5-14

brief introduction

What is webpack?

In essence, webpack is a static module bundler for modern JavaScript applications. When webpack processes the application, it will internally create a dependency graph to map to each module required by the project, and then generate all these dependencies into one or more bundles—— Official documents from webpack

In short, webpack is a modern front-end development packer. The modern front-end is very popular and developed in a modular way. What webpack does is to reasonably package each JS module into a bundle or chunk. In the process of packaging, the new JS syntax and CSS preprocessing language can be transformed into a form more easily supported by the browser through the loader.

Webpack is based on nodejs. In most cases, you need to write a configuration file for it. The main structure of this configuration file is as follows:

module.exports = {
    Mode: 'development' // mode configuration
    Entry: '', // entry file
    Output: {}, // export file
    Module: {}, // process the corresponding module
    Plugins: [], // corresponding plug-ins
    Devserver: {}, // development server configuration (only used in development)
}

Next, we will complete these configurations step by step.

prepare

Initialization and installation

Execute under the specified foldernpm initInitialize.

mkdir webpackDemo&&npm init

Because the project is not a project to be published to NPM, you can only enter all the way after executing NPM init.

Dependencies for installing webpack and react:

npm install --save-dev webpack react react-dom

In the version after webpack 4, you also need to install webpack cli. The specific method is the same as above.

Create initial directory structure and files

Create the config folder in the root directory of the project and create the webpack. Config folder inside config. js。

Open package. In the root directory JSON configurationscripts:

"scripts": {
    "build": "webpack --mode production --config ./config/webpack.config.js",
  }

The purpose of configuring scripts script is to complete the input operation on the command line only by inputting NPM ‘specify configuration in script’ on the command line in the later execution process. For example, if you enter NPM build, you will automatically execute a long series of operations such as “webpack — mode production — config. / config / webpack. Config. JS”.

Create the code folder and the entry file of react:

Create the SRC folder in the root directory of the project, and create the index js、App. js、index. css。

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css'


ReactDOM.render(
  <App />,
  document.getElementById('root')
);

App.js

import React from 'react';

export default class App extends React.Component {
    render() {
        return <div>
            < p classname = "text" > build a react development environment based on webpack4</p>
        </div>
    }
}

index.css

.text{
    color:'red'
}

After completing the above operations, the project directory structure should look like the following

webpackDemo
│   node_modules
└───config
    │   webpack.config.js
└───src
    │   index.js
    │   index.css
    │   App.js
    package.json

Now that we have finished the simple initialization, let’s start to understand webpack.

Mode

Mode is a new concept in webpack4. It has three options:developmentproductionnone, which is used to set the optimization method of webpack.

development

Development mode, which optimizes the development speed and provides detailed error mechanism and browser debugging tools. And code compression is turned off, so that the code can be built faster.

production

Production mode, which can provide smaller code packages and remove the code that only runs in the development phase. Code obfuscation compression is automatically turned on.

to configure

module.export = {
  mode:'production' // 'development'||'production'||'none'
}

Program entry

Here, you can declare the starting point of an application. There can be one or more entrances. In general, there is only one entry in a single page. However, the public dependency can also be configured as the entry of a single page application, so that a single page application can also have multiple entries. In multi page applications, there are usually multiple entry files.

A simple single page application entry is as follows:


module.export = {
  mode:'production' // 'development'||'production'||'none',
  entry:'./src/index.js',
}

Output

Output is used to configure the file name and path of the packaged project. It is used to tell webpack how to output, where to output and what its name is.

const path = require('path');

module.export = {
  mode:'production' // 'development'||'production'||'none',
  entry:'./src/index.js',
  output: {
    //Note: this option should not be enabled in production mode
    pathinfo:true,
    //Destination path for all output files
    //Must be an absolute path (using the path module of node.js)
    path: path.resolve(__dirname, './../build'),
    //Output file name configuration
    filename: "[name].[hash].js"
    }
}

The filename here does not give it an actual name, but uses the template string to set the file name generated by webpack. The [name] in this setting represents the module name and defaults to main in the single entry file. [hash] will generate a hash of the module identifier, which is 20 bits by default. Its digits can be specified in the way of [hash: 16]. The packaged file name looks like thismain.f236aaeca342dfb1f8dd.js。 Hashing the generated file name after it helps us to download the new file after the project is redeployed. Because the referenced file name changes, the browser will no longer use the local cache.

loader

The function of webpack is to process and package various modules in front-end development. The role of loader is to handle these modules in webpack.

There are many kinds of modules in webpack. The common ones are:

  • Modular JS file
  • CSS / less / sass file
  • Pictures and static files

Loader is configured in module:

//Examples
const path = require('path');

const appSrc = path.resolve(__dirname, '../src')

module.exports =  {
    mode: 'development',
    //Entrance
    entry: './src/index.js',
    //Export
    output: {
        pathinfo: true,
        //Destination path for all output files
        //Must be an absolute path (using the path module of node.js)
        path: path.resolve(__dirname, './../build'),
        //Output file name configuration
        filename: "bundle.js"
    },

    module: {
        rules: [
            {
                test: /\. (js|jsx) $/, // used to specify the file type to support regular
                exclude: /node_ Modules /, // used to specify the folders to be excluded and optimize the packaging speed
                Include: appsrc, // specify the included folder to optimize the packaging speed
                Loader: "Babel loader", // the loader used for the specified file
            }
        ]
    }
};

To process these modules, you need to use different loaders. Before that, briefly introduce the loaders you need to use.

babel-loader

Babel is a syntax converter that allows you to freely use the latest syntax of JavaScript. It can convert the new syntax and JSX we write into a form that the browser can support friendly.

To use Babel loader, you need the following dependencies, which can be implemented bynpm install --save-dev babel-loader @babel/core @babel/preset-react @babel/preset-envInstall them.

  • babel-loader
  • @babel/core
    The core component of Babel, which contains the API of Babel.
  • @babel/preset-env
    Used to escape JavaScript syntax.
  • @babel/preset-react
    Used to escape react.

Configure Babel loader:

const path = require('path');

const appSrc = path.resolve(__dirname, '../src')

module.exports =  {
    mode: 'development',
    //Entrance
    entry: './src/index.js',
    //Export
    output: {
        pathinfo: true,
        //Destination path for all output files
        //Must be an absolute path (using the path module of node.js)
        path: path.resolve(__dirname, './../build'),
        //Output file name configuration
        filename: "bundle.js"
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                include: appSrc,
                loader: "babel-loader",
                options: {
                    //Specify Babel preprocessing escape
                    presets: ["@babel/preset-env", "@babel/preset-react"]
                }
            }
        ]
    }
}

After completing the above configuration, you need to configure Babel to convert the new syntax of react and JS. You can specify the method of Babel preprocessing by using the preset field in the option option in the webpack configuration as above.

You can also create Babel’s configuration file in the root directory of the project.babelrc.babelrcThe suffix RC comes from Linux. You can know many RC ending files in Linux after using Linux, such as Bashrc, RC is the abbreviation of run command, which translates into Chinese as a run-time command, indicating that the file will be called when the program is executed.

All Babel operations will basically read the configuration file, except for some that set the options parameter in the callback function. If there is no configuration file, it will be read from package The configuration is read from the Babel attribute of the JSON file.

stay.babelrcAdd the following statement to:

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

url-loader

The functions of URL loader and file loader are similar. They both enable webpack to package static files. URL loader is more powerful than file loader. It can be packaged in two ways.

URL loader has an important parameterlimit, this parameter is used to set the limit of the package file size. When the file is smaller than the specified parameter, it can return a file with dataurl (Base64). When the file is larger than the specified parameter, it will be packaged through file loader.

Configure URL loader:

const path = require('path');

const appSrc = path.resolve(__dirname, '../src')

module.exports =  {
    mode: 'development',
    //Entrance
    entry: './src/index.js',
    //Export
    output: {
        pathinfo: true,
        //Destination path for all output files
        //Must be an absolute path (using the path module of node.js)
        path: path.resolve(__dirname, './../build'),
        //Output file name configuration
        filename: "bundle.js"
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                include: appSrc,
                loader: "babel-loader",
                options: {
                    //Specify Babel preprocessing escape
                    presets: ["@babel/preset-env", "@babel/preset-react"]
                }
            },
            //Configuration of URL loader
            {
                test: /\.(png|jpg|gif)$/,
                loader: "url-loader",
                options: {
                    //Set the maximum file size of URL loader to dataurl
                    limit: 10000
                }
            }
        ]
    }
}

URL loader also has two parametersmimetypeandfallback, these two parameters are not used much, so I won’t repeat them here.

Style loader and CSS loader

Both style loader and CSS loader are used to process CSS files, but their functions are different.

CSS loader: used to read and process the contents of CSS files, such as minimize.

Style loader: inserts CSS files imported into JS in the form of import into<style></style>Inside the label.

The configuration in webpack is as follows:

const path = require('path');

const appSrc = path.resolve(__dirname, '../src')

module.exports =  {
    mode: 'development',
    //Entrance
    entry: './src/index.js',
    //Export
    output: {
        pathinfo: true,
        //Destination path for all output files
        //Must be an absolute path (using the path module of node.js)
        path: path.resolve(__dirname, './../build'),
        //Output file name configuration
        filename: "bundle.js"
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                include: appSrc,
                loader: "babel-loader",
                options: {
                    //Specify Babel preprocessing escape
                    presets: ["@babel/preset-env", "@babel/preset-react"]
                }
            },
            {
                test: /\.(png|jpg|gif)$/,
                loader: "url-loader",
                options: {
                    //Set the maximum file size of URL loader to dataurl
                    limit: 10000
                }
            },
            //Configure style loader and CSS loader for CSS files
            {
                test: /\.css$/,
                include: appSrc,
                use: [
                        'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            //Some configurations can be included
                            Modules: true | false, // whether to enable CSS modularization. The CSS file introduced after opening is only valid for the current page and will not affect the global environment
                            Minimize: true // in the development mode, it should be set to false to optimize the packaging speed
                        }
                    }
                ]
            }
        ]
    }
}

As shown above, when we are configuring multiple loaders for the same type of file. The loader can be declared in an array. The array item can be an object or just a string, depending on whether you have special settings for a loader. For example, when configuring CSS loader, the option option is also declared, and the minimize option is enabled in the option option. However, when configuring style loader, only one string is written.

It should be noted that the order of execution of loaders in the array is from the last item of the array. We have configured CSS loader later, which is executed first. This is more in line with the processing logic. First process the CSS and then insert it into the HTML.

plug-in unit

Plug-in is an extremely important function of webpack. Webpack provides rich plug-in interfaces, enabling developers to freely develop plug-ins to expand the functions of webpack.

Here we take the famous oneHtmlWebpackPluginFor example.

Imagine a scenario. When packaging, you need to manually create an HTML file, and then introduce various packaged files into it. Even after the HTML file is created, the package file name in hash form is set in config. After each package, we also need to change the file name introduced in HTML according to the change of hash name, which is a very low-level repetitive work.

HtmlWebpackPluginSolved this problem for us.HtmlWebpackPluginIt can automatically generate HTML files according to the templates provided by us and introduce the packaged content.

Let’s introduce itHtmlWebpackPluginUse process of.

Installation:npm install --save-dev html-webpack-plugin

After installation, create a folder in the root directory of the projectpublic, create a template file in itindex.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>

Then configure the plug-in in webpack:

const path = require('path');

const appSrc = path.resolve(__dirname, '../src')
//Introduce HTML webpack plugin
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports =  {
    mode: 'development',
    //Entrance
    entry: './src/index.js',
    //Export
    output: {
        pathinfo: true,
        //Destination path for all output files
        //Must be an absolute path (using the path module of node.js)
        path: path.resolve(__dirname, './../build'),
        //Output file name configuration
        filename: "bundle.js"
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                include: appSrc,
                loader: "babel-loader",
                options: {
                    //Specify Babel preprocessing escape
                    presets: ["@babel/preset-env", "@babel/preset-react"]
                }
            },
            {
                test: /\.(png|jpg|gif)$/,
                loader: "url-loader",
                options: {
                    //Set the maximum file size of URL loader to dataurl
                    limit: 10000
                }
            },
            //Configure style loader and CSS loader for CSS files
            {
                test: /\.css$/,
                include: appSrc,
                use: [
                        'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            //Some configurations can be included

                            Minimize: true // in the development mode, it should be set to false to optimize the packaging speed
                        }
                    }
                ]
            }
        ]
    },
    plugins: [
        //HTML template file processing plug-in
        new HtmlWebpackPlugin({
            file: 'index. HTML ', // generated file name
            template: 'public/index. HTML '// specify the template file
        })
    ],
}

Now execute on the command linenpm build, webpack will package the files in the SRC directory. A build file will be generated in the root directory and the packaged content will be output in it.

At this time, we have actually completed the basic configuration of webpack. However, the current configuration is packaged based on the development mode without compression. Obviously, it can not be used as a releasable version. In fact, it is also very simple to modify to the production mode, which can be realized in two ways.

  1. Modify the mode option in the configuration file and change development to production.
  2. Delete the mode option in the configuration and modify the package The build item in JSON scripts iswebpack --mode production --config ./config/webpack.config.js

In configuration 2, using — mode can set the packaging mode for webpack cli. After modification, the code is packaged again. At this time, the code is optimized by webpack production mode, confused and compressed, and becomes a release version.

devServer

In the daily development process, we can’t rebuild every time we modify something, so the development efficiency will be greatly affected. At this time, you need to start a service to listen for file changes. When the file is saved, it will be repackaged and help us refresh the browser automatically, so that we can observe the update in time.

There are several ways to complete the above operations. Here is only one of them. Usewebpack-dev-serverplug-in unit.

implementnpm install --save-dev webpack-dev-serverInstall the plug-in in module Add configuration item in explotdevServer

There are many configuration items for devserver. Here are some common configurations:

  • Contentbase: ”, tell the server from which directory to provide content
  • HTTPS: true | false, enable HTTPS
  • Compress: true | false, whether to enable compression
  • Host: ‘127.0.0.1’, specify the host address
  • Port: 23333, specify the port
  • Overlay: true | false, full screen overlay will be displayed in the browser in case of compiler error or warning.
  • Progress: true | false, output the running progress to the console.

Add devserver to the configuration:

const path = require('path');

const appSrc = path.resolve(__dirname, '../src')
//Introduce HTML webpack plugin
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports =  {
    //Entrance
    entry: './src/index.js',
    //Export
    output: {
        pathinfo: true,
        //Destination path for all output files
        //Must be an absolute path (using the path module of node.js)
        path: path.resolve(__dirname, './../build'),
        //Output file name configuration
        filename: "bundle.js"
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                include: appSrc,
                loader: "babel-loader",
                options: {
                    //Specify Babel preprocessing escape
                    presets: ["@babel/preset-env", "@babel/preset-react"]
                }
            },
            {
                test: /\.(png|jpg|gif)$/,
                loader: "url-loader",
                options: {
                    //Set the maximum file size of URL loader to dataurl
                    limit: 10000
                }
            },
            //Configure style loader and CSS loader for CSS files
            {
                test: /\.css$/,
                include: appSrc,
                use: [
                        'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            //Some configurations can be included

                            Minimize: true // in the development mode, it should be set to false to optimize the packaging speed
                        }
                    }
                ]
            }
        ]
    },
    devServer: {
        // HOST
        host: '127.0.0.1',
        //Port
        port: 23333,
        //The error message is displayed in the web page mask layer
        overlay: true,
        //Display operation progress
        progress: true,
    },
    plugins: [
        //HTML template file processing plug-in
        new HtmlWebpackPlugin({
            file: 'index. HTML ', // generated file name
            template: 'public/index. HTML '// specify the template file
        })
    ]
}

It should be noted that devserver should be used in the development environment, so the previous configuration needs to be modified now.

  1. Delete the mode entry in the configuration.
  2. Is package Add another startup command to the scripts of JSON"start": "webpack-dev-server --open --mode development --config ./config/webpack.config.js"
  3. Change the previous build item towebpack --mode production --config ./config/webpack.config.js

Now, execute NPM build, and the webpack will be packaged using production mode. When NPM start is executed, the development mode will be used for packaging, and the webpack dev server will start a service to listen for file changes.

Now execute NPM start to start development!

Advanced

In the above configuration, we have implemented the basic configuration of a react project development environment. But this is far from enough. In the actual project, many tools may be used to optimize the development speed. At the same time, we also need to write different configurations and optimize for different environments. In addition, it may also involve code segmentation, compression and other configurations.

Next, let’s improve the configuration of webpack step by step.

devtool

The devtool option in webpack is used to control whether and how to generate a source map.

To learn about source map, take a lookThis article。 Simply put, a source map is a file that helps us locate the location of the error message. The correct configuration of source map can improve the development efficiency and locate the wrong location faster.

There are many configurations of devtool in webpack. We canhereUnderstand it.

In the development environment, it is more recommended to usecheap-module-eval-source-map, it can not only help us locate the wrong source code accurately, but also provide faster construction speed and performance.

In the production environment, you can not start any source map (without configuring the devtool item), or you can usesource-map。 It should be noted that do not deploy the source map to the production server.

Configure loader for SVG file

In general, icons are required for projects. There are many common ways to use icons, such as sprite chart, font icon, SVG, etc. The usage of Sprite chart and iconfont does not need special treatment, so we won’t repeat it here. Here is a way to use the SVG icon.

adoptsvgr, the SVG icon can be directly introduced into the project in the form of react component.

Like this:

import React from 'react';
import { ReactComponent as Icon } from './icon.svg';

export default class App extends React.Component {
    render() {
        return <div>
            <Icon width={10} height={10} />
        </div>
    }
}

In react, the latest version of CLIcreate-react-app, svgr is integrated by default. It is also very simple to use in our own projects, only for.svgJust add a loader.

{
  test: /\.svg$/,
  use: ['@svgr/webpack'],
}

Svgr also supports node, react native and other processing methodsSvgr documentTo understand.

Build configurations in different environments

The construction objectives of production environment and development environment are very different. For example, in a development environment, you need faster build speed and stronger error prompts. However, in a production environment, you want to build smaller, lighter code and focus more on performance. Therefore, different configuration files are required for different environments. However, if the configuration is completely split, the two configuration files may contain a lot of duplicate code. At this time, we need to propose public configurations. In order to combine these configurations, you can usewebpack-merge

Next, let’s start using webpack merge for configuration optimization.

First, use NPM to install dependenciesnpm install --save-dev webpack-merge

Then, create a webpack. Net file in the config folder config. common. js 、 webpack. config. dev.js 、webpack. config. prod.js。 As the name suggests, these three configurations represent the configuration files of general, development and production modes.

Put forward the public configuration used in the previous configuration to webpack config. common. JS:

// webpack.config.common.js

//Package HTML file
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const appSrc = path.resolve(__dirname, '../src')

module.exports = {
    //Entrance
    entry: './src/index.js',
    module: {
        rules: [
            {
                //Configure the SVG icon loader, and you can directly import SVG icons in the form of components in the project
                test: /\.svg$/,
                include: appSrc,
                use: ['@svgr/webpack']
            }
        ]
    },
    plugins: [
        //HTML template file processing plug-in
        new HtmlWebpackPlugin({
            file: 'index.html',
            template: 'public/index.html'
        })
    ]
}

Configuration in development environment:

const merge = require('webpack-merge');
//Import public profile
const common = require('./webpack.config.common.js');
const path = require('path');

const appSrc = path.resolve(__dirname, '../src')

module.exports = merge(common, {
    mode: 'development',
    devtool: 'cheap-module-eval-source-map',
    //Export
    output: {
        pathinfo: true,
        //Destination path for all output files
        //Must be an absolute path (using the path module of node.js)
        //Chunk name configuration
        chunkFilename: '[name].chunk.js',
        //Output file name configuration
        filename: "bundle.js"
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                // exclude: /node_modules/,
                include: appSrc,
                loader: "babel-loader",
                options: {
                    presets: ["@babel/preset-env", "@babel/preset-react"]
                }
            },
            //For static files
            {
                test: /\.(png|jpg|gif)$/,
                loader: "url-loader",
                options: {
                    limit: 8192,
                    name: 'static/[name].[hash:8].[ext]',
                }
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options: {
                            minimize: false
                        }
                    }
                ]
            }
        ]
    },
    devServer: {
        // HOST
        host: '127.0.0.1',
        //Port
        port: 23333,
        //The error message is displayed in the web page mask layer
        overlay: true,
        //Display operation progress
        progress: true,
    }
})

Production environment profile:

const path = require('path');
const merge = require('webpack-merge');
const common = require('./webpack.config.common.js');
//Clear the previous package file before each package execution
const CleanWebpackPlugin = require('clean-webpack-plugin');

const appSrc = path.resolve(__dirname,'../src')

module.exports = merge(common, {
    mode: 'production',
    //Export
    output: {
        pathinfo: false,
        chunkFilename: 'js/[name].chunk.js',
        //Destination path for all output files
        //Must be an absolute path (using the path module of node.js)
        path: path.resolve(__dirname, './../build'),
        filename: "js/[name].[chunkhash:8].js"
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                include: appSrc,
                // exclude: /node_modules/,
                loader: "babel-loader",
                options: {
                    presets: ["@babel/preset-env", "@babel/preset-react"]
                }
            },
            //For static files
            {
                test: /\.(png|jpg|gif)$/,
                loader: "url-loader",
                options: {
                    limit: 10000,
                    name: 'static/[name].[hash:8].[ext]',
                }
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options: {
                            minimize: true
                        }
                    }
                ]
            }

        ]
    },
    plugins: [
        //Clear the build directory before packaging
        new CleanWebpackPlugin(['build'], path.resolve(__dirname, '../'))
    ]
});

Now that the configuration has been modified, we need to modify the package JSON, let the startup command reference different configuration files.

Change the startup configuration of development mode to"start": "webpack-dev-server --open --mode development --config ./config/webpack.config.dev.js"

The startup configuration of production mode is modified to"build": "webpack --mode production --config ./config/webpack.config.prod.js",

Now we usenpm startCommand to start the project and run webpack config. Dev.js file, which is the development configuration file. We can optimize the development mode in it.

usenpm buildCommand to start the project and run webpack config. Prod.js file, which is the production configuration file. We can optimize the production mode in it.

Prevent duplication of packaged files

When you execute the build command to package the file, the build directory will be generated in the root directory of the project, and the package file will be generated in it. After multiple builds, you will find that there may be multiple versions of packaged files in the build directory due to different hash values of the project name. To solve this problem, you can use plug-insclean-webpack-plugin

Install the plug-in firstnpm i clean-webpack-plugin --save-dev

The configuration is as follows:

const CleanWebpackPlugin = require('clean-webpack-plugin')

// webpack config
{
  plugins: [
    new CleanWebpackPlugin(['build'], path.resolve(__dirname, '../'))
  ]
}

After configuring the plug-in, execute the NPM build command. You will find that before each package, the build directory will be deleted and recreated.

Note that this plug-in is only used for production environment configuration.

summary

Here, we have realized the basic configuration of webpack and literacy of various concepts. In fact, this can only be regarded as the basic usage. To realize a truly perfect webpack configuration, it must be far more than that.

After mastering the above basic configuration, you can try to learn more deeply, such as optimization, tree shaking, construction speed optimization in production environment, etc.