webpack生产环境的基本配置

102 阅读11分钟

webpack生产环境的基本配置

目前存在的问题

  1. css通过js动态生成,会出现闪屏现象
  2. 代码没有压缩
  3. 浏览器兼容性问题

提取css成单独的文件

我们想提取css  成一个文件。显然,不再需要 style-loader 将样式代码塞进 <style></style>标签了。需要的是另外一个 loader 或 plugin ,用于生成一个单独的文件,并将样式代码塞进去。

安装依赖

npm i  mini-css-extract-plugin -D
​
    # 或者
​
npm install --save -dev mini-css-extract-plugin 

完整配置 Webpack.config.js

// webpack.config.js
​
​
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
​
// webpack配置
module.exports = {
 
    // 入口文件
  entry: "./src/index.js",
​
  // 输出
  output: {
    filename: "[name].js",
    path: path.resolve(__dirname, "dist"),
    
    // 自定义资源文件名
    assetModuleFilename: "images/[hash:10]  [ext][query]",
    
    // 在生成文件之前清空 output 目录
    clean: true,
  },
​
  // 开发服务器配置
  devServer: {
    // 从目录提供静态文件
    static: {
      directory: path.join(__dirname, "public"),
      publicPath: "/",
    },
​
    // 启动后打开浏览器
    open: true,
​
    // 监听请求的端口号
    port: 8080,
  },
​
  // loader配置
  module: {
    rules: [
        
      // 处理css文件
      {
        test: /.css$/,
        use: [
          // 'style-loader', 
          // 创建 style 标签,将 'css-loader' 整合到 js 中的样式放到 style 标签中
          
           //这个loader取代style-loader。作用:提取js中的css成单独文件
           MiniCssExtractPlugin.loader,  // 作用:提取js 中的 css 成单独文件
          'css-loader' // 将css文件整合到js中
        ]
      },
        
      // 处理less文件
      {
        test: /.less$/i,
        use: [
          // "style-loader",
          MiniCssExtractPlugin.loader,
          "css-loader",
          "less-loader",
        ],
      },
        
      // 处理资源文件
      {
        test: /.(png|svg|jpg|jpeg|gif)$/i,
        loder: 'url-loader',
        options: {
            limit: 8 * 1024,
            name: '[hash:10].[ext]',
                    
            // html-loader 和 url-loader 同时使用会冲突
            // 解决: 关闭 ES6 模块化, 开启 Common JS
            esModule: false,
                    
           // 打包后 存放文件的文件夹
            outputPath: 'images'
        }
      },
        
      // 处理html文件,加载其中的图片
      {
        test: /.html$/i,
        loader: "html-loader",
      },
        
      //  webpack4 写法 -- 处理字体文件 
      {
        test: /.(woff|woff2|eot|ttf|otf)$/,
        use: ["file-loader"],
      },
        
      // webpack5 写法 --处理字体文件 
      /**  
      * {
      *     test: /.(woff|woff2|eot|ttf|otf)$/i,
      *     type: "asset/resource",
      * }
      */
    ],
  },
​
  // 插件配置
  plugins: [
    // 复制一份HTML文件,并自动引入打包资源(js/css)
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
      
    new MiniCssExtractPlugin({
      
      // 对输出的css文件进行重命名
      filename: "[name].css",
    }),
  ],
​
  // 模式
  mode: "development",
  // mode: 'production',
};

css兼容性处理

需要下载两个包: postcss-loader、 postcss-preset-env

  •  postcss-loader: 根据node环境变量生成对应环境的兼容性代码;

    • 设置环境变量: process.env.NODE_ENV = 'development';
    • 如果不手动设置 node 环境变量,默认为  "production" 。
  •  postcss-preset-env: 帮助 postcss-loader 找到  package.json 中browserslist  的配置

安装依赖

npm i postcss-loder postcss-preset-env —D
​
    # 或者
​
npm install --save -dev postcss-loader postcss-preset-env 

css文件的打包流程:

1. 先用 css-loader 将样式加载到 js 中;再用 MiniCssExtractPlugin.loader 将样式打包进单独的文件。 2. 进行兼容性处理的话,我们想一下,相对简单的处理顺序可能有两种:在 css-loader 前或 MiniCssExtractPlugin.loader后

