Vue-cli項目升級到webpack4.0

對之前開發的項目升級webpack4.0的一個總結。

  1. 先升級webpack的版本

npm install webpack@latest webpack-cli -D

升級成功後,我們會發現,package.json文件中的webpack版本以及變成4.0以上。接下來將我們使用的插件和·loader·全部升級到最新的版本。
執行的命令是:

npm install loadername@latest -D

請根據自己使用的插件和loader進行升級操作。

升級完成之後,接下來我們來修改配置文件:

webpack.dev.conf.js文件

由於webpack4採用了mode選項來區分開發環境和生產環境,因此,我們需要在webpack.dev.conf.js文件中設置mode屬性。並且將NamedModulesPluginNoEmitOnErrorsPlugin兩個插件註釋掉。因爲webpack4開啓development模式已經默認使用它們了。

const devWebpackConfig = merge(baseWebpackConfig, {
  mode: 'development',
  // ....
  plugins: [
    //...

    // 更新到webpack4 需要註釋掉這兩個插件
    // new webpack.NamedModulesPlugin(),
    // new webpack.NoEmitOnErrorsPlugin(),
  ]
})

webpack.prod.conf.js

webpack.prod.conf.js文件中需要設置mode選項,將mode的選項值設置成'production',

  • new NoEmitOnErrorsPlugin(),
  • new ModuleConcatenationPlugin(),
  • new DefinePlugin({ “process.env.NODE_ENV”: JSON.stringify(“production”) })
  • new UglifyJsPlugin()

以上的這些插件全部註釋掉,因爲webpack4production模式下已經默認引用了這些插件。
而webpack4最大的變化就是棄用了CommonsChunkPlugin,而採用了 optimization.splitChunks 選項。因此,我們需要移除掉與CommonsChunkPlugin有關的所有配置。最終,webpack.prod.conf.js文件變成這樣:

const webpackConfig = merge(baseWebpackConfig, {
  mode: 'production',

  // ....

  // 此配置用來替代plugin裏面的配置
  optimization: {
    minimizer: [
      // 壓縮代碼
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: config.build.productionSourceMap,
      }),
      // 可自己配置,建議第一次升級先不配置
      new OptimizeCSSPlugin({
      }),
    ],
    // 可自己配置,建議第一次升級先不配置
    splitChunks: {
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          chunks: 'initial',
          name: 'vendors',
        },
        'async-vendors': {
          test: /[\\/]node_modules[\\/]/,
          minChunks: 2,
          chunks: 'async',
          name: 'async-vendors'
        }
      }
    }
  },
  plugins: [
    // new webpack.DefinePlugin({
    //   'process.env': env
    // }),

    // new UglifyJsPlugin({
    //   uglifyOptions: {
    //     beautify: false,
    //     comments: false,
    //     compress: {
    //       warnings: false,
    //       drop_console: true
    //     }
    //   },
    //   sourceMap: config.build.productionSourceMap,
    //   parallel: true
    // }),

    // new webpack.optimize.CommonsChunkPlugin({
    //   name: 'vendor',
    //   minChunks (module) {
    //     // any required modules inside node_modules are extracted to vendor
    //     return (
    //       module.resource &&
    //       /\.js$/.test(module.resource) &&
    //       module.resource.indexOf(
    //         path.join(__dirname, '../node_modules')
    //       ) === 0
    //     )
    //   }
    // }),

     // new webpack.optimize.CommonsChunkPlugin({
    //   name: 'manifest',
    //   minChunks: Infinity
    // }),

    // new webpack.optimize.CommonsChunkPlugin({
    //   name: 'app',
    //   async: 'vendor-async',
    //   children: true,
    //   minChunks: 3
    // }),
  ]
});

這個時候運行npm run dev ,此時報錯:

vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.

在升級到webpack4的時候,我們需要手動引入vue-loader的插件,接下來,修改vue-loader.conf.js文件.

vue-loader.conf.js

module.exports = {
  // loaders: utils.cssLoaders({
  //   sourceMap: sourceMapEnabled,
  //   extract: isProduction,
  //   usePostCSS: true
  // }),
  // cssSourceMap: sourceMapEnabled,
  // cacheBusting: config.dev.cacheBusting,
  transformToRequire: {
    video: ['src', 'poster'],
    source: 'src',
    img: 'src',
    image: 'xlink:href'
  }
}

接下來在webapck.base.conf.js文件中引入vue-loader的插件

const { VueLoaderPlugin } = require('vue-loader')

//...
plugins: [
  new VueLoaderPlugin()
]

此時再次運行npm run dev,如果報下面的這種錯誤:

vue-template-compiler must be installed as a peer dependency, or a compatible compiler implementation must be passed via options.

解決方法:

  • 將你的vue-loader 升級到最新的版本
  • 如果已經處於最新的版本,檢測vue-loader是否已經安裝成功
  • 如果在package.json文件中已經存在vue-loader,此時仍然報這個錯誤,就將node_modules文件夾刪掉,再執行npm install進行重新安裝。

此時再次運行npm run dev ,就可以看到編譯成功。

接下來讓我們打包一下試試看,運行 npm run build。如果此時報錯,且錯誤與extract-text-webpack-plugin有關的話,在這裏建議將extract-text-webpack-plugin替換成mini-css-extract-plugin插件。

安裝mini-css-extract-plugin

npm install mini-css-extract-plugin@latest -D

在webpack.prod.conf.js文件中將extract-text-webpack-plugin的配置註釋掉,添加mini-css-extract-plugin的配置。

// webpack.prod.conf.js

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

const webpackConfig = merge(baseWebpackConfig, {

 // ...

 plugins: [

   // ...

   // 升級 webpack4, 由 ExtractTextPlugin 改用 MiniCssExtractPlugin
   new MiniCssExtractPlugin({
     filename: utils.assetsPath('css/[name].[contenthash].css'),
     allChunks: true,
   }),
 ]
});

修改utlis.js文件

// utlis.js

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

// ....

 function generateLoaders (loader, loaderOptions) {
    const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]

    if (loader) {
      loaders.push({
        loader: loader + '-loader',
        options: Object.assign({}, loaderOptions, {
          sourceMap: options.sourceMap
        })
      })
    }

    // 升級 webpack4, 由 ExtractTextPlugin 改用 MiniCssExtractPlugin
    return [
      options.extract ? MiniCssExtractPlugin.loader : 'vue-style-loader',
    ].concat(loaders);
  }

此時再次運行npm run build便可以看到成功打包。升級了webpack4之後打包的時間縮短了很多。

在成功升級到webpack4.0之後,又遇到了問題,便是每次更新的時候都會把所有頁面編譯一遍,此時的解決辦法:

  1. 檢測vue-loader的版本, webpack4所配置的vue-loader的版本,必須是v15以上的。

  2. 如果vue-loader的版本是最新的,請檢測webpack.dev.conf.js文件中,是否有配置mode選項。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章