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选项。

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