package.json

配置字段 browserslist
  {
  "name": "webpack-study",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  
   // postcss-loade 插件配置 browserlist
   "browserslist": {
    
    // 开发环境 --> 设置Node环境变量:process.NODE_ENV = development
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    
    // 生产环境: 默认是生产环境 
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  },
}

webpack配置

webpack4
// webpack配置
const { resolve } = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
​
// 配置nodeJS的环境变量
process.env.NODE_ENV = 'development';
​
module.exports = {
    // 入口文件
    entry: './src/index.js',
​
    // 输出
    output: {
        // 输出文件名
        filename: 'bundle.js',
        
        // 输出路径 __dirname node.js变量,当前文件的目录绝对路径
        path: path.resolve(__dirname, 'dist'),
        
        // 自定义资源文件名
        assetModuleFilename: 'images/[hash:10][ext][query]',
    },
    
  // Loader 配置
  module: {
    rules: [
      {
        test: /.css$/i,
        use: [
           
          // 创建style标签,将样式放入style标签中
          // "style-loader",
          // 提取js中的css成单独文件  
            
          MiniCssExtractPlugin.loader,
          
           // 将css文件整合到js文件中
          'css-loader',
            
          {
            // 需要配置 browserlist,配合NODE_ENV使用,通过配置加载指定的 CSS 兼容性                样式
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                ident: 'post-css',
                
                // 写法一
                plugins: [
                  'postcss-preset-env'
                ]
                
               // 写法二
               plugins: ()=>[
                    // postcss 的插件
                    require('postcss-preset-env')()
                ]
              }
            }
          }
        ]
      }
    ]
  },
  
  // plugin 插件配置
  plugins: [
    // 复制一份HTML文件,并自动引入打包资源(js/css)
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
      
    new MiniCssExtractPlugin({
      
      // 对输出的css文件重命名
      filename: "[name].css",
    }),
  ],
  
  // 模式    
  mode: 'development'
}
​
Webpack 5
// webpack.config.jsconst path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
​
​
// 配置nodeJS的环境变量
process.env.NODE_ENV = 'development';
​
// webpack配置
module.exports = {
 // 入口文件
    entry: './src/index.js',
​
    // 输出
    output: {
        // 输出文件名
        filename: 'bundle.js',
        
        // 输出路径 __dirname node.js变量,当前文件的目录绝对路径
        path: path.resolve(__dirname, 'dist'),
        
        // 自定义资源文件名
        assetModuleFilename: 'images/[hash:10][ext][query]',
    
        // 在生成文件之前清空 output 目录
        clean: true,
  },
​
  // 开发服务器配置
  devServer: {
    // 从目录提供静态文件
    static: {
      directory: path.join(__dirname, "public"),
      publicPath: "/",
    },
​
    // 启动后打开浏览器
    open: true,
​
    // 监听请求的端口号
    port: 8080,
  },
​
  // loader配置
  module: {
    rules: [
      // 处理css文件
      {
        test: /.css$/i,
        use: [
          
          // 创建style标签,将样式放入style标签中
          // "style-loader",
          // 提取js中的css成单独文件
          MiniCssExtractPlugin.loader,
            
          // 将css文件整合到js文件中
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  [
                    // postcss-preset-env 帮助postcss找到                                       package.json中`browserslist`里边的配置
                    "postcss-preset-env",
                  ],
                ],
              },
            },
          }, 
        ],
      },
      // 处理less文件
      {
        test: /.less$/i,
        use: [
          // "style-loader",
          MiniCssExtractPlugin.loader,
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  [
                    "postcss-preset-env",
                  ],
                ],
              },
            },
          }, 
          "less-loader",
        ],
      },
      // 处理资源文件
      {
        test: /.(png|svg|jpg|jpeg|gif)$/i,
        type: "asset",
      },
      // 处理html文件,加载其中的图片
      {
        test: /.html$/i,
        loader: "html-loader",
      },
      // 处理字体文件
      {
        test: /.(woff|woff2|eot|ttf|otf)$/i,
        type: "asset/resource",
      },
    ],
  },
