Discover how we migrated an AngularJS application to Angular 4. We share our step-by-step experience of migrating a financial web application.
In the life cycle of each long-lasting, enterprise-size web application there comes a time when it becomes too large to integrate innovations, add brand new features or scale efficiently anymore. Sometimes it happens because architecture has become inefficient due to project growth, or because of an out-of-date technology stack, and sometimes because of a combination of both. In such cases development teams start searching for a migration or replatforming solution for the project.
In this article we will share our step-by-step experience of migrating a huge web application for financial consultants that was developed through many years for one of our fintech clients. The application was rewritten from the old AngularJS stack to newer Angular versions with updates of the architectural approach.
Rewriting the application from scratch using a new technology stack was not a feasible solution in our case, since the project was really enormous and could take years to replicate existing functionality and make it stable enough to go alive.
Moreover, the introduction of new features and elimination of bugs are the core principles of any application life cycle, so our main constraint was to keep the application running and avoid any possible side effects for users.
A huge amount of heavy logic and calculations loaded the processes and as a result, the app started lagging more often, and sometimes even stopped replying entirely, especially in older versions of browsers.
Тhe diversity of teams working on the app definitely didn’t make code quality any better either. Sometimes the component looked like spaghetti code (some didn’t have an end). So of course, it was hard to maintain code style and best practices throughout the application. Therefore, the next requirement was to orchestrate the application in a way to resolve performance issues and prevent them in the future.
A bunch of 3d party libraries were deprecated already or they just couldn’t be updated due to the conflict with the Angular framework. That caused extra loads and performance issues.
So one more challenge was to review, analyze, and update versions of 3rd party libraries without negative impact or deleting the unused vendor scripts.
After deep investigation and analysis we created a step-by-step plan to make the AngularJS upgrade as smooth, fast and painless as possible. Our client supported our decision so it was time to get to work.
Well, let’s get started then!
How does such a process of Angular application migration and improvement usually start? Did you perhaps think that we all got together and began actively discussing ideas, scribbling charts and cutting the budget? Well, not really.
There are no silver-bullet solutions or comprehensively documented processes. A lot is determined in the long run, and colliding with pitfalls is necessary, as well as finding out pros and cons of different approaches and technologies.
That’s why, at the beginning, the architecture team came up with the decision to simulate the migration on a miniature scale. They created a small app on the good old AngularJS and started the migration process to the Angular 4 version.
The POC took approximately one month and gave us a clear vision on process optimization:
Based on the POC we came to the conclusion that a hybrid mode was best suited for our application migration. Such a combination makes the applications work together, where new functionality is written with the new Angular, and everything ‘old’ is rewritten. This root idea comes from a widely known pattern called Adapter.
With the POC as the base, we composed the roadmap with milestones that aligned strategic organization and centralized team collaboration. The roadmapping process was useful both for the development team and business leads to bring the business goals front-and-center to understand and act on. This is a kind of visual representation of a strategy as it answers the questions of what will be done, who will be involved in the work, the details of scope and resource allocation, as well as how and why certain initiatives are prioritized over others.
The next step, and one of the most important steps, is to document the application behavior and write tests for all existing user scenarios to make sure that the application is not broken and is still running correctly after migration. And proper documentation helps to align communication among teams and speed up the process of knowledge sharing.
What kind of technical documentation is needed?
Software documentation is composed of many documents and materials that accompany part of the program’s software. They might include product requirements, software development flow, standards and best practices, technical specifications, the product’s documentations etc.
The main objective of program software documentation is:
The versions of AngularJS that were used are 1.6 and 1.9, and the new one, 4.
Among the main dependencies were: AG Grid Enterprise, Momentjs and Day.js, Angular Bootstrap, Ramda and Lodash, built-in and imported select.
For a more advanced overview, here are a few numbers:
The first phase involved the infrastructure setup: we created a new app, our DevOps team set up the required pipelines, and we used one of the primary tools provided by ngUpgrade, which is called the UpgradeModule. This is a module that contains utilities for bootstrapping and managing hybrid apps.
To bootstrap a hybrid app, we first bootstrapped every Angular and AngularJS part of the app. We bootstrapped the Angular bits first and then asked the UpgradeModule to bootstrap the AngularJS bits next.
As a result, the app was running and nothing changed outside, but under the hood there is a new engine.
During the next phase we covered with types all contracts and created a proxy for every API, so that during the next changes of the API, the data remained stable.
The most common pitfalls were resolved by implementing lazy-loading for routes, fixing ui-view directives with multiple views, and upgrading resolve blocks inside views.
The next step was to transfer every route on a new router.
That’s where the long and careful work began on the migration of every component, during breaks between new features and updates.
As a result of migration, the application started running faster, achieved a huge performance boost that met performance requirements, and became more stable and secure.
The development process included creation of new features on the new Angular app, as well as migrating and refactoring old components. Migration was performed from the Angular 1.9 version, and at the time of writing, the app has successfully expanded to version 4.
Based on our experience, one of the keys to a successful upgrade is to do it incrementally, by running the two frameworks side by side in the same application, and porting AngularJS components to Angular one by one. This makes it possible to upgrade even large and complex applications without disrupting other business-critical applications, because the work can be done collaboratively and spread out over a period of time.