webpack5 study notes

basic use

1. Resource directory:

webpack_code #Project root directory (all instructions must be run in this directory

                |____src #Project source directory

                           |___ js #js file directory

                           |        |__ count.js

                           | |__ am.js

                           |____main.js # Project main file

2. Create a file 

  • count.js
export default function count(x,y) {
    return x-y;
}
  • sum.js
export default function sum(...args) {
    return args.reduce((p, c) => p + c, 0);
}
  • main.js
import count from "./js/count";
import sum from "./js/sum";

console.log(count(2,1));
console.log(sum(1, 2, 3, 4));

3. Download dependencies

Open the terminal and go to the project root directory. Run the following command:

  • Initialize package.json
npm init -y

A basic package.json file is generated at this point.

It should be noted that the name field in package.json cannot be called webpack, otherwise an error will be reported in the next step

  • download dependencies
npm i webpack webpack-cli -D

4. Enable webpack

  • development mode
npx webpack ./src/main.js --mode=development
  • production mode
npx webpack ./src/main.js --mode=production

npx webpack: is used to run locally installed Webpack packages.

./src/main.js : Specify webpack to start packaging from the main.js file. Not only will main.js be packaged, but other dependencies will also be packaged together.

--mode=xxx : specify the mode (environment)

5. Observe the output file

By default, Webpack will package and output the files to the dist directory. Let's check the files in the dist directory.

summary


Webpack itself has relatively few functions and can only process js resources. Once it encounters other resources such as css, it will report an error.

So when we learn Webpack, we mainly learn how to deal with other resources.

basic configuration

Before we start using Webpack, we need to have a certain understanding of Webpack configuration.

5 core concepts


1. entry (entry)

Instruct Webpack which file to start packing

2. output (output)

Instruct Webpack where to output the packaged files, how to name them, etc.

3. loader (loader)

Webpack itself can only handle js, json and other resources. It needs loader for Webpack to parse

4. plugins (plug-ins)

Extending the functionality of Webpack

5. mode (mode)

There are mainly two modes:

  • Development mode: development
  • Production mode: production

Prepare Webpack configuration file


Create a new file in the root directory: webpack.config.js

const path = require("path"); // nodejs核心模块,专门用来处理路径问题

module.exports = {
    // 入口
    entry: './src/main.js', // 相对路径
    // 输出
    output: {
        // 文件的输出路径
        // __dirname nodejs的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, "dist"), // 绝对路径
        // 文件名
        filename: 'main.js',
    },
    // 加载器
    module: {
        rules: [
            // loader的配置
        ]
    },
    // 插件
    plugins: [
        // plugin的配置
    ],
    // 模式
    mode: "development",
    // mode:"production",
}

Introduction to development mode

The development mode, as the name implies, is the mode we use when developing.

In this mode we mainly do two things:

1. Compile the code so that the browser can recognize and run it

When developing, we have style resources, font icons, image resources, html resources, etc., webpack cannot handle these resources by default, so we need to load configuration to compile these resources

2. Code quality inspection, establish code norms

Check some hidden dangers of the code in advance to make the code more robust when running.

Check the code specification and format in advance, agree with the team's coding style, and make the code more elegant and beautiful.

Handling styles and image resources

Learn how to use Webpack to process image resources such as Css, Less, Sass, Scss, Styl and png, jpeg, gif

introduce


Webpack itself cannot recognize style resources, so we need to use Loader to help Webpack parse style resources

When we look for Loader, we should go to the official document to find the corresponding Loader, and then use

If you can't find the official document, you can search and query from the community Github

Webpack Official Loader Documentation

Configuration:

const path = require("path"); // nodejs核心模块,专门用来处理路径问题

