Bootstrap

vue webpack3升级webpack4 踩坑记录

vue webpack3升级webpack4 踩坑记录

1 webpack4 需要node.js版本>= 10 

2先卸载旧版本插件,重新安装新版本插件 webpack4版本中cli工具分离成了webpack核心库与webpack-cli命令行工具两个模块

npm uninstall webpack webpack-bundle-analyzer webpack-dev-server webpack-merge -D
npm install webpack webpack-cli webpack-bundle-analyzer webpack-dev-server webpack-merge -D

我的版本  版本自己定义 [email protected]

3升级相关插件

npm uninstall copy-webpack-plugin css-loader eslint-loader file-loader html-webpack-plugin url-loader friendly-errors-webpack-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin -D
npm install copy-webpack-plugin css-loader eslint-loader file-loader html-webpack-plugin url-loader friendly-errors-webpack-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin -D

4.升级vue-loader

npm uninstall vue-loader -D
npm install [email protected] -D

5.替换webpack相关插件,extract-text-webpack-plugin替换为mini-css-extract-plugin

npm uninstall extract-text-webpack-plugin -D
npm install mini-css-extract-plugin -D

配置修改

  1.webpack.base.conf.js文件

module.exports = {
   + mode: process.env.NODE_ENV
}

   2. util.js文件

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

  // generate loader string to be used with extract text 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
        })
      })
    }

    // Extract CSS when that option is specified
    // (which is the case during production build)
    if (options.extract) {
       +return [MiniCssExtractPlugin.loader].concat(loaders)
      //把以下代码段去掉
      // return ExtractTextPlugin.extract({
      //   use: loaders,
      //   fallback: {
			// 		loader: 'vue-style-loader',
			// 		options: {
			// 			singleton: false // 为true表示将页面上的所有css都放到一个style标签内
			// 		}
			// 	},
      //   publicPath: '../../'
      // })
    } else {
      return ['vue-style-loader'].concat(loaders)
    }
  }

 

  3.webpack.prop.conf.js文件

   (1)将MiniCssExtractPlugin代替ExtractTextPlugin

+ const MiniCssExtractPlugin = require("mini-css-extract-plugin")
- const ExtractTextPlugin = require('extract-text-webpack-plugin')
 