​
  // 插件配置
  plugins: [
    // 复制一份HTML文件,并自动引入打包资源(js/css)
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
      
    // 对输出的css文件重命名
    new MiniCssExtractPlugin({
      filename: "[name].css",
    }),
  ],
​
  // 模式
  mode: "development",
  // mode: 'production',
};

压缩css

webpack4使用 optimize-css-assets-webpack-plugin:  github.com/NMFR/optimi…

webpack5使用 css-minimizer-webpack-plugin: webpack.docschina.org/plugins/css…

安装依赖

npm install css-minimizer-webpack-plugin --save-dev

Webpack 配置

webpack4
// webpack.config.jsconst { resolve } = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const MiniCSSExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
​
// 配置node的环境变量 - css兼容性处理时使用
// process.env.NODE_ENV = 'development';module.exports = {
  // 入口文件
    entry: './src/index.js',
​
    // 输出
    output: {
        // 输出文件名
        filename: 'bundle.js',
        
        // 输出路径 __dirname node.js变量,当前文件的目录绝对路径
        path: path.resolve(__dirname, 'dist'),
        
        // 自定义资源文件名
        assetModuleFilename: 'images/[hash:10][ext][query]',
    
        // 在生成文件之前清空 output 目录
        clean: true,
  },
 
  // loader配置
  module: {
    rules: [
      {
        test: /.css$/,
        use: [
          // 创建style标签,将样式放入style标签中
          // "style-loader",
          // 提取js中的css成单独文件
          MiniCssExtractPlugin.loader,
            
          // 将css文件整合到js文件中
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  [
                    // postcss-preset-env 帮助postcss找到                                       package.json中`browserslist`里边的配置
                    "postcss-preset-env",
                  ],
                ],
              },
            },
          }, 
        ]
      }
    ]
  },
    
​
  // plugin 插件配置
  plugins: [
    // 复制一份HTML文件,并自动引入打包资源(js/css)
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
    
    // 对输出的css文件重命名
    new MiniCssExtractPlugin({
      filename: "[name].css",
    }),
​
    // 压缩css
    new OptimizeCSSAssetsWebpackPlugin()
  ],
  
  // 模式
  mode: 'development'
}
​
​
webpack5
// webpack.config.jsconst path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
​
​
// webpack配置
module.exports = {
    
    // 入口文件
    entry: './src/index.js',
​
    // 输出
    output: {
        // 输出文件名
        filename: 'bundle.js',
        
        // 输出路径 __dirname node.js变量,当前文件的目录绝对路径
        path: path.resolve(__dirname, 'dist'),
        
        // 自定义资源文件名
        assetModuleFilename: 'images/[hash:10][ext][query]',
    
        // 在生成文件之前清空 output 目录
        clean: true,
  },
 
​
  // 开发服务器配置
  devServer: {
    // 从目录提供静态文件
    static: {
      directory: path.join(__dirname, "public"),
      publicPath: "/",
    },
​
    // 启动后打开浏览器
    open: true,
​
    // 监听请求的端口号
    port: 8080,
  },
​
  // loader配置
  module: {
    rules: [
      // 处理css文件
      {
        test: /.css$/i,
        use: [
          // 创建style标签,将样式放入style标签中
          // "style-loader",
          // 提取js中的css成单独文件
          MiniCssExtractPlugin.loader,
          // 将css文件整合到js文件中
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [["postcss-preset-env"]],
              },
            },
          },
        ],
      },
      // 处理less文件
      {
        test: /.less$/i,
        use: [
          // "style-loader",
          MiniCssExtractPlugin.loader,
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [["postcss-preset-env"]],
              },
            },
          },
          "less-loader",
        ],
      },
      // 处理资源文件
      {
        test: /.(png|svg|jpg|jpeg|gif)$/i,
        type: "asset",
      },
      // 处理html文件,加载其中的图片
      {
        test: /.html$/i,
        loader: "html-loader",
      },
      // 处理字体文件
      {
        test: /.(woff|woff2|eot|ttf|otf)$/i,
        type: "asset/resource",
      },
    ],
  },
​
  // 插件配置
  plugins: [
    // 复制一份HTML文件,并自动引入打包资源(js/css)
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
    
    //对输出的css文件重命名
    new MiniCssExtractPlugin({
      filename: "[name].css",
    }),
  ],
