Migrating a 1000 Class Components App to Vue 3

Rate this content
Bookmark

Vue 3 is amazing, but a lot of us are still stuck on a Vue 2 monolith. Some of us are stuck even more due to technology choices made before Vue 3 was even on the roadmap. Let's outline the process of migrating a large project to Vue 3 and Vite. Techniques we can employ to get some benefits sooner, process we can apply to get things done more quickly. Things we can do to get it done eventually.

This talk has been presented at Vue.js London 2023, check out the latest edition of this Tech Conference.

FAQ

The primary goal of Bagel Solutions' migration project is to switch all components to the Composition API, replace Vuex with Pinia, have both the app and storybook running on Vite, and switch from Jest to Vitest.

The main challenges include dealing with the large codebase, specifically the migration of class components to the Composition API, and handling Vuex state management transitions. Additionally, integrating these changes with minimal disruption to ongoing product development poses a significant challenge.

Bagel Solutions employs a strategy where one engineer converts two components in a two-week sprint, with each component conversion time-boxed to two hours. If a component takes longer, it is put on hold. This incremental approach helps manage complexity and avoid disrupting ongoing development.

Components are selected based on alignment with product development roadmaps to ensure that upcoming features use modern code. Additionally, components related to specific parts of the product or those interacting with the same Vuex modules are prioritized to streamline the migration process.

The benefits include improved type safety, reduced code complexity and boilerplate, fewer bugs, and enhanced performance in feature development. The migration also facilitates a better understanding of the codebase, leading to further optimizations and documentation improvements.

Nikola Begedin
Nikola Begedin
28 min
15 May, 2023

Comments

Sign in or register to post your comment.

Video Summary and Transcription

The Talk discusses the migration of a large frontend view application from Vue 2 to Vue 3. The strategy involves converting components to the Composition API, switching from Vuex to Pinea, and overcoming challenges with Vite configuration. The migration process includes selecting components based on the product roadmap, improving type safety, and reducing boilerplate. The results of the migration include improved type checking, faster tests, and a safer codebase.

1. Introduction to Bagel Solutions and V7 Migration

Short description:

Hi, everyone. My name is Nikola, and I own a sole propriety called Bagel Solutions. I've been working with V7 on their machine learning platform, which has evolved into a full AI machine learning end-to-end system. Currently, I'm focused on frontend development and involved in migrating a huge frontend view application from view 2 to view 3. This talk shares our experience, knowledge, and strategy in this process. V7 is a massive front-end monolith with 360,000 lines of code, presenting unique challenges. It includes typical single-page application features as well as whimsical and Photoshop-like parts. We have about a thousand components, but a significant portion will be deleted due to a large subsystem rewrite.

Hi, everyone. My name is Nikola, and I own a sole propriety called Bagel Solutions, because Bagel is my nickname. And for the past four years or so, I've been working with V7 on their machine learning platform. It started out as computer vision, but it became a lot more. So now it's sort of like a full AI machine learning end-to-end thing.

And I started as a backend developer, but I am now, currently, for the past year or so, working focused on the frontend. And for the past couple of months, we've been involved in migrating their huge frontend view application from view 2 to view 3. We're not done yet, but this talk is sort of about that process. So what this talk isn't, is a success story. Again, we're not done yet. It's still a work in progress. It's not a brag on how fast we did it in any way, shape, or form, because again, we're not done yet. And it's also not really a how-to, because we are doing some things specific to our project that work for us. It might not work for you. It might work, but no guarantee. What it is, is sort of a sharing of the experience we have with this, the knowledge we attained, and the strategy we used. And again, it's probably not going to be fully applicable to your case. But hopefully, it's at least going to be interesting.

