webpack3 升级到webpack4的经验帖

258 阅读2分钟

因业务更新升级,要求升级webpack4,用于接入新技术栈,将升级过程写下来,有遇到相同场景的同学可以参考一下。

参考文章 juejin.cn/post/722368… 感谢前人的无私分享

ps,经大家提醒 webpack4 能完美运行之后,基本上可以无痛升级webpack5,如果不成功可以参考官网迁移文档 webpack.docschina.org/migrate/5/ 修改部分配置

第一步,升级依赖

相关的依赖需要升级到合适的版本,这个需要根据项目所安装的依赖来升级,下面是一些比较基础常用的依赖,以及对应升级的版本供大家参考, node环境为v14.21.3,已经成功升级验证。

  • 新增两个依赖
依赖版本
mini-css-extract-plugin^1.6.2
webpack-cli^4.10.0
  • 几个基础的依赖升级
依赖升级前升级后
webpack-dev-server^2.9.1^3.11.3
webpack^3.6.0^4.47.0
vue-template-compiler^2.5.2^2.7.16
vue-loader^13.3.0^15.7.0
html-webpack-plugin"^2.30.1^4.5.2

如果启动开发环境或者打包的时候还有提示需要升级依赖的情况,按照提示更新对应的依赖即可。

第二步,修改webpack配置文件

webpack.base.conf.js

增加VueLoaderPlugin配置

   const { VueLoaderPlugin } = require('vue-loader')  // webpack4需要手动导入
   
  module.export  = {
      // ...
      plugin: [
      //...
         new VueLoaderPlugin(), 
      ]
  }
   

utils.js

mini-css-extract-plugin配置

插件的主要功能是提取css成单独的css文件, webpack4推荐 mini-css-extract-plugin插件替代以前的extract-text-webpack-plugin

const MiniCssExtractPlugin = require("mini-css-extract-plugin")  
export cssLoaders = function (options) {
    //...
     if (options.extract) {
            // return ExtractTextPlugin.extract({
            //     use: loaders,
            //     fallback: "vue-style-loader"
            // })
          return [options.extract ? MiniCssExtractPlugin.loader : 'vue-style-loader'].concat(loaders)
        } else {
            return ["vue-style-loader"].concat(loaders)
        }
}
    //...

webpack.prod.conf.js

本地开发启动有使用该插件的话,也可以在webpack.dev.conf.js如此配置


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

module.exports = {
    //...
    plugins: [
         // 升级后替换为该插件, 该插件只支持webpack4以上版本
        new MiniCssExtractPlugin({
            filename: "static/css/[name].css",
            chunkFilename: "[id].css",
            ignoreOrder: true
        }),
    ]
    // ...
}

注销或删除原有的 CommonsChunkPlugin配置,改用webpack提供的splitChunks功能

    module.exports = {
     // ... 
      optimization: {
        // 此处配置可参考,具体根项目情况来配置
        splitChunks: { 
            chunks: 'async',
            minSize: 30000, // 大于30KB才单独分离成chunk
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            name: true,
            cacheGroups: {
                default: {
                  priority: -20,
                  reuseExistingChunk: true
                },
                // 生成 vendors.js,
                vendors: {
                  name: 'vendors',
                  test: /[\\/]node_modules[\\/]/,
                  priority: 10,
                  chunks: 'all'
                  // enforce: true
                },
                common: {
                  name: 'common',
                  chunks: 'all',
                  minChunks: 2,
                  minSize: 0,
                  maxInitialRequests: 5 // The default limit is too small to showcase the effect
                }

            },

        },
        runtimeChunk: {
            name: 'manifest'
        }
    },
    // ...
    },

UglifyJsPlugin用法更新


    module.export = {
            minimizer: [
                new UglifyJsPlugin({
                    parallel: true, // 开启多进程压缩。
                    uglifyOptions: {
                      output: { comments: false },
                      compress: {
                        warnings: false,
                        drop_debugger: true, // 是否清除debugger
                        drop_console: true // 是否清除所有console
                        // pure_funcs: ['console.log','console.info','console.warn','console.debug'] //drop_console 设置false,需要特殊清除的
                      }
                    },
                    sourceMap: config.build.productionSourceMap
                  })
        ],
    plugins: [
        // ...
        ]
    }

修改 HtmlWebpackPlugin 的 chunksSortMode 为"auto" 或"none"


  new HtmlWebpackPlugin({
            filename: process.env.NODE_ENV === "testing"
                ? "index.html"
                : config.build.index,
            template: "index.html",
            inject: true,
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeAttributeQuotes: true
                // more options:
                // https://github.com/kangax/html-minifier#options-quick-reference
            },
            // necessary to consistently work with multiple chunks via CommonsChunkPlugin
            chunksSortMode: "auto"
        }),

第三步,启动命令修改

  "scripts": {
       "dev": "webpack serve --inline --progress --config build/webpack.dev.conf.js", 
     },

ps: 这一步根据实际情况来

至此,基本修改完毕,开发环境可用,生产打包也正常了。

其他问题解决

cannot assigin to read only property 'exports' of Object '#Object' ...

  • 安装插件 npm install babel-plugin-transform-es2015-modules-commonjs

  • .babelrc 里增加配置

 "presets": [
      //...
  ],
  "plugins": [
    "transform-es2015-modules-commonjs"
   ]