...
-  new ExtractTextPlugin({
+  new MiniCssExtractPlugin({
   filename: utils.assetsPath('css/[name].[contenthash].css'),
   allChunks: true,
  }),

(2)删除UglifyJsPlugin配置项

- const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
...
- new UglifyJsPlugin({
-   uglifyOptions: {
-    compress: {
-     warnings: false
-    }
-   },
-   sourceMap: config.build.productionSourceMap,
-   parallel: true
- })

(3)删除CommonsChunkPlugin配置项

- new webpack.optimize.CommonsChunkPlugin({
-   name: 'vendor',
-   minChunks (module) {
-    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
-  }), 

(4)添加optimization配置项(与plugins平级)

 + optimization: {
 +   splitChunks: {
 +     chunks: 'async',
 +     minSize: 30000,
 +     minChunks: 1,
 +     maxAsyncRequests: 5,
 +     maxInitialRequests: 3,
 +     automaticNameDelimiter: '~',
 +     name: true,
 +     cacheGroups: {
 +       vendors: {
 +         test: /[\\/]node_modules[\\/]/,
 +         priority: -10
 +       },
 +       default: {
 +         minChunks: 2,
 +         priority: -20,
 +         reuseExistingChunk: true
 +       }
 +     }
 +   },
 +   runtimeChunk: {
 +     name: 'runtime'
 +   }
 + },

遇到的错误解决记录

1npm run dev启动项目报错【module.exports = merge(prodEnv, {TypeError: merge is not a function TypeError: merge is not a function at Object.

解决方案

  • 找到项目中引入webpack-merge的地方,一般是config下的或者是build文件里用到的
  • 下面代码是修改前
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',
  BASE_API: '"http://xxxxxx.com"',
})

修改后

'use strict'
//新版本用解构出来merge模块,已经不能直接merge,因为依赖的源文件暴露方式也变了
const {merge}= require('webpack-merge')
const prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',
  BASE_API: '"http://xxxxxx.com"',
})

  • 注意是更改所有引入webpack-merge的地方
  • 我的版本  "webpack-merge": "^5.7.3"
     

解决报错Cannot find module 'webpack-cli/bin/config-yargs'

解决方法:
卸载局部或者全局 webpack-dev-server

npm uninstall webpack-dev-server -g       卸载全局
npm uninstall webpack-dev-server -D      卸载局部(本地) 

安装指定版本的 [email protected] 测试了下升级到4得是dev-server得是3以上才好使

npm i [email protected] -D    本地安装

 

RemovedPluginError: webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.

升级4以后这个也需要重新配置下

解决办法

myApp/build/webpack.base.conf.js 文件

 增加下面代码 和 plugins 平级

  optimization: {
    splitChunks: {
      cacheGroups: {
        commoms: {
          name: 'commons',
          chunks: 'initial',
          minChunks: 2
        }
      }
    }
  }

注释一行代码

  plugins: [
    // new webpack.optimize.CommonsChunkPlugin('common.js'),
    new webpack.ProvidePlugin({
      jQuery: "jquery",
      $: "jquery"
    })
  ],

 

ValidationError: Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.

copy-webpack-plugin运行报错误 升级4以后也需要重新配置

错误配置 文件位置 myApp/build/webpack.dev.conf.js / myApp/build/webpack.prod.conf.js 这两都要改

  new CopyWebpackPlugin([
            {
                // from:path.join(__dirname,'assets'),
                // to:'assets'
            }

        ])

重新配置

  new CopyWebpackPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, '../static'),
          to: config.build.assetsSubDirectory,
          // ignore: ['.*']
        }
      ],
    }),

TypeError: compilation.getLogger is not a function

CopyWebpackPlugin这个插件升级导致的问题

CopyWebpackPlugin 里的插件 copy-webpack-plugin 下载5.1.1版本的就可以了

npm uninstall copy-webpack-plugin -d
npm install  [email protected] -d

然后 myApp/build/webpack.dev.conf.js / myApp/build/webpack.prod.conf.js 文件里 配置 copy-pack配置恢复到以前的配置

 new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.dev.assetsSubDirectory,
        ignore: ['.*']
      }
    ]),

升级4 本应配置

 new CopyWebpackPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, '../static'),
          to: config.build.assetsSubDirectory,
          // ignore: ['.*']
        }
      ],
    }),

但现在要恢复以前的配置 这块 具体原因还不知道,知道的解答下。

vue 出现 Cannot GET / 的问题

修改config文件夹下面的index.js里面,把 assetsPublicPath: './'改成“ assetsPublicPath: '/'

然后重新运行 npm run dev

遇到这个问题的时候 看到CSDN上的一篇博客,好像这种情况下也会出现 Cannot GET /的问题,终端有报错信息,报错信息如下(截图来自其他人的博客,这是看到其他伙伴发生这个问题放在这记录下):

这种情况要重新装下request模块

    npm remove request

    npm install requset

然后 npm run 跑一下就可以了

 

报错 :TypeError: Cannot read property 'tap' of undefined

解决方法: 

  • 修改 "html-webpack-plugin":  版本 "4.0.0"
  • remove node_modules
  • remove package-lock.json
  • npm install

错误:Cannot read property 'babel' of undefined

解决:升级Babel   npm -i [email protected] -D

 

Error: listen EADDRINUSE: address already in use :::9090

解决:电脑本地运转的程序中和本次运行服务端口号重复,重新换一个端口号

ValidationError: Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.

css-loader大于1.0.0版本,都是会报错的

重点在minimize 上,webpack 版本的问题,我的webpack 版本是 4.32.2 css-loader 已经没有了这个选项了。

解决办法:找到 build/utils.js , 将cssloader 里的minimize 注释掉,之后重新运行

 

;