vue2.7升級指南
vue2.7升級指南
之前的架子使用的是 panjiachen,使用的是 vue2.6.14,現在升級為 vue2.7.x
升級@vue/cli
vue upgrade
這里推薦使用 vue upgrade
命令自動升級
# 確保安裝全局 @vue/cli
$ npm install -g @vue/cli
$ vue upgradeWARN There are uncommitted changes in the current repository, it's recommended to commit or stash them first.
? Still proceed? Yes
? Gathering package information...Name Installed Wanted Latest Command to upgrade@vue/cli-service 4.4.4 4.4.4 5.0.8 vue upgrade @vue/cli-service@vue/cli-plugin-babel 4.4.4 4.4.4 5.0.8 vue upgrade @vue/cli-plugin-babel@vue/cli-plugin-eslint 4.4.4 4.4.4 5.0.8 vue upgrade @vue/cli-plugin-eslint
? Continue to upgrade these plugins? Yes
Upgrading @vue/cli-service from 4.4.4 to 5.0.8
🚀 Running migrator of @vue/cli-service
? Successfully invoked migrator for plugin: @vue/cli-service
Upgrading @vue/cli-plugin-babel from 4.4.4 to 5.0.8
🚀 Running migrator of @vue/cli-plugin-babel
? Successfully invoked migrator for plugin: @vue/cli-plugin-babel
Upgrading @vue/cli-plugin-eslint from 4.4.4 to 5.0.8
🚀 Running migrator of @vue/cli-plugin-eslint
📦 Installing additional dependencies...
? Successfully invoked migrator for plugin: @vue/cli-plugin-eslinteslint ESLint upgraded from v5. to v7
這里發現有 3 個文件發生了修改,babel.config.js
實際上沒有發生改變
vue upgrade 幫你做的事情
如果不這么做,需要進行如下操作,十分麻煩。如果依賴沖突,可以使用 npm i --legacy-peer-deps
進行安裝
-
將
@vue/cli-xxx
依賴升級至最新版本范圍,這里我打算使用 vue-cli5- v4 升級至
~4.5.18
- v5 升級至
~5.0.6
$ npm i @vue/cli-plugin-babel@5 @vue/cli-plugin-eslint@5 @vue/cli-service@5 -D- "@vue/cli-plugin-babel": "4.4.4" - "@vue/cli-plugin-eslint": "4.4.4" - "@vue/cli-service": "4.4.4" + "@vue/cli-plugin-babel": "^5.0.8" + "@vue/cli-plugin-eslint": "^5.0.8" + "@vue/cli-service": "^5.0.8"
- v4 升級至
-
升級
eslint
,并安裝@babel/core
$ npm i eslint@7 eslint-plugin-vue@8 -D - "eslint": "6.7.2" - "eslint-plugin-vue": "6.2.2" + "eslint": "^7.32.0" + "eslint-plugin-vue": "^8.0.3" + "@babel/core": "^7.12.16"
還需要升級
eslint
對應的 parser,安裝@babel/eslint-parse
$ npm un babel-eslint $ npm i @babel/eslint-parser@7 @babel/core@7- "babel-eslint": "10.1.0" + "@babel/eslint-parser": "^7.12.16"
之后修改
.eslintrc.js
對應的 parsemodule.exports = {parserOptions: {parser: '@babel/eslint-parser'} }
解決@vue/cli報錯
升級完 vue-cli 需要解決一下 vue-cli 語法升級報的錯,需要修改 vue.config.js
-
之前使用 JSDoc 的形式可以改為
defineConfig
幫手函數/*** @type {import('@vue/cli-service').ProjectOptions}*/ module.exports = { }// 需要改為如下內容 const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ })
-
devtool
更加嚴格,填寫之前去 webpack 官網查一下:https://www.webpackjs.com/configuration/devtool/
# 報錯信息 ValidationError: Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.- configuration.devtool should match pattern "^(inline-|hidden-|eval-)?(nosources-)?(cheap-(module-)?)?source-map$".BREAKING CHANGE since webpack 5: The devtool option is more strict. Please strictly follow the order of the keywords in the pattern
比如:你寫
cheap-module-eval-source-map
是不合法的,需要改為eval-cheap-module-source-map
config.when(process.env.NODE_ENV === 'development', config => config.devtool('eval-cheap-module-source-map'))
-
devServer 有很多配置發生了變化,比如:
{devServer: {hotOnly: trueoverlay: {warnings: false,errors: true},before: require('./mock/mock-server.js'),disableHostCheck: true} }// 需要改為 {devServer: {hot: "only",onBeforeSetupMiddleware: require('./mock/mock-server.js'),client: {overlay: {warnings: false,errors: true}},allowedHosts: "all"} }
可以參考:https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md
比如這里報錯 ‘disableHostCheck’ 是未知屬性,就可以在這個文檔中查一下,看看它改成了什么
# 報錯信息 ValidationError: Invalid options object. Dev Server has been initialized using an optionsobject that does not match the API schema.- options has an unknown property 'disableHostCheck'. 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? }
-
svg 報錯問題
ERROR in ./src/pages/xx/icons/svg/wechat.svg Module build failed (from ./node_modules/svg-sprite-loader/lib/loader.js): Error: Cannot find module 'webpack/lib/RuleSet'
升級
svg-sprite-loader
即可$ npm i svg-sprite-loader@6 - "svg-sprite-loader": "4.1.3" + "svg-sprite-loader": "^6.0.11"
-
path 模塊找不到問題
Module not found: Error: Can't resolve 'path' in 'E:\xx\src\pages\xx\components\layout\components\Sidebar'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: { "path": require.resolve("path-browserify") }'- install 'path-browserify' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "path": false }
webpack5 不再自動填充 Node 核心模塊,如果你想使用的話需要從 npm 安裝兼容的模塊并自己包含它們。其它模塊同理
https://webpack.js.org/configuration/resolve/#resolvefallback
$ npm i path-browserify -D + "path-browserify": "^1.0.1"
引入即可。不過這里我嘗試用鏈式調用的寫法去寫,沒生效
{configureWebpack: {resolve: {fallback: {path: require.resolve('path-browserify')}}} }
-
npm i 報錯
可以使用
npm i --legacy-peer-deps
解決npm ERR! Fix the upstream dependency conflict, or retry npm ERR! this command with --force, or --legacy-peer-deps npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
不過也要統一把對應插件的版本全部升級一遍。比如:
copy-webpack-plugin
、html-webpack-plugin
-
copy-webpack-plugin@5
對應webpack@4
里面的配置寫法稍有變更,照著提示改下即可
-
html-webpack-plugin@3
對應webpack@4
-
script-ext-html-webpack-plugin@2
對應webpack@4
內聯 runtime 的代碼就直接刪掉了
$ npm i copy-webpack-plugin@11 -D - "copy-webpack-plugin": "5.0.5" + "copy-webpack-plugin": "^11.0.0"$ npm i html-webpack-plugin@5 - "html-webpack-plugin": "3.2.0" + "html-webpack-plugin": "^5.5.3"$ npm un script-ext-html-webpack-plugin - "script-ext-html-webpack-plugin": "2.1.3"
-
-
css 全局變量
需要把
pretendData
改為additionalData
{css: {loaderOptions: {sass: {additionalData: '@import "~@/styles/variables.scss";'}}} }
-
多入口 plugin 異常問題(沒有使用多入口的可以跳過這個問題)
# 報錯信息 Error: Cannot call .tap() on a plugin that has not yet been defined. Call plugin('preload')
可以參考:https://cli.vuejs.org/zh/config/#pages 這里面的提示
如果你試圖修改
html-webpack-plugin
和preload-webpack-plugin
插件的選項,可以使用vue inspect --plugins
看看都有哪些 plugin$ npm i @vue/preload-webpack-plugin -D + "@vue/preload-webpack-plugin": "^2.0.0"
之前直接使用 tap 連接即可,現在需要指定 plugin
Object.keys(pages).forEach(name => {config.plugin(`preload-${name}`).tap(() => [{rel: 'preload',fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],include: 'initial'}])config.plugins.delete(`prefetch-${name}`) })// 需要改為如下內容 Object.keys(pages).forEach(name => {config.plugin(`preload-${name}`).use(require('@vue/preload-webpack-plugin'), [{rel: 'preload',fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],include: 'initial'}])config.plugins.delete(`prefetch-${name}`) })
-
sass 警告問題
Deprecation Warning: Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0. Recommendation: math.div($--tooltip-arrow-size, 2) or calc($--tooltip-arrow-size / 2) More info and automated migrator: https://sass-lang.com/d/slash-div? 89 │ margin-bottom: #{$--tooltip-arrow-size / 2};│ ^^^^^^^^^^^^^^^^^^^^^^^^^?node_modules\element-ui\packages\theme-chalk\src\popper.scss 89:22 @contentnode_modules\element-ui\packages\theme-chalk\src\mixins\mixins.scss 74:5 b()node_modules\element-ui\packages\theme-chalk\src\popper.scss 4:1 @importnode_modules\element-ui\packages\theme-chalk\src\select-dropdown.scss 3:9 @importnode_modules\element-ui\packages\theme-chalk\src\select.scss 4:9 @importnode_modules\element-ui\packages\theme-chalk\src\pagination.scss 4:9 @importnode_modules\element-ui\packages\theme-chalk\src\index.scss 2:9 @importstdin 25:9 root stylesheet Warning: 33 repetitive deprecation warnings omitted.
升級 sass 版本 和 sass-loader 版本,注意里面 deep 寫法也需要改變,需要改為
::v-deep
$ npm i sass sass-loader@12 - "sass": "1.26.2" - "sass-loader": "8.0.2" + "sass": "^1.44.0" + "sass-loader": "^12.6.0"
這個一定要解決
warning in ./src/pages/xx/components/layout/components/Sidebar/index.vue?vue&type=script&lang=js& export 'default' (imported as 'variables') was not found in '@/styles/variables.scss' (module has no exports)
因為頁面里用到了
variables.scss
導出的變量,新版如果沒有進行處理會導致頁面阻塞- 需要將
variables.scss
名改為variables.module.scss
- 需要將
-
打包兩次問題,Vue-cli5 以后你會發現會打包兩次
vue2 項目升級到 vue3 之后 npm run build 執行兩遍打包
- Building legacy bundle for production... - Building module bundle for production...
主要是因為要兼容瀏覽器導致,可以在
.browserslistrc
里配置not dead
和not ie 11
> 1% last 2 versions not dead not ie 11
再進行打包就只會打包一次
- Building for production...
-
eslint 可能會有一些警告或報錯
- 可以先整體修復一遍,之后再解決一下沒辦法修復的
{"scripts": {"lint": "eslint . --ext .html,.vue,.js,.jsx --fix"} }
升級vue
-
升級
vue
至 2.7。同時可以將vue-template-compiler
從依賴中移除如果你在使用
@vue/test-utils
,那么vue-template-compiler
需要保留$ npm i vue@2.7 $ npm un vue-template-compiler- "vue": "2.6.10", - "vue-template-compiler": "^2.6.11", + "vue": "^2.7.14",
-
這里我沒有使用 vite,很多和 vite 相關的就沒必要處理了