美文网首页
665. 【前端】解决 webpack5 热更新时间太长的问题

665. 【前端】解决 webpack5 热更新时间太长的问题

作者: 七镜 | 来源:发表于2023-05-09 15:42 被阅读0次

    近来在写前端代码的时候,发现每次更改并保存代码之后,浏览器得傻愣好久才会更新出我的最新代码,本来准备忍忍的。但最近对代码的改动比较频繁,忍不了半分钟刷新浏览器的体验了。

    先说下解决问题时踩的坑:刚开始以为是热更新没配置对,反复调试发现和热更新没啥关系。

    重点来了,回想了下webpack.config.js近期的改动,想起来前阵子新增过压缩的功能…… ok,问题找着了:检查webpack.config.js发现不管是开发环境,还是生产环境,都启用了压缩(这是不正确的)

    修改webpack.config.js文件如下:

    ...
    const isProduction = process.env.NODE_ENV === "production"
        ...
        module.exports = {
            ...
            optimization: isProduction:{
            ...
            }:{}
        ...
    }
    ...
    

    完整的webpack.config.js[2023-05-10更新]如下:

    const path = require("path")
    const webpack = require("webpack")
    const HtmlWebpackPlugin = require('html-webpack-plugin') // 生成html入口文件
    const {CleanWebpackPlugin} = require('clean-webpack-plugin') // 编译文件时,清理 build/dist 目录,再生成新的
    
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
    
    
    const isProduction = process.env.NODE_ENV === "production"
    const isDevelopment = process.env.NODE_ENV === "development"
    console.log("print env: ", isProduction)
    
    module.exports = {
        entry: {
            app: path.resolve(__dirname, "src/index.tsx"),
        },
        mode: "development",
        module: {
            rules: [
                {
                    test: /\.(js|jsx|ts|tsx)$/,
                    exclude: /node_modules/,
                    use: [
                        {
                            loader: "babel-loader",
                            options: {
                                presets: [
                                    [
                                        "@babel/preset-env",
                                        // 配置信息
                                        {
                                            targets: {
                                                "chrome": "58",
                                                "ie": "11",
                                            },
                                            // 指定 corejs 的版本
                                            "corejs": "3",
                                            // 使用 corejs 的方式 "usage" 表示按需加载
                                            "useBuiltIns": "usage"
                                        }
                                    ],
                                    [
                                        "@babel/preset-typescript",
                                    ],
                                    [
                                        "@babel/preset-react",
                                        {}
                                    ]
                                ]
                            }
                        },
                        {
                            loader: "ts-loader" // 1. 先加载ts
                        }
                    ],
                },
                {
                    test: /\.(css|scss)$/,
                    use: [
    
                        {
                            loader: process.env.NODE_ENV === "production"
                                ? MiniCssExtractPlugin.loader // 提取css到文件中,放到head中
                                : "style-loader", // 4. 加载样式文件到head
    
                        },
                        {
                            loader: "css-loader", // 3. 加载css
                            options: {
                                importLoaders: 1,
                                sourceMap: true
                            }
                        },
                        {
                            loader: "postcss-loader", // 2. 加载postcss(项目里配置的是 autoprefixer 和 px2rem) 转换 css里的rem和厂商前缀
                            options: {
                                postcssOptions: {
                                    config: path.resolve(__dirname, 'postcss.config.js')
                                },
                                sourceMap: true
                            }
                        },
                        {
                            loader: "sass-loader", // 1. 加载 scss 转换成css
                            options: {
                                sourceMap: true
                            }
                        }
                    ]
                },
                // {
                //     test: /\.(png|jpg|gif)$/,
                //     use: [
                //         {
                //             loader: 'file-loader',
                //             options: {
                //                 name: '[sha512:hash:base64:7].[ext]'
                //             }
                //         }
                //     ]
                // } // by junfenghe 2021-12-06
                {
                    test: /\.(png|jpg|gif|ico)$/,
                    type: 'asset/resource',
                    generator: {
                        filename: 'static/media/[hash][ext][query]'
                    }
                },
                {
                    test: /\.svg/,
                    type: 'asset/inline'
                },
                // 20230216 打包html中的图片
                {
                    test: /\.(htm|html)$/i,
                    loader: "html-withimg-loader"
                }
                // {
                //     test: /\.(txt|pdf|excel)$/,
                //     type: 'asset/source'
                // }
            ]
        },
        resolve: {
            extensions: ["*", ".js", ".jsx", ".ts", ".tsx"], // 尝试按顺序解析这些后缀名。能够用户再引入模块时不带扩展,例如:import File from '../path/to/file'
        },
        output: {
            path: path.resolve(__dirname, "build"), // 文件输出的路径
            // filename: "bundle.js", //对于单一入口(entry point)起点,filename 会是一个静态名称;
            filename: "static/js/[name].[fullhash].bundle.js", // 决定了每个输出 bundle 的名称。这些 bundle 将写入到 output.path 选项指定的目录下。// 当通过多个入口起点(entry point)、代码拆分(code splitting)或各种插件(plugin) 创建多个 bundle,应该赋予每个 bundle 一个唯一的名称
            assetModuleFilename: "images/[hash][ext][query]" // by junfenghe 2021-12-06 // by junfenghe 20221228
        },
    //20230216
        optimization: {
            minimize: true,
            minimizer: [
                // 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
                `...`,
                new CssMinimizerPlugin({
                    parallel: true,//使用多进程并发执行,
                    minimizerOptions:{
                        preset:[
                            "default",
                            {
                                discardComments: {removeAll:true},//移除所有注释
                            },
                        ]
                    }
                }),
            ]
        },
    //20230216
        plugins: [
            new HtmlWebpackPlugin({
                template: path.join(__dirname, 'public/index.html')
            }),
            new CleanWebpackPlugin({
                path: path.join(__dirname, 'build')
            }),
            // // 提取css
            new MiniCssExtractPlugin({
                // Options similar to the same options in webpackOptions.output
                // both options are optional
                filename: 'static/css/[name].[contenthash:8].css',
                chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
            }),
            new CssMinimizerPlugin()
    
        ],
        devServer: {
            static: {
                directory: path.join(__dirname, "public")
            },
            historyApiFallback: true, //When using the HTML5 History API, the index.html page will likely have to be served in place of any 404 responses. Enable devServer.historyApiFallback by setting it to true:
            port: 3004,
            compress: true,
        },
        devtool: isProduction?false:'source-map',//生产环境关闭sourcemap
    }
    
    if (isProduction) {
        pluginsProduction = [
            // 20230216 代码压缩
            // new UglifyJsPlugin({
            //     parallel: true,// 使用多进程并行以提高构建速度
            //     sourceMap: true,// 使用源映射将错误信息位置映射到模块(这将会减慢编译速度)。
            //     // extractComments:true,//启用禁用提取注释
            //     cache: true,//启用缓存
            //     uglifyOptions: {
            //         comments: false,//如果你构建时不想出现注释,可以按照以下配置将 uglifyOptions.output.comments 设置为 false:
            //     },
            // }),
    
        ]
        module.exports.plugins.push(
            ...pluginsProduction
        )
    
    }
    
    

    改完之后,已如丝般顺滑

    相关文章

      网友评论

          本文标题:665. 【前端】解决 webpack5 热更新时间太长的问题

          本文链接:https://www.haomeiwen.com/subject/lubrsdtx.html