Zava’s journey to Vue.js

Yuriy Khamzyaev
Oct 10, 2019 · 8 min read
Image for post
Image for post

It’s not unusual for engineering departments to find themselves deeply invested in old technology, all too aware that there are beautiful, shinier, newer frameworks or languages out there. Technologies that could make impossible or hard things — possible and manageable.

This scenario is usually solved by a complete rewrite. A start-over in an entirely different framework, language and technology stack. While this can solve the problem, it requires a lot of effort, can lead to delays in development work and have unpredictable ETAs. Moreover, this situation can repeat itself with rewrites required every 5–6 years when new front-end technologies appear.

This was something we wanted to avoid at Zava. We wanted to find an approach that would enable us to continuously and discreetly switch from one tech stack to another. Something that made it easier to predict when new technology would be implemented and remove the usual risk associated with implementing and investing in something new.

Why did we start looking for a new front-end framework?

However, at the end of 2018, almost all of our front-end was powered by Angular.js including customer-facing and internal applications as well as lots of supplementary tools and components. It wasn’t possible to make necessary changes at the speed required because our apps used outdated approaches and accumulated problems like:

  • Big bundle sizes, no code splitting was used
  • No shared components were used between apps. Only CSS styles were shared
  • Code wasn’t modularised enough. Global objects were being referenced everywhere

As a framework, Angular.js is no longer supported for development. Its creators have abandoned it, no new libraries are being created, and the job market of Angular.js developers is slowly shrinking. It was clear we needed to try something new.

The review process — which framework should we use?

To organise our migration to new technology we created a forum for front-end devs from independent teams — the “next-web” guild. Everyone was asked to propose a framework of their choice. The main candidates were:

  • Angular
  • React.js
  • Vue.js

Angular

No one in the team was comfortable with TypeScript of RxJS library, so it seemed too risky to invest not only in a new framework but also into these new technologies as well.

React.js

  • Major internet companies support it: Facebook, Airbnb, Netflix.
  • Rich ecosystem of open-source libraries, discussions, courses.
  • Multiple libraries exist for the same problem — for example for state management Redux, Mobx, Unstated. You can pick up the most appropriate for your problem.

But on the other side of the coin there were some disadvantages:

  • Fast turnover of libraries, it’s harder to keep up with the fast pace of changes (state management, routing libraries).
  • Often React libraries try to be super generic so that they can be used both for web and native development, react-router v3 was good for web, but react-router 4 was focused on both web and native platforms, so at first, it had a lot of things missing for the web.
  • Has a steeper learning curve, developers have to understand new concepts of functional programming, such as higher-order components.

React has its specific use cases, it is especially well-suited for making apps, but it shouldn’t be used for everything, for example, for static pages.

Vue.js

  • Focused mostly on solving problems arising in the web.
  • Easy to get started.
  • Has default libraries for main problems which are supported by core contributors: vue-router, vuex for state management, vue-server-renderer, vue-cli.
  • More natural understanding by backend developers who had limited exposure to front-end before, because Vue uses plain templates.
  • It’s opinionated in a good sense. It has ready patterns for solving many problems, fewer choices to make.
  • It is aligned with the web-components standard.

Still, Vue is younger technology than React, and it has its downsides:

  • Less choice of open source libraries, fewer people that have experience in Vue.
  • Fewer companies are using Vue, though this seems to be changing — for example, Apple and Netflix have recently started using Vue.
  • Not so many examples of large applications written with Vue, with the notable exception of Gitlab. For Gitlab transition to Vue went quite well and supported their scale.

The Decision

JSX vs. HTML templates. React implies using JSX to write templates and while it’s also possible with Vue, it’s more idiomatic to use HTML templates in Vue. So we had a choice between using HTML and JSX templates.

Opinionated vs non-opinionated framework. This choice has a great impact on the codebase. Choosing a less opinionated solution provides lots of freedom and flexibility to architect your app. However it comes with a cost — teams need to spend more time on investigations and in numerous meetings to align and agree on the approach. In contrast, with an opinionated solution, a lot of decisions are already made by the framework authors so aligning the team requires way less effort.

We voted on which approach our team members preferred:

Image for post
Image for post

Final voting was about choosing between Vue and React:

Image for post
Image for post

Vue won voting with a slight advantage. After the voting, no one questioned the outcome because the decision was owned by the team.

First steps

However, initial development progress stalled for a while, as we didn’t have a clear migration path for big applications. The situation would remain like this until we figured out how to write apps in Vue whilst still delivering value to the business:

  • Using Micro Frontends — an approach with splitting frontend application into smaller and independent “micro” applications. It’s great for migrating old apps incrementally.
  • Creating new apps completely in Vue — this was easier if the app was completely independent of old apps.

For micro front-ends, we chose two approaches:

  • Use single-spa to migrate current applications gradually. Single-spa library provides utilities to initialise and destroy app automatically depending on the active URL. Another great thing is that it allows the sharing of dependencies between micro-frontend apps.
  • Writing widget apps with Vue so that we can use it anywhere. We have just two files: script and style files which we can embed whenever we need to show the widget. In the future, we would want to make web components out of the widget to isolate its styles and make it more robust.

We can show how we use both of these approaches in our Assessment application. The primary purpose of our Assessment app is to obtain information regarding a patient’s medical condition, including all details that allow us to fulfil the order safely. It consists of these sections:

  • Questionnaire to make a diagnosis for a patient
  • Product selection
  • Login and registration
  • Delivery
  • Payment

This is how it looks (displaying a questionnaire section):

Image for post
Image for post

Our general approach is to use single-spa library to split the Assessment application into independent micro apps and migrate them independently. Single-spa provides a handful of utilities for loading/destroying new apps depending on the active URL. It also allows sharing dependencies between them.

However, in some cases, we need more flexibility, so we decided to extract the Questionnaires section into a widget. This way we can reuse it in any context (e.g. an app for a user account, static pages), just by loading script and style files from the CDN. On top of that we have the additional benefit of being able to deploy widget independently from all applications where it’s located.

This hybrid approach looks like this:

Image for post
Image for post

We’re already using single-spa in other customer-facing applications, and it’s greatly simplified our migration process.

We’ve also switched from WebDriverIO to Cypress for end-to-end testing for the widget and started testing widget in different contexts: standalone widget, widget inside other applications.

What we’ve learned so far?

  • It’s hard to organise work on shared components if you have cross-functional independent teams.
  • White-labelling is particularly hard, as there are varying degrees of customisation you can provide. Narrowing down the requirements helped to get the ball rolling.
  • With Vue and Jest testing became way easier that with Angular.js

Looking back at the last nine months, we can say that the crucial part in migrating to a new tech stack is organising it incrementally. This makes it easier to convince stakeholders and to implement step-by-step migration without disrupting business processes.

As the next steps we’re planning to:

  • Join efforts of independent teams to merge multiple components implementations in the shared library
  • Add visual regression testing of shared components
  • Adopt standard tools — tracking, A/B testing for use with Vue apps
  • Start using server-side rendering of Vue components

This will allow us to easily scale Zava for multiple brands, have a consistent design and implementation and quickly experiment with ideas.

Thanks to Ramón García, Gemma Goode and Mati Shomrat for help and reviewing this post, Michele Stara for wonderful cover image and everyone from Zava Engineering team for ideas.

Zava

Delivering digital healthcare that is instant, convenient…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store