Smooth Upgrades to Vue 3 Using the Migration Build

2 v 3 — Vue updgrade graphic

Vue 3 introduces some compelling new features, but also many breaking changes. The question is, how do you get there? Fortunately, the Vue.js team has recently released the Migration Build, which makes it possible (and easy) to make a smooth transition from v2 to v3.

This post assumes basic familiarity with Vue.js v2.x.

Vue 3, the Progressive JavaScript Framework, introduces some compelling new features:

  • The Composition API introduces a new, more flexible, TypeScript-friendly syntax for defining components (albeit at the cost of a bit more complexity);
  • Significant reported performance improvements over v2, in addition to reduced bundle sizes as a result of global API tree-shaking;
  • An updated reactivity system based on Proxy, which eliminates a common source of bugs when using arrays and objects;
  • Vite, a new set of frontend tooling for a lightning-fast development experience;
  • Fragments, allowing multiple root elements in Vue components;
  • [Experimental] The <script setup> syntax, for a nicer syntax when committing fully to the Composition API in a component;
  • [Experimental] State-driven CSS Variables, allowing data bindings within the <style> section of components;
  • [Experimental] The Suspense component, which makes it much easier to write asynchronous components that display a "loading" UI while they’re processing.

It’s a valuable upgrade in terms of performance and developer productivity. The question is, how do you get there? While v3 does not make any drastic API changes compared to v2, the changes it does make are numerous, and as of the initial v3.0 release, these breaking changes would need to be migrated in one fell swoop.

Fortunately, the Vue.js team has recently released the Migration Build, which makes it possible (and easy) to make a smooth transition from v2 to v3.

Vue 3 Compatibility Caveats


There are a few reasons why you might not be ready to introduce Vue 3 into your project:

Make sure that your project’s dependencies and supported platforms allow for the upgrade. If not, keep in mind that some v3 features are being backported to v2, such as the Composition API.
 

What is the Migration Build?


The Migration Build is an alternative build of Vue 3 which provides configurable Vue 2 compatible behaviour. It enables a gradual migration process:

  1. Swap out your vue v2.x dependency with @vue/compat;
  2. Configure the Migration Build to be fully v2-compatible;
  3. One breaking change at a time, configure the Migration Build to be v3-compatible for that feature, and fix any occurrences of it in your project;
  4. Swap out @vue/compat for vue 3.x once your project is fully migrated to v3.

The amount of overhead introduced by this compability build is relatively small, so it’s even possible to make releases while in the intermediate state between v2 and v3 compatibility. The Vue.js team has guaranteed to maintain this migration build at least until the end of 2021, but after that no firm commitments have been made, so if you’ve made the decision to upgrade, it’s best not to delay for too long.
 

Using the Migration Build


The first step of course is installation, and the official installation documentation is easy to follow.

Configuration is straightforward, and can be done both globally or on a per-component basis. A global configuration can be created with a snippet like this in the root of the application:

import { configureCompat } from 'vue';

configureCompat({
   // By default, each feature is v2 compatible. Set individual features to
   // false like so to switch them to v3 compatibility.
   GLOBAL_MOUNT: false,
});

Once installed and configured, your v3-upgraded application should, for the most part, function just the same as before. From here, the Feature Reference in the official documentation is where you’ll find a list of the individual v3 features to enable in order to migrate your project. They’re separated into four "Compatibility Types", in a sensible order for sequentially working through them. These are:

  • Incompatible: These are a handful of features for which the Migration Build does not provide v2 compatibility; it only provides warnings for easy identification of code that requires migrating. If any of these warnings appear, they’ll need to be addressed upfront.
  • Partially Compatible With Caveats: These features don’t behave 100% identically to v2 in compatibility mode, but as long as you aren’t relying on private Vue APIs, this is unlikely to be a problem.
  • Compat Only (No Warning): These features are v2-compatible but do not issue a warning to identify code which needs migrating. Curently this is only the TRANSITION_CLASSES feature, instances of which are easy to find via text search.
  • Fully Compatible: These features ought to behave identically to v2.

For each feature, simply migrate each v2-style occurrence, then set FEATURE_NAME: false in your compatibility configuration in order to switch the Vue build to use the v3 behavior.

For example, consider the INSTANCE_SCOPED_SLOTS compatibility feature. The Feature Reference provides a link to the relevant migration documentation, which tells you that this.$scopedSlots has been removed due to the unification of normal/scoped slots in v3. The "Migration Strategy" section at the bottom describes simple steps to take: replace occurrences of this.$scopedSlots with this.$slots, and then replace occurrences of this.$slots.mySlot with this.$slots.mySlot(). This can easily be done in a few moments using find-and-replace, after which INSTANCE_SCOPED_SLOTS: false can be set in your compatibility configuration, one step closer to v3 compatibility.
 

Recap


Overall, the Migration Build allows for a gradual development process of migration that looks something like this:

  1. Replace your project’s Vue 2.x dependency with the Vue 3 Migration Build
    1. Install and configure it for full v2 compatibility
    2. Migrate the handful of features marked "Incompatible" in order to restore your application to full function
    3. Peform some smoke testing to ensure that everything is back to normal
    4. Merge this change into your mainline development branch
  2. Continue regular development as required, potentially even making releases along the way
  3. While numUnmigratedFeatures > 0,
    1. Use the Feature Reference documentation to identify the next compatibility feature to disable
    2. Switch to v3 behavior by setting FEATURE_NAME: false in your Migration Build configuration
    3. Use the documentation link in the Feature Reference to jump to relevant information about how to migrate to v3
    4. Migrate all occurrences in your project
    5. Merge this change into your mainline development branch (which ensures that any subsequent commits must use the v3 behavior)

This easy and comprehensive upgrade process, combined with how infrequently Vue makes breaking API changes to begin with, arguably makes it best-in-class among JavaScript UI framworks in terms of long-term maintenance (although React is introducing a similar upgrade process for the upcoming version 18). It’s one of the reasons why we recommend Vue.

Paul Hendry

Paul Hendry

Paul Hendry has been developing robust software solutions since 2011, mainly for Web and desktop. His interests include Web development, security, and tools/techniques for catching bugs before they happen.

Tags:

Creative Commons License

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.