博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vue-cli项目升级webpack4踩坑
阅读量:6853 次
发布时间:2019-06-26

本文共 7292 字,大约阅读时间需要 24 分钟。

webpack4 也发布3个月了,一直想体验一下。最近项目不忙,也感觉项目编译和打包的速度略慢,索性就把一个由 vue-cli 生成的项目从 webpack3 升级到 webpack4,期间遇到的问题也记录一下。

安装依赖

npm i webpack@latest webpack-cli --save-dev

出现报错信息:

根据报错信息,逐个升级它们:

npm install extract-text-webpack-plugin@latest html-webpack-plugin@latest inject-loader@latest webpack-dev-middleware@latest webpack-dev-server@latest

顺便把其它 loadersplugins 都升级到最新版本

npm install webpack-bundle-analyzer@latest vue-template-compiler@latest webpack-merge@latest friendly-errors-webpack-plugin@latest copy-webpack-plugin@latest optimize-css-assets-webpack-plugin@latest

npm install css-loader@latest file-loader@latest url-loader@latest less-loader@latest postcss-loader@latest vue-loader@latest vue-style-loader@latest

升级的版本信息如下:

  • webpack@4.8.3

  • webpack-cli@2.1.4

  • html-webpack-plugin@3.2.0

  • extract-text-webpack-plugin@4.0.0-beta.0

  • webpack-dev-server@3.1.4

  • webpack-dev-middleware@3.1.3

  • friendly-errors-webpack-plugin@1.7.0

  • webpack-bundle-analyzer@2.13.1

  • webpack-merge@4.1.2

  • optimize-css-assets-webpack-plugin@4.0.1

  • copy-webpack-plugin@4.5.1

  • vue-template-compiler@2.5.16

  • postcss-loader@2.1.5

  • inject-loader@4.0.1

  • less-loader@4.1.0

  • css-loader@0.28.11

  • vue-style-loader@4.1.0

  • file-loader@1.1.11

  • vue-loader@15.2.0

  • url-loader@1.0.1

运行 npm run dev,又出现 eslint 的报错信息

npm i eslint@latest eslint-config-standard@latest eslint-friendly-formatter@latest eslint-loader@latest eslint-plugin-import@latest eslint-plugin-node@latest eslint-plugin-promise@latest eslint-plugin-standard@latest eslint-plugin-vue@latest

  • eslint-plugin-standard@3.1.0
  • eslint-plugin-vue@4.5.0
  • eslint-plugin-promise@3.7.0
  • eslint-plugin-import@2.12.0
  • eslint-config-standard@11.0.0
  • eslint-loader@2.0.0
  • eslint-plugin-node@6.0.1
  • eslint@4.19.1
  • eslint-friendly-formatter@4.0.1

配置

相比于 webpack 3,webpack 4 的配置部分改变,具体如下:

在 dev 环境中,添加 mode: 'development',去掉 webpack.NamedModulesPlugin 及 webpack.NoEmitOnErrorsPlugin 插件,因为 webpack4 开发模式已经内置。

// webpack.dev.conf.jsmodule.exports = {  // ...  mode: 'development',  // ...  plugins: {      // new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.      // new webpack.NoEmitOnErrorsPlugin(),  }}复制代码

在 prod 环境中添加 mode 配置,用 optimization 代替以前的 webpack.optimize.CommonsChunkPlugin 、 uglifyjs-webpack-plugin 、 webpack.optimize.ModuleConcatenationPlugin 相关配置及引用

// webpack.production.prod.js// const UglifyJsPlugin = require('uglifyjs-webpack-plugin')const webpackConfig = merge(baseWebpackConfig, {    // ...    mode: 'production',    // webpack4 内置  optimization: {    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' }  },  // ...  pluins: {    // new UglifyJsPlugin({
// uglifyOptions: {
// beautify: false, // comments: false, // compress: {
// warnings: false, // drop_console: true // } // }, // sourceMap: config.build.productionSourceMap, // parallel: true // }), // ... // enable scope hoisting // new webpack.optimize.ModuleConcatenationPlugin(), // split vendor js into its own file // 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 // ) // } // }), // extract webpack runtime and module manifest to its own file in order to // prevent vendor hash from being updated whenever app bundle is updated // new webpack.optimize.CommonsChunkPlugin({
// name: 'manifest', // minChunks: Infinity // }), // // This instance extracts shared chunks from code splitted chunks and bundles them // // in a separate chunk, similar to the vendor chunk // // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk // new webpack.optimize.CommonsChunkPlugin({
// name: 'app', // async: 'vendor-async', // children: true, // minChunks: 3 // }), }}复制代码

运行 npm run dev,又出现 vue-loader 的报错信息:

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

