• 基于老项目升级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

  • 相关阅读:
    App集成支付宝
    关于Objective-c和Java下DES加密保持一致的方式
    Android开发规范
    android 屏幕适配问题
    Android AES加密算法及其实现
    linux文件系统调用(1)---mount
    Java(Android)解析KML文件
    【Akka】在并发程序中使用Future
    函数指针问题,求解答
    android旋转动画的两种实现方式
  • 原文地址:https://www.cnblogs.com/Tiboo/p/14385863.html
Copyright © 2020-2023  润新知