So what is v7? Basically, it's one huge front-end monolith. 360,000 lines of code, more or less. And this is just counting TypeScript, not anything else. There are parts that look like your typical single-page application, data management, account management. But they do have problems that they need to deal with, that your typical single-page application doesn't have, like rendering lists of cards of hundreds of thousands of items, or things like that. There are parts that look kind of whimsical. This is our workflow editor, where you basically drag different DOM elements on top of a canvas, connect them with arrows, stuff like that. And there are also parts that kind of work and look like Photoshop. So this is our annotation UI, where you use different tools to draw different kinds of annotations on top of a canvas, which renders an image or a video or some other visual thing. We have about a thousand components in the project. But to be fair, we are in the middle, or near the end of a large rewrite of a pretty big subsystem. So I estimate that about 20% of those components are probably due to be deleted.

2. Migration Strategy and Goals

Short description:

We initially decided to use Vue class components due to a lack of front-end engineers and our familiarity with classes. However, migrating to Vue 3 poses challenges because class components don't run in Vite or Vue 3. Despite potential support for class components in the future, we are switching to the Composition API as a new standard. Our migration goals include switching all components to the Composition API, switching from UX to Binia, running both our app and storybook on Vite, and switching Jest to Vitest. To avoid disruptions and bugs, we adopted a strategy where one engineer converts two components in a sprint, with each conversion timeboxed to two hours. Additionally, any new code added must use the Composition API.

Now, we do reserve the right to keep some of them for specific reasons, but I'm going to get into that later. Technologically speaking, we are fully using TypeScript. We are using VUEX, and it has become quite loaded with time. We have a dozen or so modules. They don't really feel well-designed anymore, because we've been a startup for a good period so we've been, like, iteratively adding to it without an amazing sense of direction. You know, startups make mistakes.

Because we are using... Well, first, we decided to use Vue class components. This was very early in the product development cycle, three and a half years or so, years ago or so, and we decided to go with that because, first of all, we didn't really have many front-end engineers. A lot of us were full-stack and classes are something we were kind of more familiar with. It seemed like the way to go back then, and at that time it also seemed like a way, an approach that has better TypeScript support because of the class decorators and the Vue X class decorators, which we also use as a library. But yeah. That was a decision made back then.

For testing, we, of course, used Jest with Vue test utils, and we do have a storybook setup, which we use as a component catalog, but not within the context of writing tests or anything like that. So clearly, for migrating 3D3, the number one problem is the fact that we use class components. That means there's more work to migrate a component than it would be with options API, and that means that right off the bat, we can't really start off with Vite config to the front-end build in Vite because class components don't really run in Vite or in Vue 3. Now, right now, there are, as far as I know, some PRs being reviewed for the Vue class components and Vue X Class libraries, potentially even a release candidate or something like that, where this support will be added. So it might be that by the time we're done with migration, it will also be possible to run class components in Vite, but we are still switching to Composition API just because this is a new standard and we prefer to use the standard rather than a third-party alternative. Well, we do now.

So our list of goals to consider this migration done is to switch all the components to Composition API, at least those that we're keeping, and maybe a few more, and again, I'll get into that a bit later, switch from UX to Binia, because that's the new standard, have both our app and storybook run on Vite, and have Jest switch to Vitest, meaning it also uses the same Vite configuration, which is a big advantage with Vitest or Jest.

So we need a strategy for this, and very early on we decided that a single big effort for us is a bad idea. We can't be doing one major push of just migrating, migrating, migrating until we're done, and then move on to something else. First of all, our team is reasonably big now, we have about 30 engineers, and even with that size it's still gonna take weeks, probably, to migrate all those components, especially because we'll be stepping on each other's toes. We are guaranteed to create bugs this way, there's just too much code being changed for that not to happen. And there will be way too many delays in our product work, so yeah, we're just not okay with that. To improve our process, we decided it needs to be something that gives us benefits as we go, and not when we're done, and it needs to be as non-disruptive as possible.

