webpack4 发版也有一段时间了,发现 vue-cli 还是基于 webpack3 ,于是想着升级一个项目模板。

这里是升级后的项目,可以直接使用。=> 项目模板在这里,relase@4 分支下

(最近修改了一个 React 版本的,基于 vue-cli ,可以看看 Module_React_Webpack4,过程比较痛苦,就不贴了)


整体而言坑还是很多的,但是基本都是一些版本错误,升级一下包的版本大部分都可以解决。

先是常规的 vue-cli 安装。

这里写图片描述

然后 webpack 升级到 4.8.1,安装 webpack-cli 等插件。

"webpack": "^4.8.1",
"webpack-cli": "^2.1.3"
  • npm run dev 报错

这里写图片描述

这个是因为 webpack 和 webpack-dev-server 版本不兼容导致的,升级一下就好了

"webpack-dev-server": "^3.1.4",
  • 再次启动,报错
    这里写图片描述
    这里是因为 html-webpack-plugin 版本不兼容导致的,这里去网上搜索的话发现大部份博客都是说执行 yarn add webpack-contrib/html-webpack-plugin -D
    但是我使用的时候作者已经更新版本了,所以直接升级就可以,不需要安装 webpack 官方的替代版本。
"html-webpack-plugin": "^3.2.0",
  • 然后再次启动
    这里写图片描述

升级一下 eslint 和 eslint-loader

"eslint": "^4.19.1",
"eslint-loader": "^2.0.0",
// 这里如果直接 npm i -D eslint-loader 的话,升级到的版本是 1.9.0 还是会报错,需要指定版本升级到 2.0 以上
  • 继续
    这里写图片描述

升级 vue-loader

"vue-loader": "^15.0.10",
  • 这里再次运行报错会很多
    这里写图片描述

这里是因为最新版的 vue-loader 需要加一个新的配置 VueLoaderPlugin

// webpack.dev.conf.js
// 引入
const { VueLoaderPlugin } = require('vue-loader')

// 在下面的插件中加入
plugins: [
    ...
    new VueLoaderPlugin(),
    ...
]


// webpack.prod.conf.js 文件同样
// 引入
const { VueLoaderPlugin } = require('vue-loader')

// 在下面的插件中加入
plugins: [
    ...
    new VueLoaderPlugin(),
    ...
]
  • 再次运行
    这里写图片描述

webpack4 需要指定打包的模式 (mode),指定一下就好,可以在 package.json 的命令中指定,也可以写入配置

// webpack.dev.conf.js
const webpackConfig = merge(baseWebpackConfig, {
    mode: 'development',
    module: {...}
}


// webpack.prod.conf.js 
const webpackConfig = merge(baseWebpackConfig, {
    mode: 'production',
    module: {...}
}
  • 然后再次运行 npm run dev
    这里写图片描述

完全没有错误提示,至此, dev 环境的升级就完成了。

  • 然而,运行 npm run build 后。。。

这里写图片描述
熟悉的界面又出现了,

这部分错误是因为 webpack.optimize.CommonsChunkPlugin 已经被弃用,需要使用新的配置 config.optimization.splitChunks

// webpack.prod.conf.js
// 在 plugins 同级下添加配置
...
optimization: {
   splitChunks: {
     cacheGroups: {
       vendor: {
         test: /[\\/]node_modules[\\/]/,
         name: 'vendor',
         chunks: 'all'
       },
       manifest: {
         name: 'manifest',
         minChunks: Infinity
       },
     }
   },
 },
 plugins: [...]

// 去掉 plugins 中的这部分代码
...
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
 }),
 ...
  • 再次打包
    这里写图片描述

这里是因为官方已经不推荐使用 extract-text-webpack-plugin 提取 css 样式,可以使用 mini-css-extract-plugin 替代
如果不想改变的话可以升级 extract-text-webpack-plugin

"extract-text-webpack-plugin": "^4.0.0-beta.0",

推荐使用 mini-css-extract-plugin

// 首先安装 "mini-css-extract-plugin": "^0.4.0",
// 并且去掉 package.json 中的包 "extract-text-webpack-plugin": "^4.0.0-beta.0",

// webpack.base.conf.js

// 去掉 extract-text-webpack-plugin
// const ExtractTextPlugin = require('extract-text-webpack-plugin')

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

// 下面的 generateLoaders 函数更改配置(*中间的为改动部分)
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)
   // ********************

   } else {
     return ['vue-style-loader'].concat(loaders)
   }
 }

// webpack.prod.conf.js

// 去掉 extract-text-webpack-plugin
// const ExtractTextPlugin = require('extract-text-webpack-plugin')

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

// 去掉 plugins 里的配置
new ExtractTextPlugin({
   filename: utils.assetsPath('css/[name].[contenthash].css'),
   allChunks: true,
 }),

// 然后加入新的插件配置
new MiniCssExtractPlugin({
   filename: utils.assetsPath('css/[name].[contenthash:12].css'),
   allChunks: true,
 }),

再次打包就可以运行了
这里写图片描述

到此 webpack4 已经升级成功了。

Logo

前往低代码交流专区

更多推荐