​
  optimization: {
    // 开发环境下启用 CSS 优化
    minimize: true,
    minimizer: [
      // 使用 cssnano 优化和压缩 CSS
      new CssMinimizerPlugin(),
    ],
  },
​
  // 模式
  mode: "development",
  // mode: 'production',
};

js语法检查eslint

需要下载:

  • eslint-loadereslint: eslint-loader 是基于 eslint的(可以类比理解为:jsnodejs 环境的关系);

    • 可以在 package.json 中增加  eslintConfig 字段,配置 eslint 。比如可以在 eslintConfig 中设置检查规则:"eslintConfig": { "extends": "airbnb-base" }
  • eslint-config-airbnb-baseeslint-plugin-import: 因本文会设置  airbnb-base 的检查规则来进行语法检查,而到 eslint-config-airbnb-base 官网可以查到还需下载  eslint-plugin-import

ESLint:

Airbnb:

注意

1. 只检查自己写的源代码, 第三方的库不用检查的 2. 设置检查的规则: package.json 中 EslintConfig 中设置 Airbnb 规则 3. 一定要排除 node_modules , 否则会对 node_modules 进行检查

安装依赖

npm i eslint eslint-config-airbnb-base eslint-plugin-import -D
​
    # 或者
    
npm install --save -dev eslint-loader eslinteslint-config-airbnb-base eslint-plugin-import

设置 package.json 检查规则

在  package.json 中配置字段 eslintConfig

{
  "name": "webpack-study",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
    
  // 配置eslintConfig
  "eslintConfig": {
    "extends": "airbnb-base",
    "env": {
      "browser": true
    }
  }
}

webpack配置

webpack4配置

安装依赖

cnpm i eslint eslint-loader -D

webpack.config.js

// webpack.config.jsconst { resolve } = require('path');
// const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
// webpack配置
module.exports = {
    
    // 入口文件
    entry: './src/index.js',
​
    // 输出
    output: {
        // 输出文件名
        filename: 'bundle.js',
        
        // 输出路径 __dirname node.js变量,当前文件的目录绝对路径
        path: path.resolve(__dirname, 'dist'),
        
        // 自定义资源文件名
        assetModuleFilename: 'images/[hash:10][ext][query]',
    
        // 在生成文件之前清空 output 目录
        clean: true,
  },
 
​
  // 开发服务器配置
  devServer: {
    // 从目录提供静态文件
    static: {
      directory: path.join(__dirname, "public"),
      publicPath: "/",
    },
​
    // 启动后打开浏览器
    open: true,
​
    // 监听请求的端口号
    port: 8080,
  },
​
  // loader配置
  module: {
    rules: [
        
      // 处理css文件
      {
        test: /.css$/i,
        use: [
          // 创建style标签,将样式放入style标签中
          // "style-loader",
          // 提取js中的css成单独文件
          MiniCssExtractPlugin.loader,
          // 将css文件整合到js文件中
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [["postcss-preset-env"]],
              },
            },
          },
        ],
      },
        
      // 处理less文件
      {
        test: /.less$/i,
        use: [
          // "style-loader",
          MiniCssExtractPlugin.loader,
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [["postcss-preset-env"]],
              },
            },
          },
          "less-loader",
        ],
      },
        
      // 处理资源文件
      {
        test: /.(png|svg|jpg|jpeg|gif)$/i,
        type: "asset",
      },
        
      // 处理html文件,加载其中的图片
      {
        test: /.html$/i,
        loader: "html-loader",
      },
        
      // 处理字体文件
      {
        test: /.(woff|woff2|eot|ttf|otf)$/i,
        type: "asset/resource",
      },
      
      /* 语法检查: eslint-loader eslint
         注意:只检查自己写的源代码,第三方的库是不用检查的
         
         设置检测规则:
            package.json 中 eslintConfig 中设置
            "eslintConfig": {
                "extends": "airbnb-base"
            }
            
            airbnb --> eslint-config-airbnb-base eslint-plugin-                     import eslint
      */ 
        
        {
            test:/.js$/,
            
            // 一定要排除 node_modules, 否则会对 node_modules 进行检查
            exclude: /node_modules/,
            loder:'eslint-loader',
            options: {
               // 自动修复 eslint 的错误
               fix: true
            }
        }
    ],
  },
