webpack5生产环境打包优化

896 阅读3分钟

正式环境的配置

const path = require('path');
const merge = require('webpack-merge');
const os = require('os');
const HappyPack = require('happypack')

// 用于将 CSS 提取成独立文件的 Webpack 插件,特别适用于生产环境。它的主要作用是将 CSS 从 JavaScript 中分离出来,生成一个或多个独立的 CSS 文件,这样可以提高页面加载性能并减少 JavaScript 文件的大小。
const MiniCssExtractPlugin = require("mini-css-extract-plugin")

// 用于删除构建目录的 Webpack 插件,在每次构建之前清理构建目录,以确保构建的输出是干净的。
const CleanWebpackPlugin = require('clean-webpack-plugin');

// 用于压缩 CSS 文件的 Webpack 插件,在生产环境中使用,以减小 CSS 文件的大小并提高页面加载速度。
const CssMinizerPlugin = require('css-minimizer-webpack-plugin');

// 用于压缩 JavaScript 文件的 Webpack 插件,在生产环境中使用,以减小 JavaScript 文件的大小并提高页面加载速度。
const TerserWbpackPlugin = require('terser-webpack-plugin');

// 浏览器在请资源时不发送用户的身份验证
const HtmlWebpackInjectAttributesPlugin = require('html-webpack-inject-attributes-plugin');

// 多线程 build 配置
const happlypackCommonConfig = {
    debug: false, // 
    // 使用电脑cpu核心数,提高打包速度
    threadPool: HappyPack.ThreadPool({
        size: os.cpus().length
    })
}

// 基类配置
const baseConfig = require("./webpack.base.js");

const webpackProdConfig = merge.smart(baseConfig, {
    // 指定生产环境
    mode: "production",
    output: {
        filename: 'js/[name]_[chunkhash:8].bundle.js',
        path: path.join(process.cwd(), './app/public/dist/prod'),
        publicPath: '/dist/prod',
        crossOriginLoading: 'anonymous'
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, 'happypack/loader?id=css']
            },
            {
                test: /\.js$/,
                // 只对业务代码进行 babel ,加快 webpack 打包速度
                include: path.resolve(process.cwd(), './app/pages'),
                use: ['happypack/loader?id=js']
            },
        ]
    },
    performance: {
        // 打开/关闭提示。此外,当找到提示时,告诉 webpack 抛出一个错误或警告。此属性默认设置为 "warning"。
        hints: false // 不展示警告或错误提示
    },
    plugins: [
        // 每次打包前清除 dist 文件
        new CleanWebpackPlugin(['pubilc/dist'], {
            root: path.resolve(process.cwd(), './app/'),
            exclude: [],
            verbose: true,
            dry: false
        }),
        // 提取 CSS 公共部分,有效利用缓存,(非公共部分用 inline )
        new MiniCssExtractPlugin({
            filename: 'css/[name]_[contenthash:8].bundle.css'
        }),
        // 优化并压缩 CSS 资源
        new CssMinizerPlugin(),
        // 多线程打包 JS ,加快打包速度
        new HappyPack({
            ...happlypackCommonConfig,
            id: 'js',
            use: [{
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env'],
                    plugins: ['@babel/plugin-transform-runtime']
                }
            }]
        }),
        // 多线程打包 CSS ,加快打包速度
        new HappyPack({
            id: 'css',
            loaders: [{
                path: 'css-loader',
                options: {
                    importLoaders: 1
                }
            }]
        }),
        // 浏览器在请资源时不发送用户的身份验证
        new HtmlWebpackInjectAttributesPlugin({
            crossorigin: 'anonymous'
        })
    ],
    optimization: {
        // 使用 TerserWbpackPlugin 的并发和缓存,提前压缩阶段性能
        // 清除console.log 输出
        minimize: true,
        minimizer: [
            new TerserWbpackPlugin({
                cache: true, // 启用缓存来加速构建结构
                parallel: true, // 利用多核 CUP 的优势加速压缩速度
                terserOptions: {
                    compress: {
                        drop_console: true // 去掉console.log
                    }
                }
            })
        ]
    }
})
module.exports = webpackProdConfig;

happypack

HappyPack插件用于实现webapck打包多线程的进行,使用案例

// 用于实现多线程打包
const HappyPack = require('happypack')
// 多线程 build 配置
const happlypackCommonConfig = {
    debug: false, // 
    // 使用电脑cpu核心数,提高打包速度
    threadPool: HappyPack.ThreadPool({
        size: os.cpus().length
    })
}
 // 多线程打包 JS ,加快打包速度
      new HappyPack({
          ...happlypackCommonConfig,
          id: 'js',
            use: [{
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env'],
                    plugins: ['@babel/plugin-transform-runtime']
                }
            }]
        }),
        // 多线程打包 CSS ,加快打包速度
        new HappyPack({
            id: 'css',
            loaders: [{
                path: 'css-loader',
                options: {
                    importLoaders: 1
                }
            }]
        }),

mini-css-extract-plugin

主要用于提取 CSS 公共部分,有效利用缓存,使用案例

const MiniCssExtractPlugin = require("mini-css-extract-plugin")
module: {
        rules: [
            {
                test: /\.css$/,
                 // 使用 MiniCssExtractPlugin的loader
                use: [MiniCssExtractPlugin.loader, 'happypack/loader?id=css']
            }
        ]
    },
    
plugins:[
    new MiniCssExtractPlugin({
        filename: 'css/[name]_[contenthash:8].bundle.css'
    }),
]

clean-webpack-plugin

用于删除构建目录的 Webpack 插件,在每次构建之前清理构建目录,以确保构建的输出是干净的,使用案例

const CleanWebpackPlugin = require('clean-webpack-plugin');
plugins:[
    // 每次打包前清除 dist 文件
        new CleanWebpackPlugin(['pubilc/dist'], {
            root: path.resolve(process.cwd(), './app/'),
            exclude: [],
            verbose: true,
            dry: false
        }),
]

css-minimizer-webpack-plugin

用于压缩 CSS 文件的 Webpack 插件,在生产环境中使用,以减小 CSS 文件的大小并提高页面加载速度,使用案例

const CssMinizerPlugin = require('css-minimizer-webpack-plugin');
plugins:[
    new CssMinizerPlugin()
]

terser-webpack-plugin

用于压缩 JavaScript 文件的 Webpack 插件,在生产环境中使用,以减小 JavaScript 文件的大小并提高页面加载速度,使用案例

const TerserWbpackPlugin = require('terser-webpack-plugin');
    optimization: {
        // 使用 TerserWbpackPlugin 的并发和缓存,提前压缩阶段性能
        // 清除console.log 输出
        minimize: true,
        minimizer: [
            new TerserWbpackPlugin({
                cache: true, // 启用缓存来加速构建结构
                parallel: true, // 利用多核 CUP 的优势加速压缩速度
                terserOptions: {
                    compress: {
                        drop_console: true // 去掉console.log
                    }
                }
            })
        ]
    }