Upgrading Vue 2 to Vue 3: The Good, The Bad, and the Ugly

Introduction

The news is out: Vue 2 is coming to an end. End-of-life for Vue 2 is planned for December 31, 2023. If that looming date caused you to break out into a cold sweat, you are most likely not alone. The thought of having to take your well-established application and do a major upgrade to it can be unpleasant. We here at FYIN have partners with major projects that use Vue 2 and Vue 3 is a major update. The prospect of this upgrade can be a daunting task in light of busy schedules and heavy workloads. Imagine your other tasks disappearing into the ether so that you can focus solely on Vue updates. It’s a nice thought but not a realistic one. This is where we can help. 

Why?

System update 3d Vector concept. 3d glass morphism gear for mobile app design.

Why or why not? To upgrade or not? While there’s probably no need to turn it into a philosophical debate, it’s worth noting that not all upgrades involve a simple “click and done” process. Most upgrades involve time and resources. Software upgrades are like maintaining a house. You could choose not to do it but it will cause more effort and cost in the long run. 

So why upgrade Vue? Vue 2 will receive eighteen (18) months of long-term support starting July 1, 2022. There will be necessary bug fixes and security updates during that time but all updates will cease after that. Since we do not have a crystal ball to see the future, who knows what might happen? Over time, support for third-party packages for Vue 2 will decline and eventually end as well.

In addition to the loss of maintenance support, there are improvements in Vue 3 that make upgrading a good idea:

  • Composition API: A new API for writing more concise and reusable components.

  • TypeScript support: First-class support for TypeScript, making it easier to write type-safe code.

  • Performance improvements: Vue 3 is significantly faster than Vue 2, thanks to a number of optimizations.

  • New features: Vue 3 also includes a number of new features, such as Fragment and Teleport.

https://v3-migration.vuejs.org/migration-build.html#installation

  1. Upgrade tooling if applicable.

  • If using custom webpack setup: Upgrade vue-loader to ^16.0.0.

  • If using vue-cli: upgrade to the latest @vue/cli-service with vue upgrade

  • (Alternative) migrate to Vite + vite-plugin-vue2. [Example commit]

  1. In package.json, update vue to 3.1, install @vue/compat of the same version, and replace vue-template-compiler (if present) with @vue/compiler-sfc:

package json

"dependencies": { -  "vue": "^2.6.12", +  "vue": "^3.1.0", +  "@vue/compat": "^3.1.0"    ... }, "devDependencies": { -  "vue-template-compiler": "^2.6.12" +  "@vue/compiler-sfc": "^3.1.0"    ... }

  1. In the build setup, alias vue to @vue/compat and enable compat mode via Vue compiler options.

Example Configs

vue-cli

// vue.config.js module.exports = {   chainWebpack: (config) => {     config.resolve.alias.set('vue', '@vue/compat')     config.module       .rule('vue')       .use('vue-loader')       .tap((options) => {         return {           ...options,           compilerOptions: {             compatConfig: {               MODE: 2             }           }         }       })   } }

 

Plain webpack

// webpack.config.js module.exports = {   resolve: {     alias: {       vue: '@vue/compat'     }   },   module: {     rules: [       {         test: /\.vue$/,         loader: 'vue-loader',         options: {           compilerOptions: {             compatConfig: {               MODE: 2             }           }         }       }     ]   } }

 

Vite

// vite.config.js export default {   resolve: {     alias: {       vue: '@vue/compat'     }   },   plugins: [     vue({       template: {         compilerOptions: {           compatConfig: {             MODE: 2           }         }       }     })   ] }

  1. If you are using TypeScript, you will also need to modify Vue's typing to expose the default export (which is no longer present in Vue 3) by adding a *.d.ts file with the following:

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 } }

The Gotcha!

Fixing settings, cogwheels, adjusting sliders. Person changing, developing, modifying, repairing system.

Upgrading Vue is not that difficult. The “gotcha” in the process is with third-party packages. The size of the site as well as the type and number of third-party NPM packages will determine the complexity of a Vue upgrade as well as the level of effort needed to upgrade. While the Vue team has done a great job in making it easy to migrate to Vue 3, the same cannot be said for all of those “wonderful” NPM packages.

While it is not comprehensive, it is recommended that you review the “Know Limitations” document on the Vue 3 migration site:

https://v3-migration.vuejs.org/migration-build.html#known-limitations

Notably, Vuetify can be a lot of effort to upgrade. Vuetify 3 has many breaking changes and unfortunately, there is no equivalent tool like the Vue 3 migration build. If you are using Vuetify 2 in your application, be prepared to do a lot of view refactoring during your Vue 3 upgrade.  

https://vuetifyjs.com/en/getting-started/upgrade-guide/ 

Review your package and make sure that they have Vue 3 versions and what the process will be to upgrade them to work with Vue 3.

Conclusion

Upgrading development frameworks is not always easy, but not doing it can become a time-consuming and costly effort in the long run. While regular maintenance may seem costly now to both budget and timelines, it is ultimately easier and cheaper to do now than waiting and having to make a massive effort to squeeze multiple years of work into a compressed timeline. You don’t want to save money in the short term only to spend more later. 

Let's Talk Shop

Need to upgrade Vue 2 to Vue 3? Not sure and want some advice? We're here to help.