​
  // 插件配置
  plugins: [
    // 复制一份HTML文件,并自动引入打包资源(js/css)
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
    
    // 对输出的css文件重命名
    new MiniCssExtractPlugin({
      filename: "[name].css",
    }),
​
    // 压缩css
    new OptimizeCSSAssetsWebpackPlugin()
  ],
​
​
  // 模式
  mode: "development",
  // mode: 'production',
};
​
webpack5

安装依赖

npm install eslint eslint-webpack-plugin --save-dev

eslint-webpack-plugin:

webpack.config.js

// webpack.config.js
const ESLintPlugin = require("eslint-webpack-plugin");

// webpack配置
module.exports = {

  // 插件配置
  plugins: [
    // 使用eslint对代码检查
    new ESLintPlugin({
      // 自动修复 eslint 的错误
      fix: true,
    }),
  ],
};

js兼容性处理

什么是JS兼容性处理?

其实就是把 ES6 及以上(后边简写为 ES6+ )新增的语法、API 处理成  ES5 及以下的版本,解决某些浏览器(ie)上的兼容性报错问题。

Babel简介:

Babel  是一个工具链,主要用于在当前和旧的浏览器或环境中,将 ES6+ 代码转换为 JavaScript 向后兼容版本的代码。

polyfill是啥?

不知道大家之前有没有过这种疑问:只知道Babel是处理 ES6+兼容的,polyfill分别是干嘛的? 其实,ES6+语法和新增的 API 需要分开进行处理,polyfill是针对新增 API 的~(比如:箭头函数是新增语法,Promise是新增的API)

Core-js

过去我们使用  babel 对  js 代码进行了兼容性处理,其中使用 @babel/preset-env 智能预设来处理兼容性问题。它能将 ES6 的一些语法进行编译转换,比如箭头函数、点点点运算符等。但是如果是 async 函数、 promise 对象、数组的一些方法(includes)等,它没办法处理。所以此时我们  js 代码仍然存在兼容性问题,一旦遇到低版本浏览器会直接报错。所以我们想要将 js 兼容性问题彻底解决。

 core-js 是专门用来做  ES6  以及以上  API 的  polyfill 。 polyfill 翻译过来叫做垫片/补丁。就是用社区上提供的一段代码,让我们在不兼容某些新特性的浏览器上,使用该新特性。

polyfill 和 core - js 区别

 Polyfill  是一段代码,它为旧版浏览器提供了新特性的实现。这样,开发者就可以在代码中使用新的 JavaScript  特性,而不需要担心旧版浏览器的兼容性问题。

  Core-js则是一个提供了许多现代 JavaScript  特性的库。它包含了大量的 polyfill,可以在不同的浏览器环境中提供一致的 JavaScript API。通过使用  core-js ,开发者可以轻松地在现代和旧版浏览器上实现相同的 JavaScript功能。

处理方案:

  • 1、 @babel/preset-env 基本 js 兼容性处理

    • 问题:只能转换基本 js 语法。如,不能转换高级语法Promise(IE不支持)
  • 2、 @babel/polyfill 全部 js 兼容性处理

    • 问题:将所有兼容性代码全部引入,体积太大
  • 3、core-js 按需加载:只加载需要处理兼容性的语法