module.exports = {
    // 入口
    entry: './src/main.js', // 相对路径
    // 输出
    output: {
        // 所有文件的输出路径
        // __dirname nodejs的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, "dist"), // 绝对路径
        // 入口文件打包输出文件名
        filename: 'main.js',
    },
    // 加载器
    module: {
        rules: [
            // loader的配置
            {
                test: /\.css$/, // 只检测 .css文件
                use: [ // 执行顺序:从右到左(从下到上)
                    "style-loader", // 将js中css通过创建style标签添加html文件中生效
                    "css-loader", // 将css资源编译成 commonjs 的模块到js中
                ],
            },
            {
                test: /\.less$/,
                // loader:'xxx', // 只能使用1个loader
                use: [ // 使用多个loader
                    // compiles Less to CSS
                    'style-loader',
                    'css-loader',
                    'less-loader', // 将less编译成css文件
                ],
            },
            {
                test: /\.s[ac]ss$/,
                use: [
                    // 将 JS 字符串生成为 style 节点
                    'style-loader',
                    // 将 CSS 转化成 CommonJS 模块
                    'css-loader',
                    // 将 Sass 编译成 CSS
                    'sass-loader',
                ],
            },
            {
                test: /\.styl$/,
                use: [
                    "style-loader",
                    "css-loader",
                    "stylus-loader", // 将 Stylus 文件编译为 CSS
                ],
            },
            {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
            }
            /* {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        // 小于10kb 的图片转base64
                        // 优点:减少请求数量  缺点:体积会更大
                        maxSize: 4 * 1024 // 4kb
                    }
                }
            } */
        ],
    },
    // 插件
    plugins: [
        // plugin的配置
    ],
    // 模式
    mode: "development",
    // mode:"production",
}

Modify the name and path of the output resource

const path = require("path"); // nodejs核心模块,专门用来处理路径问题

module.exports = {
    entry: './src/main.js', // 相对路径
    output: {
        // 所有文件的输出路径
        // __dirname nodejs的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, "dist"), // 绝对路径
        // 入口文件打包输出文件名
        filename: 'static/js/main.js',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ["style-loader","css-loader"],
            },
            {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
                generator: {
                    // [hash:10] 代表hash值只取前10位
                    filename: 'static/images/[hash:10][ext][query]'
                }
            }
        ],
    },
    plugins: [],
    mode: "development",
    // mode:"production",
}

Automatically clear the last packaged resource

const path = require("path");

module.exports = {
    entry: './src/main.js',
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: 'static/js/main.js',
        // 自动清空上次打包的内容
        // 原理:在打包前,将path整个目录内容清空,再进行打包
        clean: true,
    },
    module: {
        rules: [
            {}
        ],
    },
    plugins: [],
    mode: "development",
    // mode:"production",
}

Handling Font Icon Resources

1. Download the font icon file

2. Copy the corresponding css file and fonts (ttf|woff, etc.) folder to the src folder (note: the path in the css file needs to be modified accordingly)

3. Import the corresponding css file into the main.js file

4. Introduce font icons in html, remember to modify the path introduced by main.js, which was modified before

 5. Modify the configuration file

const path = require("path");

module.exports = {
    entry: './src/main.js',
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: 'static/js/main.js',
        clean: true,
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ["style-loader","css-loader"],
            },
            {
                test: /\.less$/,
                use: ['style-loader','css-loader','less-loader'],
            },
            {
                test: /\.s[ac]ss$/,
                use: ['style-loader','css-loader','sass-loader'],
            },
            {
                test: /\.styl$/,
                use: ["style-loader","css-loader","stylus-loader"],
            },
            {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
                generator: {
                    filename: 'static/images/[hash:10][ext][query]'
                }
            },
            {
                test: /\.(ttf|woff2?)$/,
                type: 'asset/resource',
                generator: {
                    // 输出名称
                    filename: 'static/media/[hash:10][ext][query]'
                }
            },
        ],
    },
    plugins: [],
    mode: "development",
    // mode:"production",
}

Handle other resources

There may be some other resources in the development, such as audio and video, etc., we have also dealt with them together

1. Configuration

const path = require("path"); 

