在Web开发领域,保持技术的更新是非常重要的。随着前端构建工具的快速发展,Webpack已经更新到5.x版本,如果你正在使用Vue2项目,并且还在使用Webpack 3,那么是时候考虑升级一下Webpack了。我最近将我的Vue2项目从Webpack 3升级到了Webpack 4。以下是我升级过程中积累的经验和步骤,希望能帮助那些准备进行类似升级的开发者。
写在前面
为什么不直接升级到webpack5.x?
这个问题问得很好,我最开始也是直接一键升级到最新版,一启动,直接报各种版本不匹配(哭),由于项目比较大引入的依赖太多,实在是难以推进,所以退而求其次,先升级到webpack4.x,后面再想办法往上升!!!
升级前的准备
在进行任何重大的项目改动之前,备份总是第一位的。请首先确保你的项目已经被推送到Git仓库,这样即使升级失败,也能轻松回退到之前的版本。
升级开始
我原本的webpack版本是^3.6.0,本次升级为:^4.46.0
我本次升级涉及到的文件目录如下:
1、更新package.json中Webpack和相关依赖
以下是我本次升级新增以及更新的依赖版本:
依赖 | 原版本 | 升级后版本 | 类型 |
babel-polyfill | -- | ^6.26.0 | 新增 |
babel-plugin-transform-es2015-modules-commonjs | -- | ^6.26.2 | 新增 |
html-webpack-plugin | ^2.30.1 | ^4.3.0 | 升级 |
mini-css-extract-plugin | -- | 0.9.0 | 新增 |
vue-loader | ^13.3.0 | ^15.7.0 | 升级 |
webpack | ^3.6.0 | ^4.46.0 | 升级 |
webpack-cli | -- | 3.3.12 | 新增 |
webpack-dev-server | ^2.11.5 | ^3.11.1 | 升级 |
2、安装依赖
npm install
如果由于项目中其他依赖冲突产生的报错及安装失败,可以加上--legacy-peer-deps
npm install --legacy-peer-deps
3、 逐步修改Webpack配置
.babelrc文件:
// 修改前
{"presets": [["env", {"modules": false,"targets": {"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]}}],"stage-2"],"plugins": ["transform-vue-jsx", "transform-runtime"]
}// 修改后
{"presets": [["env", {"modules": false,"targets": {"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]}}],"stage-2"],"plugins": ["transform-vue-jsx", "transform-runtime","transform-es2015-modules-commonjs"]
}
build/utils.js文件:
// 删除或注释以下代码
const ExtractTextPlugin = require('extract-text-webpack-plugin')// 改为
const MiniCssExtractPlugin = require('mini-css-extract-plugin')// 删除或注释以下代码if (options.extract) {return ExtractTextPlugin.extract({use: loaders,fallback: 'vue-style-loader',// https://www.cnblogs.com/luosiding/p/8268837.htmlpublicPath: '../../'})} else {return ['vue-style-loader'].concat(loaders)}// 改为
return [options.extract ? MiniCssExtractPlugin.loader : 'vue-style-loader'].concat(loaders)
build/webpack.base.conf.js文件:
// 删除或注释以下代码
const vueLoaderConfig = require('./vue-loader.conf')
// 改为
const { VueLoaderPlugin } = require('vue-loader')// module.exports中:
entry: {app: './src/main.js'},
// 改为:entry: {app: ['babel-polyfill', './src/main.js']},// 新增:
mode:process.env.NODE_ENV,plugins: [new VueLoaderPlugin()],// 删掉optionsmodule: {rules: [//...(config.dev.useEslint ? [createLintingRule()] : []),{test: /\.vue$/,loader: 'vue-loader',options: vueLoaderConfig //删除该条},
build/webpack.dev.conf.js文件:
如果项目中使用了jquery才改:
plugins: [
...,new webpack.ProvidePlugin({$: 'jquery'})
]
build/webpack.prod.conf.js文件:
// 删掉或注释以下代码
const ExtractTextPlugin = require('extract-text-webpack-plugin')
// 改为
const MiniCssExtractPlugin = require('mini-css-extract-plugin')// 删掉或注释以下代码new UglifyJsPlugin({uglifyOptions: {compress: {warnings: false}},sourceMap: config.build.productionSourceMap,parallel: true}),new ExtractTextPlugin({filename: utils.assetsPath('css/[name].[contenthash].css'),// Setting the following option to `false` will not extract CSS from codesplit chunks.// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110allChunks: true,}),// 改为:new MiniCssExtractPlugin({filename: utils.assetsPath('css/[name].[contenthash].css'),ignoreOrder: true}),// 删掉或注释以下代码:chunksSortMode: 'dependency'
// 改为:
chunksSortMode: 'none'// 删掉或注释以下代码:new webpack.optimize.CommonsChunkPlugin({name: 'vendor',minChunks (module) {// any required modules inside node_modules are extracted to vendorreturn (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 updatednew 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-chunknew webpack.optimize.CommonsChunkPlugin({name: 'app',async: 'vendor-async',children: true,minChunks: 3}),// 改为:optimization: {minimizer: [new UglifyJsPlugin({parallel: true, // 开启多进程压缩。uglifyOptions: {output: { comments: false },compress: {warnings: false,drop_debugger: true, // 是否清除debuggerdrop_console: true // 是否清除所有console// pure_funcs: ['console.log','console.info','console.warn','console.debug'] //drop_console 设置false,需要特殊清除的}},sourceMap: config.build.productionSourceMap})],splitChunks: {chunks: 'async',minSize: 30000, // 大于30KB才单独分离成chunkmaxAsyncRequests: 5,maxInitialRequests: 3,name: true,cacheGroups: {default: {priority: -20,reuseExistingChunk: true},// 生成 vendors.js,vendors: {name: 'vendors',test: /[\\/]node_modules[\\/]/,priority: 10,chunks: 'all'// enforce: true},common: {name: 'common',chunks: 'all',minChunks: 2,minSize: 0,maxInitialRequests: 5 // The default limit is too small to showcase the effect}}},// 生成 manifest.jsruntimeChunk: {name: 'manifest'}}
总结
如果改完可以正常启动,那么恭喜你!升级成功了!!如果不幸失败了,那么。。。很抱歉没有给你提供有效的帮助(哭),你也可以留言或私信,我看看有没有遇到类似报错。希望我的经验能帮助你在升级Vue2项目到Webpack 4的过程中少走弯路!