preface

The configuration date is 2021 1/6/28. The node. js version is 14.15.4. This article documents the learning process of manually configuring a basic Vue3 project from scratch using Webpack5.

Project file address for reference: gitee.com/willflow/ju…

To create a Vue3 project using VUE-CLI:

  • Install/upgrade vue-cli: NPM install -g@vue /cli
  • Ensure that the VUe-CLI version is later than 4.5.0: vue –version
  • Create a project select Vue 3.0: vue create project name
  • CMD create Project name Winpty vue. CMD create Project name

All configuration items in this document are basic usage methods. For more configuration items, refer to the official documents. If there is improper in the article, but also hope not stingy correction, rational communication.

Part one: Initialize the project

Goal: To complete a basic configuration that can be packaged and run in preparation for gradual improvement. The basic directory structure for the example is as follows

Create the project directory, initialize package.json, install Webpack, and add the configuration file webpack.config.js

# create folder and go to mkdir demo && CD $_ # to initialize package.json NPM init// Use the default NPM init -y optionNPM I webpack -d NPM I webpack-cli -d/ / webpack command execution, will find webpack - cli and execute this bag. See the entry file logic: node_modules/webpack/bin/webpack. Js
Copy the code

The root directory creates the webpack.config.js file and configures entry and output

//webpack.config.js
const path = require('path');
module.exports = {
    entry: './src/main.js'.// Configure entry files, single entry uses strings, multiple entry uses objects
    output: {                           // The storage location of the packaged project file on the hard disk
        filename: '[name].js'.// the [name] placeholder can be written in a way that supports multiple entries
        path: path.resolve(__dirname, 'dist'),},mode: 'production'.// Tell Webpack to use the built-in optimizations for the corresponding schema, which default to Production
}
Copy the code

Vue and related dependencies

npm i vue -S                 -s = --save-d = --save-dev = install
npm i vue-loader -D          // Parse and convert.vue files. Extract the logic code Script, style code style, and HTML template, and then hand them to the corresponding loader for processing
npm i @vue/compiler-sfc -D   // Compile the parsed VUE single page component (SFC) into JS
Copy the code
//webpack.config.js
const { VueLoaderPlugin } = require('vue-loader');
module: {
    rules: [{test: /\.vue$/,
            loader: 'vue-loader',},]; }plugins: [
        new VueLoaderPlugin(),
]
Copy the code

Use Vue in main.js

import { createApp } from 'vue'
import App from './App.vue'       // The test file app.vue and the index. HTML for mounting are created by ourselves

createApp(App).mount('#app')
Copy the code

CSS dependencies

npm i css-loader -D  // For processing.css files
npm i style-loader -D  // Mount styles to the head section of the page as a 
Copy the code
//webpack.config.js module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader' // loader executes from right to left, css-loader is executed first]},]; }Copy the code

html-webpack-plugin

npm i html-webpack-plugin -D  // At the end of the package, an HTML file is automatically generated and the js file generated by the package is imported into the HTML file
Copy the code
//webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
    new HtmlWebpackPlugin({
        template: path.join(__dirname, 'index.html'),
        filename: 'index.html'}),]Copy the code

clean-webpack-plugin

npm i clean-webpack-plugin -D  // Empty the output configuration folder before packaging
Copy the code
// //webpack.config.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
plugins: [
    new CleanWebpackPlugin()
]
Copy the code

webpack-dev-server

npm i webpack-dev-server -D  // Open the packaged file in the browser as file and cannot send ajax requests. So you need devServer to start a server locally and send requests as HTTP.
Copy the code
// //webpack.config.js
module.exports = {
    devServer: {
        contentBase: path.resolve(__dirname, 'dist'),
        open:true.port:8888.// Part 3 uses portFinder to automatically get the available port numbers
        hot:true.hotOnly:true,}}Copy the code

To integrate the webpack-dev-server command into webpack-CLI, run the following command: webpack-cli4

//package.json
"scripts": {
    "dev": "webpack serve --config webpack.config.js"
},
Copy the code

At this point, type NPM run dev on the command line and the project can be packaged and started normally

Part two: Introducing common libraries

Goal: To introduce VUex, VUE-Router, Element Plus, Axios, ESLint into the project

Create router, Store, Views, Components, assets folders in the SRC folder

Vuex and vue – the router

npm i vuex --save
npm i vue-router --save  
Copy the code