module.exports = {
    entry: './src/main.js', 
    output: {
        path: path.resolve(__dirname, "dist"), 
        filename: 'static/js/main.js',
        clean: true,
    },
    module: {
        rules: [
            {
                test: /\.css$/, 
                use: [ "style-loader","css-loader"],
            },
            {
                test: /\.less$/,
                use: ['style-loader','css-loader','less-loader'],
            },
            {
                test: /\.s[ac]ss$/,
                use: ['style-loader','css-loader','sass-loader'],
            },
            {
                test: /\.styl$/,
                use: ["style-loader","css-loader","stylus-loader"],
            },
            {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
                generator: {
                    filename: 'static/images/[hash:10][ext][query]'
                }
            },
            {
                // 有其他资源时继续往后添加,就会原封不动输出的
                test: /\.(ttf|woff2?|map3|map4|avi)$/,
                type: 'asset/resource',
                generator: {
                    filename: 'static/media/[hash:10][ext][query]'
                }
            },
        ],
    },
    plugins: [],
    mode: "development",
    // mode:"production",
}

Handle js resources

Some people may ask, isn't the js resource Webpack already processed, why do we still need to process it?

The reason is that Webpack has limited processing of js. It can only compile the ES modular syntax in js, and cannot compile other syntax. As a result, js cannot run in browsers such as IE, so we hope to do some compatibility processing.

During development, the team has strict requirements on the code format. We cannot detect the code format with the naked eye, and need to use professional tools to detect it.

  • For js compatibility processing, we use Babel to complete
  • For code formatting, we use Eslint to complete

Let's complete Eslint first, and after checking that the code format is correct, Babel will do code compatibility processing

Eslint


Composable JavaScript and JSX inspection tool.

The meaning of this sentence is: it is a tool used to detect js and jsx syntax, and can configure various functions

When we use Eslint, the key is to write the Eslint configuration file, which contains various rules rules. When running Eslint in the future, the code will be checked with the written rules.

1. Configuration file

There are many ways to write configuration files:

.eslintrc.* : Create a new file, located in the root directory of the project

  • .eslintrc
  • .eslintrc.js
  • .eslintrc.json
  • The difference is that the configuration format is different

eslintConfig in package.json : No need to create files, Eslint will find and automatically read them based on the original files, so only one of the above configuration files needs to exist

2. Specific configuration

Let's take the .eslintrc.js configuration file as an example:

module.exports = {
    // 解析选项
    parserOptions: {},
    // 具体检查规则
    rules:{},
    // 继承其他规则
    extends:[],
    // ...
    // 其他规则详见:https://eslint.bootcss.com/docs/user-guide/configuring
};

1. parserOptions parser options

parserOptions: {
    ecmaVersion: 6, // ES 语法版本
    sourceType: "module", // ES 模块化
    ecmaFeatures:{ // ES 其他特性
        jsx: ture // 如果是 React 项目,就需要开启 jsx 语法
    }
}

2. rules Specific rules

  • "off" or 0 - turn off the rule
  • "warn" or 1 - enable rule, use warning level errors: warn (does not cause the program to exit)
  • "error" or 2 - enable rule, use error level error: error (when triggered, the program will exit)
rules: {
    semi: "error", // 禁止使用分号
    'array-callback-return': 'warn', // 强制数组方法的回调函数中有 return 语句。否则警告
    'default-case': [
        'warn', // 要求 switch 语句中有 default 分支,否则警告
        { commentPattern: '^no default$' } // 允许在最后注释 no default, 就不会有警告了
    ],
    eqeqeq: [
        'warn', // 强制使用 === 和 !== ,否则警告
        'smart' // https://eslint.bootcss.com/docs/rules/eqeqeq#smart 除了少数情况下不会有警告
    ],
}

For more rules, see: Rules Documentation

3. extends inheritance

It is too strenuous to write rules little by little during development, so there is a better way to inherit existing rules.

The following well-known rules exist:

  • Eslint official rules : eslint:recommended
  • Vue Cli official rules: plugin:vue/essential
  • React Cli official rules: react-app