步骤一: @babel/preset-env
安装依赖
npm i babel-loader @babel/core @babel/preset-env -D
​
npm install --save-dev babel-loader @babel/core@babel/preset-env@babel/polyfill core-js
配置webpack.config.js
// webpack.config.jsmodule.exports = {
    // Loader 配置
    module: {
      rules: [
          {
            // js兼容性处理
            test: /.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
                // 预设,提示babel怎么样做兼容性处理
                // 基本的兼容性处理,
                presets: ['@babel/preset-env']
            }
        }
    ]
  }
}
步骤二: @babel/polyfill
安装依赖
npm i @babel/polyfill -S
使用方式
// 直接引入即可
import '@babel/polyfill';
步骤三: @core-js
安装依赖
npm i core-js -D
配置webpack.config.js
// webpack.config.js
// 结合 步骤一 和 步骤三 就可以完成 JS 的兼容性处理module.exports = {
  
    // Loader 配置
    module: {
      rules: [
          {
            // js兼容性处理
            test: /.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
                // 预设,提示babel怎么样做兼容性处理
                // 基本的兼容性处理,
                presets: [[
                '@babel/preset-env',
                {
                  /** https://babeljs.io/docs/en/babel-preset-                                env #usebuiltins
                     
                      useBuiltIns:配置 @babel/preset-env 如何处理                               polyf 取“usage”,“entry”,“false” 之一,默认                                为 “false”
                      
                      - 当使用 usage 或 entry 选项时                                               @babel/preset-env 将添加对 core-js 模块的直                                 接引用,类似 import(或require)。这意味着                                    core-js 将相对于文件本身进行解析,并且按需入。
                    */
​
                    
                // 按需加载
                useBuiltIns: 'usage',
                    
                // 指定core-js版本
                corejs: {
                    version: 3
                },
                    
                // 指定兼容性到哪个版本浏览器
                targets: {
                    chrome: '60',
                    firefox: '60',
                    ie: '9',
                    safari: '10',
                    edge: '17'
                 }
​
                }
              ]
            }
        }
    ]
  }
}

压缩html和js

压缩js

非常简单,只需要把 mode 设置为 “production”

原因:

“production” mode 下,webpack 会自动启用 TerserWebpackPlugin/UglifyJsPlugin 来压缩。

压缩HTML文件

HTML 文件不像 CSS 和 JS,不需要做兼容性处理。

webpack 配置

Webpack4
// webpack.config.js

// 生产环境下会自动压缩js代码
mode: 'production'

// 生产环境默认压缩html
new HtmlWebpackPlugin({
    cache: true,
        minify: isProdution? {
            // 移除注释
            removeComments: true,
            // 移除属性
            removeEmptyAttributes: true,
            // 移除默认属性
            removeRedundantAttributes: true,
            // 折叠空白字符
            collapseWhitespace: true,
            // 压缩内联的CSS
            minifyCSS: true,
            // 压缩JavaScript
            minifyJS: {
                mangle: {
                    toplevel: true
                }
            }
        }: false
}),
webpack5

安装依赖

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

webpack.config.js

const TerserPlugin = require("terser-webpack-plugin");module.exports = {
  optimization: {
    minimize: true,
    minimizer: [
      // 使用 terser 优化和压缩 JS
      new TerserPlugin()
    ],
  },
};

完整的 Webpack.config.js 配置