Configure router/index.js with optional Hash mode (createWebHashHistory) and history mode (createWebHistory). History mode requires back-end support.

import { createRouter, createWebHashHistory } from 'vue-router'

const routes = [
  {
    path: '/'.name: 'Home'.component: () = > import('.. /views/home.vue')}, {path: '/about'.name: 'About'.component: () = > import(/* webpackChunkName: "about" */ '.. /views/about.vue')}]const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router
Copy the code

The configuration store/index. Js

import { createStore } from 'vuex'

export default createStore({
  state: {},mutations: {},actions: {},modules: {}})Copy the code

Vue-router and vuex are introduced in main.js

import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
import router from './router'

let app = createApp(App)
app.use(store)
app.use(router)
app.mount('#app')
Copy the code

After configuration and introduction, vuex and vue-Router are ready for normal use, and the test pages in the example (home.vue, about.vue) are created by themselves.

Element Plus

npm i element-plus --save 
Copy the code

Use the on-demand import method of the official website to reduce the packaging volume, need to download the plug-in babel-plugin-import

npm i babel-plugin-import -D  // Change the method of importing from the entire component library to require from specific modules to implement component loading on demand
Copy the code

To use this plug-in, you need the Babel configuration file: babel.config.js

plugins: [
        [
            "import",
            {
              libraryName: 'element-plus'.customStyleName: (name) = > {
                return `element-plus/lib/theme-chalk/${name}.css`; }},]]./ / interpretation:
// When Babel parses:
import { xxx } from 'element-plus'
// will be converted to:
var xxx = require('element-plus/lib/xxx')
// Instead of introducing the entire library named element-plus, introduce the specific module 'element-plus/lib/ XXX '. So WebPack thinks it's dependent on the specific XXX rather than the whole Element-Plus. The corresponding style file is also introduced.
Copy the code

main.js

// Introduce and use element-plus in main.js
import {
    ElButton,
    ElSelect
} from 'element-plus';

const Elcomponents = [
    ElButton,
    ElSelect
]

Elcomponents.forEach(component= > {
    app.use(component )
})
Copy the code

Axios

npm i axios -S
Copy the code

Axios can be further encapsulated

// http.js
import axios from 'axios'

axios.defaults.baseURL = baseURL
// Request interception
axios.interceptors.request.use(config= > {
    // do something
    return config
},error= > {
    return Promise.reject(error)
})
// Return interception
axios.interceptors.response.use(response= > {
    // do something
    return response
},error= > {
    return Promise.reject(error)
})

export function get(url, params) {
  return axios.get(url, {
    params
  }).then((res) = > {
    // do something
    return res.data
  }).catch((e) = > {
    console.log(e)
  })
}
Copy the code

Use it directly in vUE components, or extract it into functions and use it in components

// Define the function that gets the data
import { get } from './http'

export function getXxx() {
  return get('/api/getXxx').then((result) = > {
    // do something
    return result
  })
}

/ / use
import { getXxx } from '... '
const list = await getXxx()
Copy the code

ESLint

npm i eslint -D
npm i eslint-plugin-vue -D
Copy the code

Generate esLint files

./node_modules/.bin/eslint --init
Copy the code

In the generated configuration file, add the plug-in