// 例如在React项目中,我们可以这样写配置
module.exports = {
    extends:["react-app"],
    rules:{
        // 我们的规则会覆盖掉react-app的规则
        // 所以想要修改规则直接改就是了
        eqeqeq:["warn","smart"],
},

3. Use in Webpack

1. Download package

npm i eslint-webpack-plugin eslint -D

2. Modify the webpack.config.js file

  • webpack.config.js
// 把插件添加到你的 webpack 配置
const ESLintPlugin = require('eslint-webpack-plugin');

module.exports = {
  // ...
  // 插件
    plugins: [
        // plugin的配置
        new ESLintPlugin({
            // 检测哪些文件
            context: path.resolve(__dirname, "src")
        })
    ],
  // ...
};

3. Define the Eslint configuration file

  • .eslintrc.js
module.exports = {
    // 继承 Eslint 规则
    extends: ["eslint:recommended"],
    env: {
        node: ture, // 启用node中全局变量
        browser: true, // 启用浏览器中全局变量
    },
    parserOptions: {
        ecmaVersion: 6,
        sourceType: "module",
    },
    rules: {
        "no-var": 2, // 不能使用 var 定义变量
    },
};

4. Modify the js file code

  • main.js
import count from "./js/count";
import sum from "./js/sum";
// 要想 webpack 打包资源,必须引入该资源
import "./css/iconfont.css";
import "./css/index.css";
import "./less/index.less";
import "./sass/index.sass";
import "./sass/index.scss";
import "./stylus/index.styl";

const result = count(2, 1); // 不能用 var 会报错
console.log(result);
// console.log(count(2, 1));
console.log(sum(1, 2, 3, 4));

5. Add .eslintignore file

Since I added the Eslint syntax checking plug-in in VS Code, and we don't need him to check the output js file, which is the dist folder, we need to add a new configuration file.eslintignore file, which contains dist, so that he The js file in the dist folder will be ignored, so that the error of the red wavy line will not be reported

  • .eslintignore
dist

Babel


JavaScript compiler.

It is mainly used to convert code written in ES6 syntax to backward compatible JavaScript syntax so that it can run in current and old versions of browsers or other environments.

1. Configuration file

There are many ways to write configuration files:

babel.config.* : New file, located in the root directory of the project

  • babel.config.js
  • babel.config.json

.babelrc.* : Create a new file, located in the root directory of the project

  • .babelrc
  • .babelrc.js
  • .babelrc.json

babel in  package.json : No need to create files, Babel will find and automatically read them when written on the basis of the original files, so only one of the above configuration files needs to exist

2. Specific configuration

Let's take the babel.config.js configuration file as an example:

module.exports = {
    // 预设
    presets: [],
};

1. presets

Simple understanding: it is a set of Babel plugins that extend Babel's functionality

  • @babel/preset-env : A smart preset that allows you to use the latest JavaScript.
  • @babel/preset-react : A preset for compiling Recat jsx syntax
  • @babel/preset-typescript : A preset for compiling TypeScript syntax

3. Use in Webpack

1. Download package

npm i babel-loader @babel/core @babel/preset-env -D

2. Define the Babel configuration file

  • babel.config.js
module.export = {
    // 智能预设:能够编译ES6语法
    presets: ['@babel/preset-env'],
}

3. Configure the webpack.config.js file

  • webpack.config.js

In the webpack configuration object, you need to add babel-loader to the list of modules, like this:

module: {
  rules: [
    {
      test: /\.m?js$/,
      exclude: /node_modules/, // 排除node_modules中的js文件(这些文件不处理)
      /* use: {
            loader: 'babel-loader',
            options: {
                presets: ['@babel/preset-env']
            }
      } */
      /* loader: 'babel-loader',
      options: {
          presets: ['@babel/preset-env']
      } */
      loader: 'babel-loader',
      // options也可以写在外面,babel.config.js 里面 
    }
  ]
}

Handle Html resources

1. Download package

npm i html-webpack-plugin -D

2. Configuration

webpack.config.js

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

module.exports = {
  entry: 'index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'index_bundle.js',
  },
  plugins: [
        new HtmlWebpackPlugin({
            // 模板:以public/index.html 文件创建新的html文件
            // 新的html文件特点:1.结构和原来一致 2.自动引入打包输出的资源
            template: path.resolve(__dirname, "public/index.html"),
        })
    ],
};

Development Server & Automation

Note: The dist folder will not be automatically generated after the automated development server runs

1. Download package

npm i webpack-dev-server -D

2. Configuration

  • webpack.config.js
const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    // ......
    plugins: [],
    // 开发服务器:不会输出资源,在内存中编译打包的
    devServer: {
        host:"localhost", // 启动服务器域名
        port: "3000", // 启动服务器端口号
        open: true, // 是否自动打开浏览器
    },
    mode:"development",
}

