Refactor legacy code, Vue that was easy!

VueDay

Verona

12/04/2019

Nicolò (Nico) Maria Mezzopera

@DonNicoJs

Who am I

Nicolò (Nico) Maria Mezzopera

  • Senior Frontend Developer @ Pulilab

  • More than 8 years of experience

  • Vue2Leaflet maintainer

  • vue-xlsx author

TLDR

  • Refactor legacy code is not always an impossible task
  • Migrating your codebase to Vue can be approached in many ways
  • Having Vue and another framework coexist is not a nightmare
  • We can rely on established and well known patterns

Manager / PM / PO:

We are here to go from eww to:

Strategies

  • One Vue per day

  • VueOrchestrator

One Vue per day

  • Identify new 'standalone' features
  • Leverage Vue small footprint to create web components
  • Use the web components until the time is ripe to rewrite the section/page in Vue

The VueOrchestrator

  • Rewrite routing in vue-router
  • Rewrite data storage in Vuex (optional)
  • Use the clear hooks coming from vue-router/vue lifecylce to mount the previous codebase components and feed them data via Vuex

One Vue per day

  • Floating elements
  • Shared complex UI components
  • Modals

Perfect use cases:

...keeps the refactor away

One Vue per day

  • Limited time to allocate to refactor
  • Few / one developer involved
  • Is easy to keep the UI homogenous without third party libraries

When

One Vue per day

  • Spin up a new VueJs codebase
  • Create your reusable components
  • Compile them as WebComponents
  • Deploy them to npm or similar registry
  • Consume your web components in your main codebase

How

One Vue per day

  • Web components require polyfills on older browsers
  • Limitation due to shadow dom issue on styling
  • Split codebase
  • They are not a solution to our problem but a very good starting point

Cons

One Vue per day

Example: Contact me Dot

One Vue per day

 Why: Contact me Dot

  • Standalone functionality

  • Reusable across different web apps

  • Show off 'VueJs'

One Vue per day

 Internals: Contact me Dot

One Vue per day

 Integration: Contact me Dot

<script src="//unpkg.com/vue-django-feedback/dist/packaged/vue-django-feedback.js"></script>
<vue-django-feedback
  meta="{{vm.meta}}"
  name="{{vm.user.profile.name}}"
  email="{{vm.user.profile.email}}"
  auth-token="{{vm.token}}"
  submit-button-text="{{'SUBMIT' | translate }}"
  global-error-warning="{{'ERROR' | translate }}"
  name-label="{{'Your name' | translate }}"
  email-label="{{'Your email' | translate }}"
  subject-label="{{'Subject' | translate }}"
  message-label="{{'Message / Question' | translate }}"
>
  <span vue-slot="header-text">
    <translate>
        Ask our experts!
    </translate>
  </span>

</vue-django-feedback>

One Vue per day

One Vue per day

Why was it a success? 

  • It was the precursor of a bigger refactor
  • Even if it was in the codebase being refactored we still use the original code
  • Developing it in Vue was faster than doing it in AngularJs

VueOrchestrator

  • Major refactor needed
  • Totally new pages need to be added
  • Lots of ready and battle-proven UI components

Perfect use cases:

VueOrchestrator

  • The codebase does not follow any standardised/opinionated approach
  • Frequent bug due to async issues/callback hell
  • A bigger chunk of time can be allocated to the refactor

When

VueOrchestrator

  • Spin up a new codebase based on VueCli / Nuxt
  • Rewrite all the routes in vue-router
  • Optionally rewrite/create state manager in Vuex
  • Create wrapping components
  • Import old code in each page

How

VueOrchestrator

  • A good amount of time is needed for this approach
  • Results may not be 'immediately' visible
  • Vuex state management may be a bit quirky to adapt to older code 'style'

Cons

VueOrchestrator

Case Study: DigitalHealthAtlas

VueOrchestrator

Why: DigitalHealthAtlas

  • The project started years ago as an AngularJs website
  • As the software kept evolving refactor came as a necessity
  • When a big piece of the software was added we managed to refactor huge chunks to Vue with a minimal overhead

VueOrchestrator

Internals: DigitalHealthAtlas

  • Nuxt Js in Universal mode
  • AngularJs / Vue Integration
  • Vuex as a global state manager
  • 150+ components 
  • 10+ store modules
  • ~100k lines of code (JS / JSON / VUE)

VueOrchestrator

Integration: DigitalHealthAtlas

Legacy component in SSR Page:

 

<template>
  <div class="angularjs">
    <div id="thematicjs" />
    <!-- placeholder to avoid a flash of content -->
    <a
      v-if="!initialised"
      class="HeaderBtn ToolkitBtn"
    >
      <translate>Toolkit</translate>
    </a>
  </div>
</template>
<script>
export default {
  data () {
    return {
      initialised: false
    };
  },
  async mounted () {
    await this.$nextTick();
    const { factory } = await import('@/angular/Thematic/thematicFactory');
    factory(0, 0, this.$gettext('MAPS Toolkit'), 'HeaderBtn', this.$gettext('Toolkit'));
    this.initialised = true;
  }
};
</script>

VueOrchestrator

Integration: DigitalHealthAtlas

AngularJs Page

<template>
  <div class="angularjs">
    <div id="cmsjs" />
  </div>
</template>

<script>

export default {
  async mounted () {
    const { cmsFactory } = await import('@/angular/Cms/cmsFactory');
    cmsFactory();
  }
};
</script>

VueOrchestrator

Why was it a success

  • Got rid of a huge piece of legacy code
  • Completed a refactor in the timeframe of developing a new feature
  • Better understood why VueJs architecture is amazing for integration with other frameworks

Legacy code as Vue component

  • Mounted hook: the holy grail
  • Placeholder DOM elements
  • SSR compatibility

Key parts:

Legacy code as Vue component

Let's check the code: https://codesandbox.io/s/j3246j07kw

Legacy page as Vue component

  • Factory function to bootstrap legacy code (AngularJs)
  • Dom placeholder element
  • Appropriate loaders
  • A bit of DOM manipulation

Key parts:

Legacy page as vue component

Special thanks to
my Wife and this wonderful fellas:

Walter Tommasi

@walter_tommasi

Dobromir Hristov

@d_m_hristov

András Takács

@paragonhex

Find me at

DonNicoJs

@DonNicoJs

donnico

DonNico

Thank you!

Refactor Legacy Code to Vue

By don_nico

Refactor Legacy Code to Vue

Strategies, tips and examples on how to convert legacy codebase to Vue.js and being able to preserve the old working code in some areas of your website. Coexistence between legacy code and Vue.js code can be achieved in a stable and reliable way opening up a path to a gradual rewrite.

  • 1,466