为了解决上面的 vue-loader 的报错,在 webpack.base.conf.js 中添加配置

// webpack.base.conf.jsconst { VueLoaderPlugin } = require('vue-loader')//...plugins: [  new VueLoaderPlugin()]复制代码

运行 npm run dev,报错:

虽然有报错信息,但是没有显示错误的具体位置。在网上查找了很久,发现有人说他在template filerouting file 出现了循环引用。 根据这个,我突然发现在 main.js 和 向后台请求的api文件中都引用了路由文件,api.js 中引用是为了写 axios拦截器,出现 401、404 或 500 时,跳转相应页面。 注释掉 api.js 中对 router 的引用,确实可以成功运行了,但是 401、404、500 跳页的问题就没法解决了。 但是后来我又找到了另一种方法,在 HtmlWebpackPlugin 插件中添加或者修改 chunksSortMode: none。(不过不确定这方式会不会对性能优化等等有影响)

new HtmlWebpackPlugin({  filename: 'index.html',  template: 'index.html',  inject: true,  chunksSortMode: 'none'}),复制代码

运行 npm run dev,没问题了。

接下来试试生产环境,运行 npm run build。1分钟过去了……5分钟过去了……中午吃饭1个小时都过去了……居然没反应,也没有报错。又尝试了好几次,依旧如此。在网上也没有找到相关问题。

于是我只好在 build.js 中逐步打断点,最后发现是 extract-text-webpack-plugin 插件的问题。 查找资料了解到 extract-text-webpack-plugin 其实是适配 webpack3 的,有个 extract-text-webpack-plugin@4.0.0-beta.0 版本可以适配 webpack4,但是我用的就是这个版本。

有人推荐用 mini-css-extract-plugin 来替代它,我就根据 尝试配置一下。

需要在 webpack.prod.conf.jsutils.js 两个文件中配置。

// webpack.prod.conf.js// const ExtractTextPlugin = require('extract-text-webpack-plugin')const MiniCssExtractPlugin = require('mini-css-extract-plugin')// ...// extract css into its own file// new ExtractTextPlugin({
// ...// })// 升级 webpack4, 由 ExtractTextPlugin 改用 MiniCssExtractPluginnew MiniCssExtractPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css'), allChunks: true,}),复制代码
// utils.js// const ExtractTextPlugin = require('extract-text-webpack-plugin')const MiniCssExtractPlugin = require('mini-css-extract-plugin')// ...// generate loader string to be used with extract text pluginfunction generateLoaders (loader, loaderOptions) {  const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]  if (loader) {    loaders.push({      loader: loader + '-loader',      options: Object.assign({}, loaderOptions, {        sourceMap: options.sourceMap      })    })  }  // 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' // }) // } else {
// return ['vue-style-loader'].concat(loaders) // } // 升级 webpack4, 由 ExtractTextPlugin 改用 MiniCssExtractPlugin return [ options.extract ? MiniCssExtractPlugin.loader : 'vue-style-loader', ].concat(loaders)}复制代码

运行 npm run build,终于成功了。

附上 webpack3 和 webpack4 的打包对比图,可以看到,体积少了一点(后期我会在边学习 webpack 边进行优化)但是打包的时间减少了一半,也不枉费我这么辛苦的升级。

参考

  1. https://github.com/jantimon/html-webpack-plugin/issues/870
  2. https://webpack.js.org/plugins/mini-css-extract-plugin/
  3. https://vue-loader.vuejs.org/guide/extract-css.html#webpack-4

转载地址:http://pefyl.baihongyu.com/

你可能感兴趣的文章
数据库设计的14个技巧(转)
查看>>
C++学习笔记之 (三)
查看>>
网络设备的安全汇总
查看>>
[转载] 七龙珠第一部——第103话 比克大魔王
查看>>
oracle datafile 生成查询树
查看>>
docker 资料
查看>>
swingEDT机制
查看>>
洛谷2038 无线网络发射器选址
查看>>
TP 服务器phpmyadmin用不了原因之一 开启伪静态 需要修改文件
查看>>
Java基础学习总结(1)——equals方法
查看>>
对于工作的一点点感悟
查看>>
大型网站技术架构(八)网站的安全架构
查看>>
查询Oracle正在执行和执行过的SQL语句
查看>>
MyBatis学习总结(10)——批量操作
查看>>
Linux的shell脚本打印图形和主机监控脚本练习
查看>>
storm流处理的简单例子的一些问题
查看>>
我的友情链接
查看>>
php5.2.5安装xcache-2.0.0
查看>>
varnish缓存四:性能调优
查看>>
关于顽固进程scclient.exe、scguardc.exe、sccltui.exe和系统服务scclient、scguardc
查看>>