基于老项目升级webpack的心路历程

老项目,构建时长久的不敢想象,升级不敢动,一动动全身,各处报错,无从下手。结合自己的经验,一步步把架构升级的主体弄好,对于其他报错就可实际问题一个个解决,排除干扰项。

先从package解剖:

1) 升级至对应webpack版本

"webpack": "^3.6.0"

替换为:
"webpack": "^4.26.0"
"webpack-cli": "^3.3.0" (使用 webpack 4+ 版本,需要安装 CLI)

 

2)  查看"webpack-dev-server": "^2.9.1"源码文件中peerDependencies知依赖的webpack版本为2.x, 3.x。 所以平时在升级时要多注意包peerDependencies的依赖版本

"webpack-dev-server": "^2.9.1"

替换为:
"webpack-dev-server": "^3.11.0"

 

3) html-webpack-plugin同上由于依赖项缘故

"html-webpack-plugin": "^2.30.1"

替换为:
"html-webpack-plugin": "^3.2.0"

 

4) babel-loader同上由于依赖项缘故

"babel-loader": "^7.1.1"

替换为:
"babel-loader": "^8.1.0"

 

5) "babel-loader": "^8.1.0" 的依赖项为@babel/core,故需将babel周边进行升级

"babel-core": "^6.22.1"
"babel-preset-env": "^1.3.2"
"babel-plugin-transform-runtime": "^6.22.0"

替换为:
"@babel/core": "^7.4.4"
"@babel/preset-env": "^7.3.4"
"@babel/plugin-transform-runtime": "^7.11.0"

 

6) 从babel7.4开始,官方不推荐再使用@babel/polyfill转译

"babel-polyfill": "6.22.0"

替换为:
"@babel/runtime-corejs3": "^7.12.5"

如果对babel-polyfill、babel-preset-env、babel-plugin-transform-runtime的理解不清不楚,这里安利一个博主写的系列文章,清晰易懂

 

7) 升级vue-loader、eslint-loader:解决TypeError: Cannot read property 'vue' of undefined、TypeError: Cannot read property 'eslint' of undefined此类报错

"vue-loader": "^13.3.0"
"eslint-loader": "^1.7.1"
替换为: "vue-loader": "^14.2.2"
"eslint-loader": "^2.0.0"

 

8) 对于vue项目内支持使用JSX需安装的配套插件

"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-helper-vue-jsx-merge-props": "^2.0.3",

官网推荐的说明有如下规则:(我在babel7环境测试使用babel-plugin-transform-vue-jsx 3.x 的版本也能支持JSX, 不知是否是其他特殊写法不支持么,如若遇到JSX问题,可按官网推荐调整下版本,如果没有的话,忽视就好≧◠◡◠≦✌):

1、如果你使用的babel版本为6.x, 相对应的转译插件为babel-plugin-transform-vue-jsx 3.x

2、如果你使用的babel插件为7.x, 那么相对应的插件应该为babel-plugin-transform-vue-jsx 4.x 或者是 @vue/babel-plugin-transform-vue-jsx

关于babel-plugin-transform-vue-jsx说明

关于@vue/babel-plugin-transform-vue-jsx说明

 

build文件夹下配置修改:

1) 增加mode属性: 开发模式:mode: 'development'; 生产模式:mode: 'production'

2) CommonsChunkPlugin的废除,由splitChunks替代,默认的splitChunks配置如下:  

module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'async', 
      minSize: 30000,
      maxSize: 0,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      name: true,
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }
};

当然如果需要根据自身项目合理自定义,安利博文

 

3) 更换提取css的插件,对mini-css-extract-plugin不了解,点击

"extract-text-webpack-plugin": "^3.0.0"   
 
替换为:
"mini-css-extract-plugin": "^0.9.0",


utils.js文件:
if (options.extract) {
  return ExtractTextPlugin.extract({
    use: loaders,
    fallback: 'vue-style-loader'
  })
}
替换为:
if (options.extract) { return [MiniCssExtractPlugin.loader].concat(loaders) }
webpack.prod.conf.js文件:
new ExtractTextPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css'), allChunks: false })
替换为:
new MiniCssExtractPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css'), allChunks: false, ignoreOrder: true })

 

4) 关于混淆压缩 , 因为webpack4带有内置的terser-webpack-plugin,故插件uglifyjs-webpack-plugin可去掉

"uglifyjs-webpack-plugin": "^1.1.1" // 去除

 new UglifyJsPlugin({
   uglifyOptions: {
     compress: {
       warnings: false
     }
   },
   sourceMap: config.build.productionSourceMap,
   parallel: true
 })
   
 更改为:
 new terserPlugin({
   cache: true,
   parallel: true,
   sourceMap: false
 })

如若对混淆压缩打包感兴趣,可参考

 

5)既然是优化,少不了按需加载这个概念,支持第三方组件按需加载插件

如elementUI: 借助 babel-plugin-component,只引入需要的组件,以达到减小项目体积的目的

"babel-plugin-component": "^1.0.0", // element团队在基础上修改,未提PR,自成一家,具体使用: 参考element文档说明更改


如vxe-table:借助 babel-plugin-import,引入需要的组件

"babel-plugin-import": "^1.13.1", // Ant团队最先提出, 具体使用: 参考vxe-table文档说明更改

本以为按需加载的插件下一个就行,忽然来了两个,用的不明不白,顺手查了关于两者之间区别说明

 

6)最后如遇到此报错:BaseClient.js?e917:12 Uncaught TypeError: Cannot assign to read only property 'exports' of object '#

去除resolve('node_modules/webpack-dev-server/client')即可正常,原因不详,暂时无深入研究。

 

完成上面的步骤路程走了70%,下面接着根据项目的实际情况按以下思路进行优化:

1)还是从package.json下手,对于老项目,往往会存在很多不再使用的第三方包,删除dependencies中未引用的包

2)借助webpack-bundle-analyzer工具,将如下图所示处改为true, 执行npm run build即可得到分析结果



分析项目中过大的npm包,能否替换成体积更小的包,以及如若引入了echarts等,也需配置成按需加载

3)开启多线程打包,合理利用thread-loader, cache-loader处理性能开销大的loader(这个需要根据项目来进行测试是否达到优化的目的),从而优化构建时间


如若完成上续步骤,还想继续深入,更进一步的优化方案送上

只有耐得住性子,方可拨开云雾见月明

案例Demo: vue-cli2-webpack4-youhua

posted @ 2021-02-20 14:51  Tiboo  阅读(654)  评论(0编辑  收藏  举报