So.. we migrated our entire front-end to Nuxt.js

Bill K
UCARS-TECH
Published in
5 min readSep 21, 2020

Hi I’m Bill 👋 I’m a full stack software engineer at ucars.sg.

In March 2020, we decided to do an entire front-end migration to Nuxt.js and I was assigned to lead the project. I understand that a total migration is very risky and should be avoided as much as possible. However, there were many problems that we had, that a total migration seems like the best solution. I will structure this article using PAR (Problem, Action, Result) statements, in hope that it will be easier to digest.

Problems:

  • Our team inherited two Vue.js instances from an outsourced software house, one for desktop and another for mobile (you know, with the “m” subdomain, aka m.ucars.sg at the time). Due to limited resources, this is an issue because any bug fixing, feature implementation, and further design changes need to be made in two different codebases. Furthermore, we need to deal with the inconsistent UI designs, and to handle the redirections from the desktop site to the mobile site (with the user-agent thingy..)
  • The desktop Vue.js instance uses a proprietary library from the software house to interface with the back-end API. This raises significant maintainability issues, as only the uglified javascript code was provided and there was also no documentation. (technically, we can reverse engineer the library but this is almost just as much effort as migrating the entire thing, not to mention other issues such as copy-pasted codes everywhere, giant components, etc..)
  • The instances were client-side rendered (CSR) SPAs and the desktop instance’s architecture was quite unconventional (at least to me, please tell me if this is actually common as I am not that experienced with it myself). It was using Gulp + Vue.js with iframes inside the router-config file. The bigger issue also is that they were not indexable by our beloved search engine (Google) due to the nature of CSR. Just a small peek at the router code:
The inherited vue router config file. 😬

Actions:

So, we decided to migrate away from those codebases. There were a few considerations we need to take into before we proceed:

  • It was preferred to still use Vue.js (at least syntax wise), due to the lesser learning curve compared to the other front-end frameworks (at least in our opinion), hence it is easier to onboard new programmers, hence faster time to be productive, etc...
  • Based on the SEO crawlability need, we need SSR because our content is dynamically changing and pre-rendering is not enough. (right??..)

On the SSR side, I actually tried doing raw Vue.js SSR based on ssr.vuejs.org, also I tried out Nuxt.js based on the recommendation in that website. To my surprise, without the need for profiling, Nuxt.js actually felt much faster (I am not sure why to be honest). So we decided to use Nuxt.js! 🎉

“Lucky” benefits from using Nuxt.js that we did not account for:

  • The opinionated folder structure actually makes it more maintainable in my opinion. Vue-cli structure is more “malleable” I think, but it comes at a cost where usually more experienced developers are the ones to know what’s “better” to put where, otherwise there will be a need to enforce a stricter linting rule, etc. Due to resources constraints, we have more of less experienced developers in our project, the opinionated structure keeps things more consistent naturally.
  • It was relatively very easy to add metadata headers for social media sharing, due to the built-in vue-meta.
  • The old project was using element-ui and there is an easy integration with Nuxt.js, pretty neat. (Not Nuxt.js specific, just a happy accident. We were planning to build our own base UI components from scratch, but due to time constraints, we soon realized that this was not a good idea, only then I found out that the inherited codebases were using element-ui)

The migration happened in a few phases:

  1. Firstly, we want to deprecate the desktop instance first. Migration of the public facing pages took around 2 weeks.
  2. Migration of the internal pages (where users need to log in), took around 2 weeks as well. After this point we deprecate the desktop instance and redirect non-mobile traffic to the fresh Nuxt.js instance already.
  3. Making the site responsive to deprecate the old mobile instance, at the same time we are doing a re-design of almost the entire app. This step started around end of May as to stabilize the Nuxt instance first (and there were other priorities too). This also took awhile due to the simultaneous app-wide redesign, around 1 month I believe. Finally we are able to deprecate the old mobile instance.

Initially the deployment steps were done manually, where we SSH into our EC2 instances, pull the code from git, build, and run it there using pm2. Now, I already configured a staging instance, dockerized the staging and prod instances, and automatic deployment using Github Actions, AWS ECR and ECS. (Stay tuned for the upcoming article about this 😄)

Other miscellaneous things to mention:

  • The general folder structure of the components is heavily influenced by this article. (Although it is a React.js article, I love the index.js trick inside each folder and the separation of concern between the styling and the actual component.)
  • For linting we use both prettier and eslint and we mostly use the default out of the box rule, with an added comma dangle rule, nothing too fussy.
  • The first 6 minutes of this video really helps to understand SSR in SPA context, as I was pretty new with SSR as well.

TLDR; We migrated to Nuxt.js!

Results:

The migration was a massive success with about 35k-40k lines of code last time I checked. The old instances were also not too big in the beginning, thus increasing our confidence in migrating. The product is relatively stable and growing until now.

  • We managed to cut the maintenance effort significantly as now we don’t need to make changes in 2 different codebases.
  • Improved software internal quality. (Easier to add features, thus we can move faster)
  • Faster time to content due to SSR.
  • Achieving consistent UI designs between desktop and mobile is just natural at this point.
  • Most importantly, Google ranking is improved significantly. Although there is still so much work to do to improve the ranking, at least now we are “index-able”. Our search ranking as of end of June with a keyword of “used cars sg”:
Hooray we are in the first page!! 🎊

Thank you for reading my first ever Medium Story!

--

--