// webpack.config.jsconst path = require("path");
​
// Html 插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
​
// 抽取成单独的 Css 文件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
​
// 压缩Css文件
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
​
​
​
process.env.NODE_ENV = 'production';
​
// css 公共loader
const commonCssLoaders = [
  // "style-loader", // 直接将 CSS 放到 Style 标签里
  MiniCssExtractPlugin.loader,
  "css-loader",
  {
    loader: "postcss-loader",
    options: {
      postcssOptions: {
        ident: 'post-css',
        plugins: [
          [
            // 配合package.json browserlist使用
            "postcss-preset-env", 
          ],
        ],
      },
    },
  },
];
​
// webpack配置
module.exports = {
    // 入口文件
    entry: './src/index.js',
​
    // 输出
    output: {
        // 输出文件名
        filename: 'bundle.js',
        
        // 输出路径 __dirname node.js变量,当前文件的目录绝对路径
        path: path.resolve(__dirname, 'dist'),
        
        // 自定义资源文件名
        assetModuleFilename: 'images/[hash:10][ext][query]',
    
        // 在生成文件之前清空 output 目录
        clean: true,
  },
​
  // 开发服务器配置
  devServer: {
    // 从目录提供静态文件
    static: {
      directory: path.join(__dirname, "public"),
      publicPath: "/",
    },
​
    // 启动后打开浏览器
    open: true,
​
    // 监听请求的端口号
    port: 8080,
  },
​
  // loader配置
  module: {
    rules: [
        
      // 处理css文件
      {
        test: /.css$/i,
        use: [...commonCssLoader],
      },
        
      // 处理less文件
      {
        test: /.less$/i,
        use: [...commonCssLoaders, "less-loader"],
      },
        
        
      // eslint-loader JS 语法检验 
      /**
       * 注意:正常来讲,一个文件只能由一个loader处理。
       * 当一个文件要被多个loader处理,需要指定loader执行的先后顺序。
       * 这里:应先执行eslint-loader,再执行babel-loader
       */
      {
        // 需要在package.json中配置eslintConfig
        test: /.js$/,
        exclude: /node_modules/,
        enforce: 'pre', // 优先执行
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
        
      // js兼容性处理
      {
        test: /.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            // 预设,提示babel怎么样做兼容性处理
            // 基本的兼容性处理,
            presets: [
              [
                "@babel/preset-env",
                {
                  // 按需加载
                  useBuiltIns: "usage",
                  // 指定core-js版本
                  corejs: {
                    version: 3,
                  },
                  // 指定兼容性到哪个版本浏览器
                  targets: {
                    chrome: "60",
                    firefox: "60",
                    ie: "9",
                    safari: "10",
                    edge: "17",
                  },
                },
              ],
            ],
          },
        },
      },
        
      // 处理资源文件
      {
        test: /.(png|svg|jpg|jpeg|gif)$/i,
        loader: "url-loader",
        options: {
            limit: 8 * 1024,
            name: '[hash:10].[ext]',
            
            // 输出路径
            outputPath: 'imgs',
            exModule: false
        }
      },
        
      // 处理html文件,加载其中的图片
      {
        test: /.html$/i,
        loader: "html-loader",
      },
        
      // 处理字体文件
      {
        test: /.(woff|woff2|eot|ttf|otf)$/i,
        type: "file-loder",
      },
      
      // 处理其他资源
      {
        test: /.(js|css|less|sa[c]ss|html|jpg|png|gif)$/i,
        type: "file-loder",
        options: {
            outputPath: 'media'
        },
    ],
  },
​
  // 插件配置
  plugins: [
    // 复制一份HTML文件,并自动引入打包资源(js/css)
    new HtmlWebpackPlugin({
      template: "./src/index.html",
        
        // 压缩 Html 文件
        minify: {
            // 移除空格
            collapseWhitespace: true,
        
            // 移除注释
            removeComments: true,
        }
    }),
        
    // 对输出的css文件重命名
    new MiniCssExtractPlugin({
      filename: "[name].css",
    }),
      
    // 压缩 Css文件
    new OptimizeCssAssetsWebpackPlugin();
      
  ],
​
  // 模式
  // mode: "development",
  mode: "production",
};
​

配置 package.json

{
  "scripts": {
    "dev": "webpack serve",
    "build": "webpack"
  },
  "devDependencies": {
    "@babel/core": "^7.18.0",
    "@babel/preset-env": "^7.18.0",
    "babel-loader": "^8.2.5",
    "core-js": "^3.22.5",
    "css-loader": "^6.7.1",
    "css-minimizer-webpack-plugin": "^4.0.0",
    "eslint": "^8.15.0",
    "eslint-config-airbnb-base": "^15.0.0",
    "eslint-plugin-import": "^2.26.0",
    "eslint-webpack-plugin": "^3.1.1",
    "html-loader": "^3.1.0",
    "html-webpack-plugin": "^5.5.0",
    "less": "^4.1.2",
    "less-loader": "^11.0.0",
    "mini-css-extract-plugin": "^2.6.0",
    "postcss": "^8.4.14",
    "postcss-loader": "^7.0.0",
    "postcss-preset-env": "^7.6.0",
    "style-loader": "^3.3.1",
    "terser-webpack-plugin": "^5.3.1",
    "webpack": "^5.72.1",
    "webpack-cli": "^4.9.2",
    "webpack-dev-server": "^4.9.0"
  },
  "dependencies": {
    "@babel/polyfill": "^7.12.1"
  },
  "browserslist": {
    "development": [
      "last 1 version"
    ],
    "production": [
      "last 1 version",
      "> 1%",
      "ie 10"
    ]
  },
  "eslintConfig": {
    "extends": "airbnb-base"
  }
}