3. Run command

npx webpack serve

Production Mode Introduction

In production mode, after the code is developed, we need to deploy the code and put it online.

In this mode, we mainly optimize the code to make it run better.

Optimization mainly starts from two perspectives:

  1. Optimize code execution performance
  2. Optimize code packaging speed

Production mode preparation

We prepare two configuration files for different configurations

1. File directory

|—— webpack-test (project root directory)

          |—— config (Webpack configuration file directory)
          | |—— webpack.dev.js (development mode configuration file)

          | |—— webpack.prod.js (development mode configuration file)

          |—— node_modules (download package storage directory)

          |—— src (project source code directory, except html, everything else is in src)

          | |——Slightly

          |——public (project html file)

          |         |——index.html

          |—— .eslintrc.js (Eslint configuration file)

          |—— babel.config.js (Babel configuration file)

          |—— package.json (package dependency management configuration file)

2. Modify webpack.dev.js

const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/main.js',
    output: {
        // 所有文件的输出路径
        // 开发模式没有输出
        path: undefined,
        // ......
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ["style-loader","css-loader"],
            },
            {
                test: /\.less$/,
                use: ['style-loader','css-loader','less-loader'],
            },
            // .......
        ],
    },
    plugins: [
        new ESLintPlugin({
            // 检测哪些文件
            context: path.resolve(__dirname, "../src")
        }),
        new HtmlWebpackPlugin({
            // 新的html文件特点:1.结构和原来一致 2.自动引入打包输出的资源
            template: path.resolve(__dirname, "../public/index.html"),
        })
    ],
    devServer: {
        host: "localhost",
        port: "3000",
        open: true,
    },
    mode: "development",
}

 3. Run in development mode

npx webpack serve --config ./config/webpack.dev.js

4. Modify webpack.prod.js

const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/main.js',
    output: {
        // 所有文件的输出路径
        // __dirname nodejs的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, "../dist"), // 绝对路径
        // 入口文件打包输出文件名
        filename: 'static/js/main.js',
        // 自动清空上次打包的内容
        // 原理:在打包前,将path整个目录内容清空,再进行打包
        clean: true,
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ["style-loader","css-loader"],
            },
            {
                test: /\.less$/,
                use: ['style-loader','css-loader','less-loader'],
            },
            // .......
        ],
    },
    plugins: [
        new ESLintPlugin({
            // 检测哪些文件
            context: path.resolve(__dirname, "../src")
        }),
        new HtmlWebpackPlugin({
            // 新的html文件特点:1.结构和原来一致 2.自动引入打包输出的资源
            template: path.resolve(__dirname, "../public/index.html"),
        })
    ],
    mode: "production",
}

 5. Running in production mode

npx webpack --config ./config/webpack.prod.js

Optimize running code

Script configuration in package.json

"scripts": {
        "start": "npm run dev",
        "dev": "webpack serve --config ./config/webpack.dev.js",
        "build": "webpack --config ./config/webpack.prod.js"
    },

The code to run the development mode like this is: npm start

The code to run production mode like this is: npm run build

CSS processing

Extract Css into a separate file

Css files are currently packaged into js files, when the js file is loaded, a style tag will be created to generate styles

In this way, for the website, there will be a splash screen phenomenon, and the user experience is not good

We should be a separate Css file, and the performance of loading through the link tag is better

1. Download package

npm i mini-css-extract-plugin -D

2. Configuration

webpack.prod.js

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
         // 指定文件输出目录
         filename: "static/css/main.css"
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },
};

Css Compatibility Processing

1. Download package

npm i postcss-loader postcss postcss-preset-env -D

2. Configuration

webpack.prod.js

Insert configuration code behind css-loader and before less-loader

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          'style-loader',
          'css-loader',
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [
                  [
                    'postcss-preset-env',
                    {
                      // 其他选项
                    },
                  ],
                ],
              },
            },
          },
        ],
      },
    ],
  },
};

Or use the configuration file of PostCSS itself  :

postcss.config.js