"extends": [
        "plugin:vue/vue3-essential".// Verify the Vue3 logic code
        "plugin:vue/vue3-strongly-recommended".// Verify the Vue3 template
        "eslint:recommended"                      // Introduce esLint core functionality].Copy the code

Eslint-plugin-node: eslint-plugin-promise: eslint-plugin-import: eslint-plugin-import Optimized eslint-plugin-standard for import syntax: Base configuration (deprecated)

Part three: Split webpack.config.js

Objective: Starting with Part 3, we need to split webpack.config.js into the following three files for easy debugging and rollout.

  • Webpack.dev.js: development environment configuration
  • Webpack.prod. js: production environment configuration
  • Webpack.common.js: shared configuration for development and production environment configurations

The difference between development and production environments

  • Production environments may need to separate CSS into separate files so that multiple pages share the same CSS file
  • Production environments require compression of HTML/CSS/JS code
  • The development environment requires the SourceMap file for easy debugging
  • The development environment requires HMR, devServer and other functions
  • .

In summary: the development environment helps us to develop and test the integration quickly, and the production environment ensures that the packaging process in the live environment is the optimal experience.

Install webpack – merge

npm i webpack-merge -D   // Use it to join arrays and merge objects, as shown below:
Copy the code
merge( 
    {a : [1].b:5.c:20}, 
    {a : [2].b:10.d: 421})// The result of the merge
{a : [1.2].b :10 , c : 20.d : 421}
Copy the code

Introduce Webpack-merge, which splits files as described in the instructions. The configuration is simple, refer to the project file.

mode

The mode option is used to tell Webpack to use the built-in optimizations for the corresponding mode. The options are Development, production or None. Typically, development environments use development and production environments use production.

module.exports = {
  mode: 'development'};Copy the code

The environment variable

Use cross-env to set node environment variables across operating systems.

npm i cross-env -D
Copy the code
"scripts": {
    "dev": "cross-env NODE_ENV=development webpack serve --config webpack.dev.js"."build": "cross-env NODE_ENV=production webpack --config webpack.prod.js"
  },
Copy the code

sourcemap

Sourcemap produces files that map the source location of the compressed code before the transformation, eliminating the difficulty of debugging the compressed code. For details, see the document. Set parameter values as required. Different parameter values significantly affect the build and rebuild speed.

// webpack.dev.js
devtool: 'eval-cheap-module-source-map'.// webpack.prod.js
devtool: 'cheap-module-source-map'.Copy the code

Part four: WebPack basic shared configuration

Goal: To improve webpack.common.js

The use of Babel

npm i babel-loader -D   // Acts as a bridge between Webpack and Babel and does not transform JS code
Copy the code

Add a new rule to webpack.base.js rules. The node_modules folder is excluded, because the NPM library is already compiled and does not need to be compiled again, which affects packaging speed.

// webpack.base.js
{
   test: /\.js$/,
   exclude: /node_modules/,
   loader: 'babel-loader',}Copy the code

For the next configuration of Babel Polyfill, please refer to my previous article, comparing common configurations of Babel Polyfill

CSS style configuration

In part 1, we installed and configured csS-loader and style-loader to enable Webpack to recognize CSS syntax and insert CSS code into HTML files as style tags. Now we can further improve this part of the configuration.

1. The CSS – importLoaders loader

Configures the number of loaders before csS-loaders apply to @import resources. For example: let’s first assume we have two files: style.css and body.css. Style. CSS via @import ‘body.css’; The introduction of the body. The CSS:

/* style.css */
@import 'body.css';
.style-div {
    display: flex;
}

/* body.css */
.body-import {
    /* body import */
    display: flex;
}
Copy the code

The WebPack configuration items used for the test are as follows

rules: [
    {
        test: /\.css$/,
        use: [
            {
                loader: 'css-loader'.options: {
                    importLoaders: 1   // The other configuration does not use importLoaders}},'postcss-loader']}]Copy the code

Then we compare the packing results with importLoaders=1 on and importLoaders not on

/* Not enabled importLoaders */
.body-import {
    /* body import */
    display: flex;
}

.style-div {
    display: -ms-flexbox; display: flex; } -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -ImportLoaders =1 */
.body-import {
    /* body import */
    display: -ms-flexbox;
    display: flex;
}

.style-div {
    display: -ms-flexbox;
    display: flex;
}
Copy the code

You can see that by comparison

  • Display: flex is not used in importLoaders’ body.css; If the prefix is not automatically added, Postcss is not used in the files imported by @import.
  • Use display: flex in body.css with importLoaders=1; Prefixes indicate that Postcss is applied to the files introduced by @import.
  • Therefore, based on project requirements, we need to use importLoaders to ensure that the loader after CSS-Loader works properly.

2. CSS preprocessor

Preprocessors can improve development efficiency and experience. I use Sass as a preprocessor in my project.

Node-sass is no longer maintained. Use the official recommended Dart-sass. You can install sass-Loader and dependent Sass directly.

npm i sass sass-loader -D  // Sass-loader only compiles sASS syntax to CSS. CSS -loader and style-loader can be used together later
Copy the code
module.exports = {
    / /...
    module: {
        rules: [{test: /\.sass$/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader'.options: {
                            importLoaders: 1}},'sass-loader'}]}};Copy the code

3. PostCSS and autoprefixer

PostCSS parses CSS into an AST and then transforms it through plug-ins to produce a new, processed CSS, similar in functionality and implementation to Babel. Here we install PostCSS and use Autoprefixer to automatically add browser prefixes.

npm i postcss-loader postcss autoprefixer -D 
Copy the code
module: {
        rules: [{test: /\.sass$/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader'.options: {
                            importLoaders: 2}},'sass-loader'.'postcss-loader']]}}Copy the code

Create postcss.config.js and.browserslistrc files in the root directory to use autoprefixer.

// postcss.config.js
module.exports = {
  plugins: [
    require('autoprefixer')]}// .browserslistrc 
> 1%
not ie <=8
Copy the code
// Original style
display: flex;
// Automatically add the browser prefix
display: -webkt-box;
dispaly: -ms-flexbox;
display: flex;
Copy the code

4. sass-resources-loader

Sass variables, mixins, and functions are automatically introduced into each Sass file. Unused mixins and functions are not compiled into CSS after being packaged, so you don’t have to worry about volume.

npm i sass-resources-loader -D  
Copy the code
{
    test: /\.scss$/,
    use: [
        {
            loader: MiniCssExtractPlugin.loader,
        },   
        {
            loader: 'css-loader'.options: {
                importLoaders: 2,}},'sass-loader'.'postcss-loader',
        { loader: 'sass-resources-loader'.options: {
            resources: [
                'src/style/tools/index.scss'.// Import mixins and functions files
                'src/style/settings/var.scss'.// Import the global SasS variable file]}}],},Copy the code

Using the vue-CLI generated project, add the configuration to the vue.config.js file. Reference documentation: ‘Pass options to preprocessor Loader’ in vue-CLI official documentation

module.exports = {
    css: {
      loaderOptions: {
        scss: {
            prependData: `@import "@/style/tools/index.scss"; @import "@/style/settings/var.scss"; `}}}},Copy the code

Managing Static Resources

1. Resource module type

Webpack itself does not recognize static resources such as images. In this case, loader is needed. Before Webpack5, there are two commonly used loaders: file-loader and URl-loader

  • file-loader: Can copy used resources (not limited to images) to the built folder according to the configuration item, and can change the corresponding links;
  • url-loader: contains all functions of file-loader and can import files that meet the configuration into Base64 according to the configuration. Importing small-volume images into projects can reduce HTTP requests, which is a common front-end optimization method.

Webpack V5 adds the configuration of resource module types to use resource files without the need to configure additional loaders.

  • asset/resourceSend a single file and export the URL, previously via file-loader
  • asset/inlineExport the data URL of a resource using url-loader
  • asset/sourceExport the source code of a resource, previously implemented through raw-loader
  • assetThe automatic choice between exporting a data URL and sending a separate file is previously achieved by url-loader and configuring resource volume limits.
{
     test: /\.(png|svg|jpg|gif)$/,
     type: 'asset'.parser: {
        dataUrlCondition: {
            maxSize: 8 * 1024}}}Copy the code

2. html-loader

HTML is used inWhen importing static resources such as images, you need to add the HTML-loader configuration. Otherwise, static resource paths will not be processed.

npm i html-loader -D      // Export HTML as a string. You can compress HTML strings.
Copy the code
{
    test: /\.html$/,
    use: ['html-loader']},Copy the code

3. image-webpack-loader

Image-webpack-loader can be used to optimize images. It supports JPG, PNG, GIF and SVG images. This loader cannot embed images. Configure Enforce: ‘pre’ to ensure that this is executed before embedding images

npm i image-webpack-loader -D 
Copy the code
{
   test: /\.(jpe? g|png|gif|svg)$/,
   loader: 'image-webpack-loader'.enforce: 'pre'
}
Copy the code

4. Fonts, rich media

Such resources do not need to be packaged as Base64

{
     test: /\.(eot|woff|ttf|woff2|appcache|mp4|pdf)(\? | $) /,
     type: 'asset/resource'
}
Copy the code

Narrow down the search.

1. oneOf

In the original rule matching, each rule is matched once. OneOf is used to indicate a unique match. If a rule is matched, the match ends, which improves the execution efficiency of loader.

rules: [
    {
        oneOf: [{test: /\.css$/, use: [...] }, {test: /\.scss$/, use: [...] }, {test: /\.html$/, use:[...] },... ] ],},Copy the code

2. alias

Configuring an alias can speed up the search

module.exports = {
    resolve: {
        alias: {
            The '@': path.resolve(__dirname, 'src'),}}},Copy the code

3. extensions

If the extensions are specified, require and import will be matched in sequence, but only the first file will be matched if the same directory has different files of the same name.

module.exports = {
    resolve: {
        extensions: ['.vue'.'.js'.'.json'.'scss'.'css',}}Copy the code

4. modules

Specifies the directory to store third-party dependencies. Default is ‘node_modules’

module.exports = {
    resolve: {
        modules: [
            path.resolve(__dirname, '.. /.. /node_modules'),
            'node_modules']}}Copy the code

Part five: WebPack development environment configuration

Install portfinder

npm i portfinder -D     // Automatically obtain available ports to avoid port occupation
Copy the code
// //webpack.dev.js
const path = require('path');
const { merge } = require('webpack-merge');
const commonWebpackConfig = require('./webpack.common');
const portfinder = require('portfinder');

const devConfig = {
   // WebPack configuration items for the development environment
};

const devWebpackConfig = merge(commonWebpackConfig, devConfig);

module.exports = new Promise((resolve, reject) = > {
    portfinder.getPort({
        port: 1081.// The default port is 1081. If it is occupied, repeat +1 until it finds an available port or stops at stopPort
        stopPort: 65535.// maximum port
    },(err, port) = > {
        if(err) {
            reject(err)
            return
        }

        devWebpackConfig.devServer.port = port
        resolve(devWebpackConfig);
    });
})
Copy the code

The cache

1. cache

Cache the previously packaged content, after configuration will generate a.cash folder, through the file cache, directly cached to the local disk

// //webpack.dev.js
cache: {
    type: 'filesystem'.// The default cache is node_modules/.cache/webpack. You can also customize the configuration using the cacheDirectory option
},
Copy the code

2. babel-loader

Babel-loader has its own cache configuration. Node_modules /. Cache /babel-loader

// //webpack.dev.js
{
    loader: 'babel-loader'.options: {
        cacheDirectory: true,}}Copy the code

3. cache-loader

By using this loader, you can cache the results of other Loaders to the disk. The default path is node_modules/. Cache /cache-loader

npm i cache-loader -D
Copy the code
{
    test: /\.css$/,
    use: [
        'cache-loader'.'style-loader'.'css-loader'],},Copy the code

Part six: WebPack production environment configuration

Extracting CSS separately

In a production environment where CSS files should be exported separately, the mini-CSS-extract-plugin is needed

npm i mini-css-extract-plugin -D   // Extract the CSS to a separate file
Copy the code

When using mini-CSS-extract-plugin, configure loader and plugin respectively. Loader should be placed after CSS-loader to replace style-loader

// webpack.prod.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].css'.chunkFilename: '[name].[contenthash:8].css'})].module: {
        rules: [{test: /\.css$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            publicPath: '.. / '.hmr: false}},'css-loader'}]}};Copy the code

Tree Shaking

Webpack5 has a better Tree Shaking handling mechanism, enabled by default when mode is production or manually configured.

// webpack.prod.js
optimization {
    usedExports: true.minimize: true
    // There are more configurations...
}
Copy the code
// package.json
"sideEffects": [
    "*.css"             // You can also set some files not to Tree Shaking
]
Copy the code

Scope Hoisting

Scope promotion, combining several functions into one function, reducing the temporary execution context generated by each new function execution, reducing overhead. Mode is enabled by default when mode is production.

The compression

JS compressed

If you are using WebPack 5 or above, you do not need to install this plugin. Webpack 5 comes with the latest Terser-webpack-plugin and is used automatically when mode is ‘production’.

npm i terser-webpack-plugin -D
Copy the code
// // webpack.prod.js
const TerserPlugin = require("terser-webpack-plugin");

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

HTML compression

1. The HTML – webpack – plugin minify

The html-webpack-plugin’s minify option is used to set compression of HTML files, and minify is automatically enabled if mode is ‘production’. The html-minifier-terser command is used to compress the configuration. The default configuration is as follows. You can modify the configuration as required according to the html-minifier-terser document:

{
  collapseWhitespace: true.keepClosingSlash: true.removeComments: true.removeRedundantAttributes: true.removeScriptTypeAttributes: true.removeStyleLinkTypeAttributes: true.useShortDoctype: true
}
Copy the code
2. html-minimizer-webpack-plugin

Internally, htML-minifier -terser is also used to compress HTML. Starting with webpack5, plug-ins like the compression class should be configured in the optimization.minimizer array for easy unified management. You can refer to the official documentation for how to use the plug-in.

npm i html-minimizer-webpack-plugin -D
Copy the code
// webpack.prod.js
const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin");

optimization: {
    minimize: true.minimizer: [
      // For webpack@5 you can use the `... ` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
      / / `... `,
      new HtmlMinimizerPlugin(),
    ],
},
Copy the code

CSS compression

Before Webpack5, it was common to use the plug-optimize-css-assets-webpack-plugin to compress CSS code. But in its NPM library, there is a paragraph “For webpack V5 or above please use CSS-minimizer-webpack-plugin instead.” So, The optimization of Webpack can be configured to unlock CSS compression, as documented in CSS-minimizer-webpack-plugin.

npm i css-minimizer-webpack-plugin -D
Copy the code
// webpack.prod.js
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = {
  optimization: {    // Tell WebPack to compress bundles using TerserPlugin or other plugins defined in Optimization.minimizer.
    minimizer: [
      / / `... `, // For webpack@5 you can use the `... ` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
      new CssMinimizerPlugin(),
    ],
  },
};
Copy the code

Break up the code

splitChunks

Before configuring splitChunks, take a look at the concepts of Module, chunk, and bundle

  • module: Resources introduced by import and require statements.
  • chunk: Chunk consists of one or more modules, which are divided according to webpack configuration. For example, splitChunks can be divided into additional chunks.
  • bundle: The final file packed and compressed by chunk is generally one-to-one with chunk, or the common parts of multiple chunks may be combined into a bundle.

Starting with Webpack4, the splitChunks feature for handling common modules is out-of-the-box and the default configuration is as follows:

module.exports = {
    // ...
    optimization: {
        splitChunks: {
            chunks: 'async'./ / "initial" | "all" | "async", async by default
            minSize: 20000.// 20K, when the volume exceeds this, it is separated into the common parts.
            minRemainingSize: 0.// Ensure that the minimum chunk size left after splitting exceeds the limit to avoid zero-size modules.
            minChunks: 1.// The minimum number of chunks that must be shared before splitting.
            maxAsyncRequests: 30.// Maximum number of parallel requests when loading on demand. For example, if import('./page.js') is imported, the maximum number of requests including page.js is limited to 30.
            maxInitialRequests: 30.// Maximum number of parallel requests for entry. The entry file itself counts as a request. The dynamically loaded module in the entry file does not count requests.
            enforceSizeThreshold: 50000.// Volume thresholds and other restrictions that enforce detaching (minRemainingSize, maxAsyncRequests, maxInitialRequests) will be ignored.
            cacheGroups: {
                defaultVendors: {
                    test: /[\\/]node_modules[\\/]/.// If the rule is met, chunk is extracted
                    priority: -10 // Priority. When a module belongs to multiple chunkgroups, the chunkGroup with the highest weight takes precedence
                    reuseExistingChunk: true.// If the chunk contains modules that already exist in another chunk, reference the existing chunk directly without creating another chunk
                },
                default: {
                    minChunks: 2.priority: -20.reuseExistingChunk: true,}}}}};Copy the code

In real projects, bundle analysis tools such as Webpack-bundle-Analyzer can be used to analyze and break down oversized common modules. For example, if the moment package shown in the image below is too large, you can add a configuration to break it out (you can also use the smaller day.js or use the moment-locales-webpack-plugin to reduce the size of the moment).

// webpack.prod.js
optimization: {
    splitChunks: {
        cacheGroups: {
            moment: {
                test: / / \ \ / node_modules / \ \ / _moment @ 2.29.1 @ my moment \ \ / /,
                name: 'moment'.chunks: 'all',},},},},Copy the code

If the HTML-webpack-plugin is used, you need to add chunks configuration to automatically introduce the chunks that are split.

new HtmlWebpackPlugin({
    // ...
    chunks: ['moment'.'main'],}).Copy the code

The last

Well, that’s all for this article, there are many common configurations and new Webpack5 features that are not used, and there is plenty of room for encapsulation and optimization of the options provided. Of course, you can also write your own loader and plugin to solve practical problems you encounter. This article only serves as the study record, plays the role of a cast a brick to lead jade, hoped the content in the article can you help, thank you.