So the basic approach we went with is to have one engineer convert two components in a sprint, and our sprint is two weeks, for us, and this conversion of a single component is timeboxed to two hours. That means that if it looks like it's gonna take more than two hours, that ticket is immediately put on hold and we grab the next one. The reasoning is, as we get experience doing these conversions, we get to wrap up in speed, maybe change the rules to pick more components, and then we get to revisit those tickets that we put on hold, to see, maybe, it's gonna be faster this time because we know more. And then, as part of this whole effort, there's the additional rule that any new code that we write, any new component that we add to the codebase, needs to be Composition API, So no more, like no introduction of additional class components to the codebase.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Vite: Rethinking Frontend Tooling
JSNation Live 2021JSNation Live 2021
31 min
Vite: Rethinking Frontend Tooling
Top Content
Vite is a next-generation build tool that leverages native ES modules for improved performance. It eliminates the need for bundling and improves hot module replacement. Vite provides an opinionated default configuration while still allowing advanced customization through plugins. It is framework agnostic and can be used for React and other applications. Vite is being adopted by Next.js and Create React App, and integration with Nuxt 3 offers significant speed improvements.
Everything Beyond State Management in Stores with Pinia
Vue.js London Live 2021Vue.js London Live 2021
34 min
Everything Beyond State Management in Stores with Pinia
Top Content
State management is not limited to complex applications and transitioning to a store offers significant benefits. Pinia is a centralized state management solution compatible with Vue 2 and Vue 3, providing advanced devtools support and extensibility with plugins. The core API of Pinia is similar to Vuex, but with a less verbose version of stores and powerful plugins. Pinia allows for easy state inspection, error handling, and testing. It is recommended to create one file per store for better organization and Pinia offers a more efficient performance compared to V-rex.
Welcome to Nuxt 3
Vue.js London Live 2021Vue.js London Live 2021
29 min
Welcome to Nuxt 3
Top Content
Nux3 has made significant improvements in performance, output optimization, and serverless support. Nuxt Bridge brings the Nitro engine for enhanced performance and easier transition between Nuxt 2 and Nuxt Read. Nuxt 3 supports Webpack 5, Bytes, and Vue 3. NextLab has developed brand new websites using Docus technology. Nuxt.js is recommended for building apps faster and simpler, and Nuxt 2 should be used before migrating to Nuxt 3 for stability. DOCUS is a new project that combines Nuxt with additional features like content modules and an admin panel.
One Year Into Vue 3
Vue.js London Live 2021Vue.js London Live 2021
20 min
One Year Into Vue 3
Top Content
Vue 3 has seen significant adoption and improvements in performance, bundle size, architecture, and TypeScript integration. The ecosystem around Vue 3 is catching up, with new tools and frameworks being developed. The Vue.js.org documentation is undergoing a complete overhaul. PNIA is emerging as the go-to state management solution for Vue 3. The options API and composition API are both viable options in Vue 3, with the choice depending on factors such as complexity and familiarity with TypeScript. Vue 3 continues to support CDN installation and is recommended for new projects.
Utilising Rust from Vue with WebAssembly
Vue.js London Live 2021Vue.js London Live 2021
8 min
Utilising Rust from Vue with WebAssembly
Top Content
In this Talk, the speaker demonstrates how to use Rust with WebAssembly in a Vue.js project. They explain that WebAssembly is a binary format that allows for high-performance code and less memory usage in the browser. The speaker shows how to build a Rust example using the WasmPack tool and integrate it into a Vue template. They also demonstrate how to call Rust code from a Vue component and deploy the resulting package to npm for easy sharing and consumption.
Vue: Feature Updates
Vue.js London 2023Vue.js London 2023
44 min
Vue: Feature Updates
Top Content
The Talk discusses the recent feature updates in Vue 3.3, focusing on script setup and TypeScript support. It covers improvements in defining props using imported types and complex types support. The introduction of generic components and reworked signatures for defined components provides more flexibility and better type support. Other features include automatic inference of runtime props, improved define emits and defined slots, and experimental features like reactive props destructure and define model. The Talk also mentions future plans for Vue, including stabilizing suspense and enhancing computer invalidations.

Workshops on related topic

Vue3: Modern Frontend App Development
Vue.js London Live 2021Vue.js London Live 2021
169 min
Vue3: Modern Frontend App Development
Top Content
Featured WorkshopFree
Mikhail Kuznetcov
Mikhail Kuznetcov
The Vue3 has been released in mid-2020. Besides many improvements and optimizations, the main feature of Vue3 brings is the Composition API – a new way to write and reuse reactive code. Let's learn more about how to use Composition API efficiently.