module.exports = {
    // 你可以指定下面提到的所有选项 https://postcss.org/api/#processoptions
    // parser: 'sugarss',
    plugins: [
        // PostCSS 插件
        ['postcss-short', { prefix: 'x' }],
        'postcss-preset-env',
    ],
};

Loader will automatically search for configuration files.

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader', 'postcss-loader'],
      },
    ],
  },
};

Finally, run webpack the way you like

3. Control Compatibility

We can add browserslist to the package.json file to control the compatibility of styles.

{
    // 其他省略
    "browserslist": ["ie >= 8"]
}

To know more about browserslist configuration, see browserslist documentation

In order to test compatibility, the above settings are compatible with browsers ie8 and above.

In actual development, we generally don't consider old browsers, so we can set it like this:

{
    // 其他省略
    " browserslist": ["last 2 version", ">1%", "not dead"]
}

4. Merge configuration

Due to the high rate of code reuse, we can encapsulate functions that handle styles

const path = require("path"); // nodejs核心模块,专门用来处理路径问题
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

// 用来获取处理样式的loader
function getStyleLoader(pre) {
    return [
        MiniCssExtractPlugin.loader, // 将js中css通过创建style标签添加html文件中生效
        "css-loader", // 将css资源编译成 commonjs 的模块到js中
        'postcss-loader',
        pre,
    ].filter(Boolean);

}

module.exports = {
    // 入口
    entry: './src/main.js', // 相对路径
    // 输出
    output: {
        // 所有文件的输出路径
        // __dirname nodejs的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, "../dist"), // 绝对路径
        // 入口文件打包输出文件名
        filename: 'static/js/main.js',
        // 自动清空上次打包的内容
        // 原理:在打包前,将path整个目录内容清空,再进行打包
        clean: true,
    },
    // 加载器
    module: {
        rules: [
            // loader的配置
            {
                test: /\.css$/, // 只检测 .css文件
                use: getStyleLoader(),
            },
            {
                test: /\.less$/,
                // loader:'xxx', // 只能使用1个loader
                use: getStyleLoader('less-loader'),
            },
            {
                test: /\.s[ac]ss$/,
                use: getStyleLoader('sass-loader'),
            },
            {
                test: /\.styl$/,
                use: getStyleLoader('stylus-loader'),
            },
            {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
                generator: {
                    // [hash:10] 代表hash值只取前10位
                    filename: 'static/images/[hash:10][ext][query]'
                }
            },
            /* {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        // 小于10kb 的图片转base64
                        // 优点:减少请求数量  缺点:体积会更大
                        maxSize: 4 * 1024 // 4kb
                    }
                }
            } */
            {
                test: /\.(ttf|woff2?|map3|map4|avi)$/,
                type: 'asset/resource',
                generator: {
                    // 输出名称
                    filename: 'static/media/[hash:10][ext][query]'
                }
            },
            {
                test: /\.m?js$/,
                exclude: /node_modules/, // 排除node_modules中的js文件(这些文件不处理)
                /* use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                } */
                /* loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env']
                } */
                loader: 'babel-loader',
                // options也可以写在外面
            },
        ],
    },
    // 插件
    plugins: [
        // plugin的配置
        new ESLintPlugin({
            // 检测哪些文件
            context: path.resolve(__dirname, "../src")
        }),
        new HtmlWebpackPlugin({
            // 模板:以public/index.html 文件创建新的html文件
            // 新的html文件特点:1.结构和原来一致 2.自动引入打包输出的资源
            template: path.resolve(__dirname, "../public/index.html"),
        }),
        new MiniCssExtractPlugin({
            // 指定文件输出目录
            filename: "static/css/main.css"
        }),
    ],
    // 模式
    // mode: "development",
    mode: "production",
}

 Css compression

1. Download package

npm i css-minimizer-webpack-plugin -D

2. Configuration

  • webpack.prod.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /.s?css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
      },
    ],
  },
  optimization: {
    minimizer: [
      // 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
      // `...`,
      new CssMinimizerPlugin(),
    ],
  },
  plugins: [new MiniCssExtractPlugin()],
};

html compression

The default production mode is already enabled: html compression and js compression

No additional configuration required

Guess you like

Origin blog.csdn.net/DIUDIUjiang/article/details/127388827