基於vue-cli2.0項目中Webpack的升級與優化(一)

概述

在基於vue-cli2.0腳手架開發的項目至今已經有一年半的時間了,由於業務在不斷迭代的關係,項目的代碼已經達到8w行了,從而致使了webpack打包編譯的速度愈來愈慢。爲了項目的長治久安,我決心要對這個項目中的webpack進行升級與優化。javascript

vue-cli2.0集成了Webpack3,可是在當前Webpack5都呼之欲出的狀況下,Webpack3顯然就顯得太老了,並且新版本自己就是對老版本的優化和加強,與其花精力在老版本上作優化爲何不在新版本上這麼作呢?站在巨人肩膀上的感受難道很差麼?css

升級至Webpack4

升級Webpack並安裝webpack-cli

yarn add webpack webpack-cli
複製代碼

更新webpack-dev-server

yarn add webpack-dev-server -D
複製代碼

更新loader

yarn add postcss-loader@3.0.0 css-loader@3.2.0 vue-style-loader@4.1.2 vue-loader@15.7.1  -D
複製代碼

修改webpack.base.conf.js中的vue-loader解析規則html

//const vueLoaderConfig = require('./vue-loader.conf')
const { VueLoaderPlugin } = require('vue-loader');

module.exports = {
  ...,
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
       // options: vueLoaderConfig
      },
    ]
  },
 plugins: [
   new VueLoaderPlugin()
 ]
}

複製代碼

更新plugin

yarn add html-webpack-plugin@3.2.0 -D
複製代碼

替換插件

若是存在如下錯誤,那是因爲extract-text-webpack-plugin不兼容webpack4形成,官方推薦的使用mini-css-extract-plugin來替換使用。vue

yarn add mini-css-extract-plugin@0.8.0 -D
複製代碼

修改utils.jsjava

// const ExtractTextPlugin = require('extract-text-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

exports.cssLoaders = function (options) {
  ...
// Extract CSS when that option is specified
    // (which is the case during production build)
    // if (options.extract) {
    // return ExtractTextPlugin.extract({
    // use: loaders,
    // fallback: 'vue-style-loader',
    // publicPath: '../../', //注意: 此處根據路徑, 自動更改,添加publicPath,能夠在css中使用背景圖
    // })
    // } else {
    // return ['vue-style-loader'].concat(loaders)
    // }

 return [
      options.extract ? {loader:MiniCssExtractPlugin.loader, options: {publicPath: '../../'}} : 'vue-style-loader',
    ].concat(loaders)
}
複製代碼

修改webpack.prod.conf.jsnode

//const ExtractTextPlugin = require('extract-text-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const webpackConfig = merge(baseWebpackConfig, {
    ...,
    plugins: [
      new MiniCssExtractPlugin({
        filename: utils.assetsPath('css/[name].[contenthash].css'),
        allChunks: true,
      }),
        // new ExtractTextPlugin({
        // filename: utils.assetsPath('css/[name].[contenthash].css'),
        // Setting the following option to `false` will not extract CSS from codesplit chunks.
        // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
       // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
       // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
      // allChunks: true,
      // }),
    ]
})
複製代碼

配置development環境

在webpack.dev.conf.js中添加mode:「development」,並移除NamedModulesPlugin,NoEmitOnErrorsPlugin插件,webpack4已修改成內置插件。webpack

module.exports = {
  ...,
 mode: "development",
 ...,
 plugins: {
     //new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
    //new webpack.NoEmitOnErrorsPlugin(),
  }  
}
複製代碼

在dev環境下運行,發現報錯,咱們能夠經過修改webpack.base.conf.js中的配置來解決。git

module.exports = {
  ...
  module: {
    rules: [  
      {
        test: /\.js$/,
        loader: 'babel-loader'
       // include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
        include: [resolve('src'),resolve('test')],
        exclude: /node_modules/
      },
    ]
  }
}
複製代碼

這樣的咱們的dev環境就算升級成功了github

配置production環境

在webpack.prod.conf.js中添加mode: "production"web

const webpackConfig = merge(baseWebpackConfig, {
   ...,
    plugins: [
      //new webpack.optimize.CommonsChunkPlugin(),
      //new webpack.optimize.CommonsChunkPlugin({}),
      //new webpack.optimize.CommonsChunkPlugin({}),
      //new webpack.optimize.ModuleConcatenationPlugin(),
      //new OptimizeCSSPlugin({}),
      //new UglifyJsPlugin({})
   ],
})
複製代碼

再刪除webpack.prod.conf.js中的部分插件

const webpackConfig = merge(baseWebpackConfig, {
    ...,
   optimization: {
    //取代 new UglifyJsPlugin
    minimizer: [
      // 壓縮代碼
      new UglifyJsPlugin({
        uglifyOptions: {
          compress: {
            warnings: false,
            drop_debugger: true,//關閉debug
            drop_console: true,//關閉console
          }
        },
        sourceMap: config.build.productionSourceMap,
        parallel: true
      }),
      // 可本身配置,建議第一次升級先不配置
      new OptimizeCSSPlugin({
        // cssProcessorOptions: config.build.productionSourceMap
        // ? {safe: true, map: {inline: false}, autoprefixer: false}
        // : {safe: true}
      }),
    ],
    // 識別package.json中的sideEffects以剔除無用的模塊,用來作tree-shake
    // 依賴於optimization.providedExports和optimization.usedExports
    sideEffects: true,
    // 取代 new webpack.optimize.ModuleConcatenationPlugin()
    concatenateModules: true,
    // 取代 new webpack.NoEmitOnErrorsPlugin(),編譯錯誤時不打印輸出資源。
    noEmitOnErrors: true,
    splitChunks: {
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          chunks: 'initial',
          name: 'vendors',
        },
        'async-vendors': {
          test: /[\\/]node_modules[\\/]/,
          minChunks: 2,
          chunks: 'async',
          name: 'async-vendors'
        }
      }
    },
    runtimeChunk: { name: 'runtime' }
    },
  })
複製代碼

最後再production環境下打包,若是出現下面這樣的結果說明咱們

參考

基於vue-cli2.0,webpack3升級爲webpack4的踩坑之旅以及優化

相關文章
相關標籤/搜索