Besides core Vue3 features we'll explain examples of how to use popular libraries with Vue3.

Table of contents:
- Introduction to Vue3
- Composition API
- Core libraries
- Vue3 ecosystem

Prerequisites:
IDE of choice (Inellij or VSC) installed
Nodejs + NPM
Using Nitro – Building an App with the Latest Nuxt Rendering Engine
Vue.js London Live 2021Vue.js London Live 2021
117 min
Using Nitro – Building an App with the Latest Nuxt Rendering Engine
Top Content
Workshop
Daniel Roe
Daniel Roe
We'll build a Nuxt project together from scratch using Nitro, the new Nuxt rendering engine, and Nuxt Bridge. We'll explore some of the ways that you can use and deploy Nitro, whilst building a application together with some of the real-world constraints you'd face when deploying an app for your enterprise. Along the way, fire your questions at me and I'll do my best to answer them.
Monitoring 101 for React Developers
React Summit US 2023React Summit US 2023
107 min
Monitoring 101 for React Developers
Top Content
WorkshopFree
Lazar Nikolov
Sarah Guthals
2 authors
If finding errors in your frontend project is like searching for a needle in a code haystack, then Sentry error monitoring can be your metal detector. Learn the basics of error monitoring with Sentry. Whether you are running a React, Angular, Vue, or just “vanilla” JavaScript, see how Sentry can help you find the who, what, when and where behind errors in your frontend project. 
Workshop level: Intermediate
Going on an adventure with Nuxt 3, Motion UI and Azure
JSNation 2022JSNation 2022
141 min
Going on an adventure with Nuxt 3, Motion UI and Azure
WorkshopFree
Melanie de Leeuw
Melanie de Leeuw
We love easily created and deployed web applications! So, let’s see what a very current tech stack like Nuxt 3, Motion UI and Azure Static Web Apps can do for us. It could very well be a golden trio in modern day web development. Or it could be a fire pit of bugs and errors. Either way it will be a learning adventure for us all. Nuxt 3 has been released just a few months ago, and we cannot wait any longer to explore its new features like its acceptance of Vue 3 and the Nitro Engine. We add a bit of pizzazz to our application with the Sass library Motion UI, because static design is out, and animations are in again.Our driving power of the stack will be Azure. Azure static web apps are new, close to production and a nifty and quick way for developers to deploy their websites. So of course, we must try this out.With some sprinkled Azure Functions on top, we will explore what web development in 2022 can do.
TresJS create 3D experiences declaratively with Vue Components
Vue.js London 2023Vue.js London 2023
137 min
TresJS create 3D experiences declaratively with Vue Components
Workshop
Alvaro Saburido
Alvaro Saburido
- Intro 3D - Intro WebGL- ThreeJS- Why TresJS- Installation or Stackblitz setup - Core Basics- Setting up the Canvas- Scene- Camera- Adding an object- Geometries- Arguments- Props- Slots- The Loop- UseRenderLoop composable- Before and After rendering callbacks- Basic Animations- Materials- Basic Material- Normal Material- Toon Material- Lambert Material- Standard and Physical Material- Metalness, roughness - Lights- AmbientLight- DirectionalLight- PointLights- Shadows- Textures- Loading textures with useTextures- Tips and tricks- Misc- Orbit Controls- Loading models with Cientos- Debugging your scene- Performance
Building Vue forms with VeeValidate
Vue.js London Live 2021Vue.js London Live 2021
176 min
Building Vue forms with VeeValidate
Workshop
Abdelrahman Awad
Abdelrahman Awad
In this workshop, you will learn how to use vee-validate to handle form validation, manage form values and handle submissions effectively. We will start from the basics with a simple login form all the way to using the composition API and building repeatable and multistep forms.

Table of contents:
- Introduction to vee-validate
- Building a basic form with vee-validate components
- Handling validation and form submissions
- Building validatable input components with the composition API
- Field Arrays and repeatable inputs
- Building a multistep form
Prerequisites:
VSCode setup and an empty Vite + Vue project.