Vue 2 reaches EOL, upgrade to Vue 3 now
Tags: vue, upgradevue
Published: 2024-01-24 20:11:41

Vue 2 has reached its end of life on December 31, 2023, It's been more than 3 years since Vue 3 was available, but still, there are a lot of Vue Js applications that are running in Vue 2. In this article, I will demonstrate two different approaches to upgrading the Vue Js application. 



## Approach 1: Follow the Vue Js upgrade guide

Vue Js Team has provided the [upgrade guide](https://v3-migration.vuejs.org/) to migrate from Vue 2 to Vue 3. The documentation has also listed all the [breaking changes](https://v3-migration.vuejs.org/breaking-changes/), which you may need to consider while upgrading your application. Besides that, you also need to consider all the dependencies and its upgrade guide. But even after you consider all the factors, there will be a lot of work to do. But there is a solution [Migration Build](https://v3-migration.vuejs.org/migration-build.html).



### Migration Build

Migration build or `@vue/compat` is a package that provides compatibility of your current Vue 2 application to run with Vue 3. This package provides the same APIs as Vue 2 and runs in Vue 2 mode by default so that the same application runs in Vue 3 but in compatibility Vue 2 mode. This feature helps to write new code in Vue 3 and change a component one by one in the long run. Another feature of this package is that you can turn on or turn off a single feature, which means you start with full compatibility mode and migrate one by one turning the migrated features off and finally removing the compatibility mode. The basic example with [Vite](https://vitejs.dev/) would look like:

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

### Example: v-model compat mode

In 2.x, `v-model` passes the `value` as a prop and emits an `input` event. This concept can be presented as:

``` vue
<BaseInput v-model="model"/>
<!-- is equivalent to -->
<BaseInput :value="model" @input="model=$event"/>
```



But in 3.x version, the `value` props of `v-model` is changed to `modelValue`, and `input` is changed to `update:modelValue`.  This concept can be presented as:

```vue
<BaseInput v-model="model"/>
<!-- is equivalent to -->
<BaseInput :modelValue="model" @update:modelValue="model=$event"/>
```

So to work with the Vue 2 Version of code in Vue 3 as well, we can simply enable the `COMPONENT_V_MODEL` migration build flag.

```js
compilerOptions: {
    compatConfig: {
        MODE: 3,
        COMPONENT_V_MODEL: true,    
    }
}
```



### Compat mode Limitation

NOT all the features and APIs of Vue 2 are supported by `@vue/compat`, there are some features that are not supported even by Migration build mode, they have also listed the [Limitations](https://v3-migration.vuejs.org/migration-build.html#known-limitations) in details. One of my experiences was with the [vee-validate](https://github.com/logaretm/vee-validate) library. We were solely depending on the `vee-validate` version 2.x library to validate input on the frontend side,  this library was using some internal APIs (VDOM and VNode API) to make things work, However, those internal APIs are removed in Vue 3 and not even supported by compact mode as well, which means this library never gonna upgrade to 3.x version, resulted that **[we never can do upgrade our Vue 2 application to Vue 3](https://github.com/logaretm/vee-validate/issues/4379)**. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tg6sm9xzhsdz4gxb3i1t.png)

### Approach 2: Separate a new Vue project

In this approach, instead of migrating the old code-base into Vue 3, a new Vue project will be created in a new directory, let say `assets`. Basically, it would be completely new Vue project, inside `assets` directory, that would be it's own `package.json` files, it's own `index.html`, it's own `node_modules`, everything new. The benefits of this approach is that you don't need to consider any breaking change, it doesn't interfere the existing system, however, you can use the **components from the root projects**.  The folder structure would look like, Please go through a source code for this demo [App](https://github.com/bedus-creation/vue-3-migration): 

```markdown
root
│   package.json    
│   node_modules
│   vite.config.js
└───src <!-- Vue 2 Application -->
│   │   App.vue 
│   │   main.js
│   │   index.html
└───src-vue-3 <!-- Vue 3 Application -->
│   │   package.json
│   │   node_modules
│   │   index.html
│   │   main.js
│   │   vite.config.js
```

### Routing 

Routing is little bit tricky here, your Vue 2 application is serving for the root route `http::127.0.0.1:8080`, and Vue 3 application will be served on some path let's say `http::127.0.0.1:8080/vue-3`, which means `vue-3` path will be root for this Vue 3 application. The one limitation of this is that you can't define multiple immediate routes path from root domain, i.e, you can't define `http::127.0.0.1:8080/vue-3` and `http::127.0.0.1:8080/vue-3-another` for the Vue 3 application unless you explicitly define a `nginx` rule for it.



### Conclusion

In this article, I have discussed two different approach to migrate your Vue application from version 2 to Version 3, For many of us, the 1st approach doesn't work because of various reasons, that's where the second approach gives us a way to write all new code in Vue 3, where as leaving the existing code in Vue 2. Another solution would be to get help from paid [Nerver Ending Support](https://v2.vuejs.org/lts/), in which they are offering never ending support for Vue 2 (Non Promotional Link). If none of these solution works for you, you can stay at Vue 2 as long as you want, End of life doesn't mean It will stop working from tomorrow, It just means there will be no active development, and no any more new features, and no security fix, otherwise, it would work forever, like it's working now.