Successfully reported this slideshow.
Your SlideShare is downloading. ×

Is it time to migrate to Vue 3?

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 74 Ad

Is it time to migrate to Vue 3?

Download to read offline

Are you eager to migrate your entire codebase to Vue 3 and composition API? Before starting the long journey away from Vue 2.6 you should consider a few intermediate steps:

- compatibility with your dependencies
- tests
- maintainability
- consider a step-by-step migration passing trough Vue 2.7
- what about the Vite/Vitest ecosystem?

Are you eager to migrate your entire codebase to Vue 3 and composition API? Before starting the long journey away from Vue 2.6 you should consider a few intermediate steps:

- compatibility with your dependencies
- tests
- maintainability
- consider a step-by-step migration passing trough Vue 2.7
- what about the Vite/Vitest ecosystem?

Advertisement
Advertisement

More Related Content

Recently uploaded (20)

Advertisement

Is it time to migrate to Vue 3?

  1. 1. Is it time to migrate to Vue.js 3.x? VUEDAY 2022 Verona, November 18th, 2022 1
  2. 2. WHO AM I Denny Biasiolli Full Stack Developer (JavaScript, Python, Go) Front End Developer UX/ UI Fingerprint Supervision Ltd Italy, Savigliano (CN) @dennybiasiolli denny.biasiolli@gmail.com www.dennybiasiolli.com 2
  3. 3. Vue.js Version Release date 2.6 February 4, 2019 3.0 September 18, 2020 3.1 June 7, 2021 3.2 August 5, 2021 3.x as new default February 7, 2022 2.7 (maintenance mode) July 1, 2022 2.x End of Life End of 2023 3
  4. 4. SEPTEMBER 18, 2020 VUE 3.0 OFFICIALLY ANNOUNCED Composition API <script setup> (experimental) no IE11 support https://blog.vuejs.org/posts/vue-3-one-piece.html 4
  5. 5. 5
  6. 6. OPTIONS API (VUE 2, VUE 3) export default { data() { return { count: 0 } }, methods: { increment() { this.count++ }, }, } <template> <button @click="increment">Count is: {{ count }}</button> </template> 6
  7. 7. COMPOSITION API IN setup() (VUE 3) <script> import { ref } from 'vue' export default { setup() { const count = ref(0) function increment() { count.value++ } return { count, increment } }, } <template> <button @click="increment">Count is: {{ count }}</button> </template> 7
  8. 8. COMPOSITION API IN setup() (Vue 2 + @vue/composition-api) import VueCompositionAPI from '@vue/composition-api' Vue.use(VueCompositionAPI) - import { ref, ... } from 'vue' + import { ref, ... } from '@vue/composition-api' 8
  9. 9. COMPOSITION API IN setup() (Vue 2 + @vue/composition-api) import VueCompositionAPI from '@vue/composition-api' Vue.use(VueCompositionAPI) - import { ref, ... } from 'vue' + import { ref, ... } from '@vue/composition-api' BROKEN TESTS 8.1
  10. 10. COMPOSITION API IN setup() (Vue 2 + @vue/composition-api) import VueCompositionAPI from '@vue/composition-api' Vue.use(VueCompositionAPI) - import { ref, ... } from 'vue' + import { ref, ... } from '@vue/composition-api' BROKEN TESTS in tests files Vue.use(VueCompositionAPI) // or localVue.use(VueCompositionAPI) 8.2
  11. 11. COMPOSITION API + SCRIPT SETUP (VUE 3) <script setup> import { ref } from 'vue' const count = ref(0) function increment() { count.value++ } </script> <template> <button @click="increment">Count is: {{ count }}</button> </template> 9
  12. 12. FEBRUARY 7, 2022 VUE 3 AS NEW DEFAULT https://blog.vuejs.org/posts/vue-3-as-the-new-default.html 10
  13. 13. POTENTIAL REQUIRED ACTIONS NPM dependency versions in package.json Use "^" to bind to a specific major version "dependencies": { - "vue": "latest", + "vue": "^2.6.14", - "vue-router": "*", + "vue-router": "^3.5.3", - "vuex": "latest" + "vuex": "^3.6.2" }, "devDependencies": { - "vue-loader": "latest", + "vue-loader": "^15.9.8", - "@vue/test-utils": "latest" + "@vue/test-utils": "^1.3.0" } 11
  14. 14. SPOILER ALERT means 2.x Starting from July 1, 2022 it auto-updates to Vue 2.7 if you don't use explicit package-lock.json or yarn.lock files to accept only patch releases "vue": "^2.6.14" - "vue": "^2.6.14" + "vue": "~2.6.14" 12
  15. 15. JULY 1, 2022 VUE 2.7 "NARUTO" RELEASED Composition API <script setup> (partial) https://blog.vuejs.org/posts/vue-2-7-naruto.html 13
  16. 16. 14
  17. 17. VUE 2.7 UPGRADE GUIDE 1. Upgrade local @vue/cli-xxx dependencies Upgrade to the latest version in your major version range (if applicable) ~4.5.18 for v4 ~5.0.6 for v5 npx @vue/cli@latest upgrade 15
  18. 18. VUE 2.7 UPGRADE GUIDE 2. Upgrade vue to ^2.7 You can also remove vue-template-compiler from the dependencies, it is no longer needed in 2.7. If you are using @vue/test-utils, you may need to keep it in the dependencies for now, but this requirement will also be lifted in a new release of test utils. Always keep vue and vue-template-compiler in sync. npm install -S vue@~2.7 npm install -D vue-template-compiler@~2.7 16
  19. 19. VUE 2.7 UPGRADE GUIDE 3. Check your package manager lockfile for version requirements If not, you will need to remove node_modules and the lockfile and perform a fresh install to ensure they are bumped to the latest version. npm ls vue-loader # should be at least ^15.10.0 npm ls vue-demi # should be at least ^0.13.1 17
  20. 20. VUE 2.7 UPGRADE GUIDE 4. Remove @vue/composition-api and update imports to vue instead npm uninstall @vue/composition-api - import VueCompositionAPI from '@vue/composition-api' - Vue.use(VueCompositionAPI) - import { ref, ... } from '@vue/composition-api' + import { ref, ... } from 'vue' 18
  21. 21. More info about Vue 2.7 upgrade https://blog.vuejs.org/posts/vue-2-7-naruto.html 19
  22. 22. USING <script setup> - <script> + <script setup> import { ref } from 'vue' - export default { - setup() { const count = ref(0) function increment() { count.value++ } - return { count, increment } - }, - } </script> 20
  23. 23. 21
  24. 24. Broken vue-router usage! npm i -S vue-router@^3.6.5 + import { useRoute, useRouter } from 'vue-router/composables' + const route = useRoute() + const router = useRouter() - this.$route + route - this.$router + router 22
  25. 25. Same for vuex $store usage? Import the store and navigate through it or migrate to pinia import store from '@/store'; store.state.propertyName store.state.moduleName.propertyName store.getters.getterName store.getters['moduleName/getterName'] store.commit(/* */) store.dispatch(/* */) 23
  26. 26. 24
  27. 27. WHAT ABOUT TESTS? 25
  28. 28. Broken tests! console.error [Vue warn]: Property or method "count" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-R console.error [Vue warn]: Property or method "increment" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-R 26
  29. 29. Broken tests! console.error [Vue warn]: Property or method "count" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-R console.error [Vue warn]: Property or method "increment" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-R @vue/vue2-jest 27.x not working with Vue 2.7 26.1
  30. 30. SEPTEMBER 15, 2022 @vue/vue2-jest 29.1 released with support for <script setup> in Vue 2.7... 27
  31. 31. SEPTEMBER 15, 2022 @vue/vue2-jest 29.1 released with support for <script setup> in Vue 2.7... ...with Jest 29 27.1
  32. 32. USING JEST DIRECTLY update jest.config.js from node_modules @vue/cli-plugin-unit-jest/presets/default/jest-preset.js update package.json test script run tests without vue-cli-service - "test:unit": "vue-cli-service test:unit", + "test:unit": "jest", npm run test:unit # or npx jest 28
  33. 33. UPGRADING JEST TO 29.X and fix deprecation warnings npm uninstall @vue/cli-plugin-unit-jest npm install -D jest-environment-jsdom jest-serializer-vue jest-transform-stub jest-watch-typeahead @vue/vue2-jest@^29 babel-jest@^29 jest@^29 - testURL: 'http://localhost/', + testEnvironmentOptions: { + url: 'http://localhost/', + }, 29
  34. 34. Components using <script setup> are closed by default Won't work anymore const spyIncrement = jest.spyOn(wrapper.vm, 'increment') defineExpose({ increment }) # not working 30
  35. 35. Components using <script setup> are closed by default Won't work anymore const spyIncrement = jest.spyOn(wrapper.vm, 'increment') defineExpose({ increment }) # not working Temporary (not suggested) workaround // FIXME: temporary workaround - const spyIncrement = jest.spyOn(wrapper.vm, 'increment') + const spyIncrement = jest.spyOn( + wrapper.vm._setupState, 'increment') 30.1
  36. 36. COMPONENT TESTING Test what a component does, not how it does it. - // FIXME: temporary workaround - const spyIncrement = jest.spyOn( - wrapper.vm._setupState, 'increment') - wrapper.find('button').trigger('click') - expect(spyIncrement).toHaveBeenCalled() + expect(wrapper.find('p').text()).toBe('Count is: 0') + await wrapper.find('button').trigger('click') + expect(wrapper.find('p').text()).toBe('Count is: 1') https://vuejs.org/guide/scaling-up/testing.html#component-testing 31
  37. 37. MIGRATION TO VUE 3 https://v3-migration.vuejs.org/ 32
  38. 38. MIGRATION TO VUE 3 New Features Breaking Changes Recommendations Migration Build https://v3-migration.vuejs.org/ 33
  39. 39. MIGRATION TO VUE 3 BREAKING CHANGES While it looks like a lot has changed, a lot of what you know and love about Vue is still the same; but we wanted to be as thorough as possible and provide detailed explanations and examples for every documented change. https://v3-migration.vuejs.org/breaking-changes/ 34
  40. 40. NEW FRAMEWORK-LEVEL RECOMMENDATIONS New versions of Router, Devtools & test utils w/ Vue 3 support Build Toolchain: Vue CLI -> Vite State Management: Vuex -> Pinia IDE Support: Vetur -> Volar ... https://v3-migration.vuejs.org/recommendations.html 35
  41. 41. EASY MIGRATIONS Devtools IDE Support: Vetur -> Volar 36
  42. 42. MANDATORY MIGRATIONS Vue Router Vuex Test utils Third party libraries (Vuetify, Quasar, ElementUI, etc...) 37
  43. 43. AVOIDABLE MIGRATIONS Vue CLI -> Vite Jest -> Vitest 38
  44. 44. MIGRATION BUILD: @vue/compat build of Vue 3 configurable Vue 2 compatible behavior runs in Vue 2 mode by default usage of changed/deprecated features will emit runtime warnings https://v3-migration.vuejs.org/migration-build.html 39
  45. 45. KNOWN LIMITATIONS dependencies that rely on Vue 2 internal APIs or undocumented behavior. usage of private properties on VNodes (Vuetify, Quasar, ElementUI, ...) IE11 support dropped Server-side rendering 40
  46. 46. MIGRATION BUILD: EXPECTATIONS aims to cover only publicly documented Vue 2 APIs and behavior if your application is large and complex, migration will likely be a challenge even with the migration build 41
  47. 47. UPGRADE WORKFLOW 1. upgrade tooling if applicable vue-cli: custom webpack setup: upgrade vue-loader to ^16 npx @vue/cli@latest upgrade 42
  48. 48. 2. update vue in package.json "dependencies": { - "vue": "~2.7", + "vue": "^3.2.39", + "@vue/compat": "^3.2.39" ... }, "devDependencies": { - "vue-template-compiler": "~2.7" } npm i -S vue@^3.2 @vue/compat@^3.2 --force npm uninstall vue-template-compiler --force 43
  49. 49. 3.1. alias vue to @vue/compat Webpack or Vite config on // vue.config.js module.exports = { // ... chainWebpack: (config) => { config.resolve.alias.set('vue', '@vue/compat') // ... } } https://v3-migration.vuejs.org/migration-build.html 44
  50. 50. 3.2. enable compat mode via Vue compiler options Webpack or Vite config on config.module .rule('vue') .use('vue-loader') .tap((options) => { return { ...options, compilerOptions: { compatConfig: { MODE: 2 } } } }) https://v3-migration.vuejs.org/migration-build.html 45
  51. 51. 4. if using TypeScript, update vue's typing declare module 'vue' { import { CompatVue } from '@vue/runtime-dom' const Vue: CompatVue export default Vue export * from '@vue/runtime-dom' const { configureCompat } = Vue export { configureCompat } } 46
  52. 52. 5. fix compile-time errors When compiler warnings are gone, you can set the compiler to Vue 3 mode compilerOptions: { compatConfig: { MODE: 3 } } 47
  53. 53. 6. Run the app 48
  54. 54. 6. Run the app the app should be able to run if no limitations mentioned above focus on fixing your own source code warnings first 49
  55. 55. 7. Update <transition> class names This feature does not have a runtime warning. Search for `.*-enter` and `.*-leave` CSS class names - .*-enter + .*-enter-from - .*-leave + .*-leave-to 50
  56. 56. 8. Update app entry to use new global mounting API - import Vue from 'vue' + import { createApp } from 'vue' import App from './App.vue' import router from './router' import store from './store' - Vue.config.productionTip = false - new Vue({ + const app = createApp({ router, store, - render: h => h(App) + ...App, - }).$mount('#app') + }) + app.mount('#app') 51
  57. 57. 9. Upgrade vuex to v4 npm i -S vuex@^4 --force https://vuex.vuejs.org/guide/migrating-to-4-0-from-3-x.html 52
  58. 58. 9. Upgrade vuex to v4 // src/store/index.js - import Vue from 'vue' - import Vuex from 'vuex' + import { createStore } from 'vuex' - Vue.use(Vuex) - export default new Vuex.Store({ + export default createStore({ - state: { - count: 0, + state() { + return { + count: 0, + }; }, // ... 53
  59. 59. 9. Upgrade vuex to v4 // src/main.js import store from './store' const app = createApp({ router, - store, ...App, }) + app.use(store) 54
  60. 60. 9. Upgrade vuex to v4 Composition API usage import { useStore } from 'vuex' const store = useStore() 55
  61. 61. 10. Upgrade vue-router to v4 npm i -S vue-router@^4 --force https://router.vuejs.org/guide/migration/index.html 56
  62. 62. 10. Upgrade vue-router to v4 // src/router/index.js - import Vue from 'vue' - import VueRouter from 'vue-router' + import { createRouter, createWebHistory } from 'vue-router' - Vue.use(Vuex) const routes = [ // ... ] - const default new VueRouter({ + export default createRouter({ - mode: 'history', - base: process.env.BASE_URL, + history: createWebHistory(process.env.BASE_URL), routes }) 57
  63. 63. 10. Upgrade vue-router to v4 // src/main.js import router from './router' const app = createApp({ - router, ...App, }) + app.use(router) 58
  64. 64. 10. Upgrade vue-router to v4 Composition API usage import { useRouter, useRoute } from 'vue-router' const router = useRouter() const route = useRoute() 59
  65. 65. 11. Pick off individual warnings (if any) Always refer to the doc. https://v3-migration.vuejs.org/ 60
  66. 66. 12. Remove the migration build and switch to Vue 3 when all warnings are fixed. Note you may not be able to do so if you still have dependencies that rely on Vue 2 behavior. npm uninstall @vue/compat --force 61
  67. 67. 62
  68. 68. BROKEN TESTS! Upgrade testing packages npm uninstall @vue/vue2-jest --force npm i -D @vue/vue3-jest@^29 --force npm i -D @vue/test-utils@^2 --force // jest.config.js transform: { - '^.+.vue$': '@vue/vue2-jest', + '^.+.vue$': '@vue/vue3-jest', https://test-utils.vuejs.org/migration/ 63
  69. 69. VUE TEST UTILS V2 CHANGES propsData is now props no more createLocalVue mocks and stubs are now in global findAll().at() removed use findAll()[] ... https://test-utils.vuejs.org/migration/ 64
  70. 70. SOLVING TEST ERRORS/WARNINGS Solution console.warn [Vue warn]: Avoid app logic that relies on enumerating keys on a component instance. The keys will be empty in production mode to avoid performance overhead. - expect(wrapper).toMatchSnapshot() + expect(wrapper.html()).toMatchSnapshot() 65
  71. 71. SOLVING TEST ERRORS/WARNINGS Solution ReferenceError: Vue is not defined > 1 | import { shallowMount } from '@vue/test-utils'; | ^ // jest.config.js testEnvironmentOptions: { customExportConditions: ["node", "node-addons"], }, https://github.com/vuejs/vue-jest/issues/479#issuecomment-1163421581 https://stackoverflow.com/a/72608494/3963422 66
  72. 72. 67
  73. 73. RECAP Vue 2.6 + @vue/composition-api Composition API (setup() only) Vue 2.6 → 2.7 Composition API <script setup> Vue 2.x → 3.x long term support for your codebase 68
  74. 74. THANK YOU! | | migrate-to-vue3 branch @dennybiasiolli blog.vuejs.org vuejs.org v3-migration.vuejs.org vuex.vuejs.org router.vuejs.org test-utils.vuejs.org github.com/dennybiasiolli/vue-migration-2-to-3 www.dennybiasiolli.com 69

×