vue2 老项目 webpack4 升级 5 调研
将 node 切换到项目可以启动的版本
省流:升级失败,项目本地启动无问题,build 速度提升显著,热更新速度提升显著。但是部署失败,后期有时间可继续调研!
以 crm-pc 为例,项目 node 版本为 14.0.0,如果有使用 nvm 管理 node 版本的,需要将全局 node 设置成14.0.0,并安装@vue/cli
(因为升级 vue-cli 版本默认会使用全局默认 node 版本,而不是 nvm 在当前终端设置的版本)
// 指定电脑全局默认 node 版本
nvm alias default v14.0.0
// 安装 vue-cli 工具
npm install -g @vue/cli
// 安装完可以通过一下命令确定是否安装
nvm ls
或
vue -v
安装依赖
vue-cli 提供脚本可以快速升级版本
vue upgrade
vue-cli 会给出已安装版本和最新版本列表
可以查看 npm 下载量确定5.0.8
版本可以使用,同意更新之后,就会自动下载所需依赖
看到以上提示表示已经安装成功,打开packagejson
可以看到升级了以下依赖
启动项目
webpack5 更新一些 api 改动,可以先启动项目看一下需要改什么
Error: Cannot call .tap() on a plugin that has not yet been defined. Call plugin('preload').use() first.
webpack5 已经不内置 preload 方法
解决方法:
一:修改vue.config.js原配置:
// 修改前
config.plugin('preload').tap(() => [
{
rel: 'preload',
// to ignore runtime.js
// https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
include: 'initial'
}
])
// 修改后
const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin')
config.plugin('preload').use(PreloadWebpackPlugin).tap(() => [
{
rel: 'preload',
// to ignore runtime.js
// https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
include: 'initial'
}
])
ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema. - options has an unknown property 'hotOnly'. These properties are valid: object { allowedHosts?, bonjour?, client?, compress?, devMiddleware?, headers?, historyApiFallback?, host?, hot?, http2?, https?, ipc?, liveReload?, magicHtml?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, port?, proxy?, server?, setupExitSignals?, setupMiddlewares?, static?, watchFiles?, webSocketServer? }
报错意思是Dev Server已使用与API模式不匹配的选项对象初始化,webpack5 已经更新了部分 api,参考如下修改! image
(node:65739) UnhandledPromiseRejectionWarning: TypeError: Cannot add property htmlWebpackPluginAlterChunks, object is not extensible
当webpack的版本到5.x时,html-webpack-plugin的版本需要升级到4.x才不会出现这个问题
升级版本
"html-webpack-plugin": "5.5.3"
Module not found: Error: Can't resolve 'timers' in '/Users/chenxiaoyu/Documents/crm/wkcrmjavapc/src/components/NewCom/WkForm'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to: - add a fallback 'resolve.fallback: { "timers": require.resolve("timers-browserify") }' - install 'timers-browserify' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "timers": false }
由于在webpack5中移除了nodejs核心模块的polyfill自动引入,所以需要手动引入,如果打包过程中有使用到nodejs核心模块,webpack会提示进行相应配置
解决办法:
.vue.config.js中修改配置
// 头部引入
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
configureWebpack: (config) => {
const plugins = []
plugins.push(new NodePolyfillPlugin())
}
// 或者
configureWebpack: {
plugins: [new NodePolyfillPlugin()],
}
ERROR in [eslint] .eslintrc.js: Configuration for rule "vue/max-attributes-per-line" is invalid: Value {"max":1,"allowFirstLine":false} should be number. Value {"max":1,"allowFirstLine":false} should NOT have additional properties. Value {"max":1,"allowFirstLine":false} should match some schema in anyOf.
修改办法
修改.eslintrc.js
配置,具体可参考链接
!
开启持久化缓存
module.exports = {
configureWebpack: {
name: name,
resolve: {
alias: {
'@': resolve('src')
}
},
// 开启持久化缓存:手动开启才能生成webpack5缓存目录提升打包速度
cache: {
type: 'filesystem'
},
},
}
问题记录
vue-cli 默认使用 yarn 安装,但是项目可使用的 yarn 版本未知,
方案一:
打开/Users/你的电脑名字/.vuerc
修改配置文件如下
{
"useTaobaoRegistry": false,
"packageManager": "npm"
}
此问题大概率是因为 node 版本不对导致,方法参考步骤一切换全局默认 node 版本后删除 node_modules
包重新 npm i
后运行vue upgrade
因为vue-cli 更新了 eslint 配置和校验,现在是@babel/eslint-parser 校验更加严格,如果你想要禁用该规则,可以在需要禁用的代码块前加上注释:
// eslint-disable-next-line vue/no-mutating-props
this.propsData.someProp = 'new value';
- template 标签提示Parsing error: Cannot find module '@babel/eslint-parser'
因为使用了新版@babel/eslint-parser
可能存在缓存,重启编辑器即可解决
本地启动项目正常,但是部署后白屏,控制台报下图错误
原因:升级 webpack5 后原项目使用的sass-resources-loader
插件不支持 webpack5,需要使用style-resources-loader
插件;
安装方法:直接使用vue add style-resources-loader安装 ,会提示选择预处理器,根据所需选择即可,安装完成后vue.config.js
文件会自动添加下图配置
将全局注入的 scss 文件路径添加即可
pluginOptions: {
'style-resources-loader': {
preProcessor: 'scss',
patterns: [
// 这个是绝对路径,不能使用 alias中配置的别名路径,如@表示的src
path.resolve(__dirname, './src/styles/xr-theme.module.scss'),
path.resolve(__dirname, './node_modules/element-ui/packages/theme-chalk/src/common/var.scss'),
]
}
}
此时打印 scss 变量发现,scss 变量导出对象为空,查询 webpack
modules
类型:Boolean|String|Object 默认值:undefined 启用/禁用 CSS 模块或者 ICSS 及其配置:
- undefined - 为所有匹配/.module.\w+$/i.test(filename) 与 /.icss.\w+$/i.test(filename) 正则表达式的文件启用 CSS 模块。
这里有2个坑:
- 必须让 css-loader 使用 icss 模式,否则 vars 为空对象!
- 不能让 JS import 的 scss 文件跟 additionalData 里的 @import 是同一个文件,会报错!
这个改动影响面还是太大了,我们往往并不需要让所有的 scss 都具备互操作能力。按照 css-loader | webpack 中文文档 来看,最方便的办法是将需要导出变量的文件改名为 *.module.scss 即可,Vite 也是一样的做法,这样即可使得这些文件具备导出变量的能力。
将原有 scss 文件xr-theme.scss
改名为xr-theme.module.scss
即可
chunk chunk-commons [mini-css-extract-plugin].Conflicting order. Following module has been added:
在js里css的引入顺序导致的问题,多个css的在js里的引入顺序不同,就会提示这个警告。例如,在1.js 里,引入的顺序是a.css, b.css; 在2.js里,引入顺序是b.css,a.css, 出现了这种引入顺序不同,就导致了警告。
- 在两个js里把引入顺序调成一致,就没问题了。在1.js和2.js里的引入顺序都调整成a.css, b.css 就没有那个警告了。
- vue.config.js 添加配置忽略提醒
css: {
extract: process.env.NODE_ENV === 'production' ? {
ignoreOrder: true,
} : false,
},
如下图 warning
configureWebpack:{
performance:{
// 资源(asset)是从 webpack 生成的任何文件。此选项根据单个资源体积(单位: bytes),控制 webpack 何时生成性能提示
maxEntrypointSize:process.env.NODE_ENV === 'development'? 250000 : 10000000, // 整数类型(以字节为单位)
// 入口起点表示针对指定的入口,对于所有资源,要充分利用初始加载时(initial load time)期间。此选项根据入口起点的最大体积,控制 webpack 何时生成性能提示。
maxAssetSize: process.env.NODE_ENV === 'development'? 250000 : 30000000, // 整数类型(以字节为单位)
//只给出 js 文件的性能提示
assetFilter: function(assetFilename) {
return assetFilename.endsWith('.js');
}
}
}|
生产环境登录后调整白屏,仪表盘空白,刷新白屏
script-ext-html-webpack-plugin
不支持 webpack5,暂时没有解决版本,官方推荐使用 vite。