Slaying the UI AngularJS Monolith Using Micro Frontends Architecture
A Micro Frontend Approach to a Framework Agnostic Modular UI Architecture
A brief journey into the fast-changing web development world…
Over the last decade, AngularJS has been something of the “new kid on the block”, replacing many of the weaknesses that came with jQuery-based web engineering solutions. Many enterprises were extremely happy building their cutting-edge web portals with AngularJS, and with the exponential growth of web businesses, AngularJS made many developers’ lives easier.
Everyone was happy in the web development world, but this happiness didn’t last long.
(Note: In this blog, AngularJS will be referred to as AngularJS and Angular 2 and above will be referred to as Angular. Angular was a major step ahead from AngularJS in terms of code reusability, performance, code organization, modularity, structure, evolved dependency management, etc. In short, Angular’s component-based architecture and cancellable asynchronous operation support, has changed underlying structure with a considerable learning curve to upgrade to)
Newer, more disruptive front end frameworks began to take over the web development world, plunging AngularJS into the pile of legacy software that was seen as holding businesses back. But replacing AngularJS would be no easy task. With faster growth, the complexity of AngularJS-based projects had also increased, with large enterprise codebases often spanning across multiple teams.
The result — a large monolithic AngularJS beast disguised as a front end application that had no dearth of performance and deployment bottlenecks. Among the several disadvantages that a monolithic app like this can cause, some key challenges enterprises face are:
- Tech architecture that can’t keep up with business growth: As applications grow, so does the features that teams need to support. With multiple teams contributing to a monolithic application, development and release coordination is a nightmare.
- Impeded innovation: Newer frameworks and libraries like Angular 2, React, Vue, etc offer considerable performance improvements and innovations in the front end space. However, the onerous task of upgrading a monolithic application and/or making it interoperate with these new frameworks and libraries often can’t be done without compromising the ability to ship new features at existing release rates.
- Attracting and retaining top talent: Who wants to work in an outdated framework that’s seen as diminishing one’s marketable skills? Thus employee motivation can take a hit when engineering teams are forced to solve problems that don’t add much value to their technological skill set, leading to employee churn.
A viable solution to overcoming all these challenges is to move to a modular front end architecture style called micro frontends. Through this architecture, one can help future proof the disruption and risks caused by the ever-changing web technology landscape, while also staying ahead of the curve in leveraging these technologies.
To put it in very simple terms, micro frontends is the equivalent of microservices for the front end world.
The Micro Frontends Approach
A micro frontends approach splits the front end code that loads in the browser into multiple independent web applications. These are capable of being managed by different teams and allow for framework agnosticism (apps and features being built in Vue, Angular, React).
Figure 2 illustrates a framework agnostic micro frontends architecture for a single page application.
Benefits to Micro Frontends Architecture
The key advantages of a micro frontends architecture over a monolith are:
- Gives teams their release autonomy and time back: By breaking features from the monolith into separate micro frontends, teams enjoy increased autonomy and flexibility when releasing products/features. No longer are teams who aren’t releasing required to stay up late on release calls trying to regression test other teams’ changes in production. What a relief, right!
- Keeps engineers happy: Not having to rely on the entire codebase reduces dependencies and scope, enabling teams to onboard and deliver quickly. This creates room for time spent innovating without fear of breaking other teams’ features
- Results in a scalable, better-performing web app: A loosely coupled architecture with established global standards makes it easier to add new features or spin up teams when needed. Since each app is fragmented into its own micro frontend, if a single feature (one micro frontend) on an enterprise app isn’t loading fast, it won’t affect the performance of the entire application. It also makes it possible for certain parts of a webpage to load faster, allowing users to interact with the page before all features are loaded or needed.
Challenges to Micro Frontends Architecture
As all good things come with a challenge, there are several challenges to implementing a micro frontends architecture:
- Rollout strategy: A major implementation consideration is deciding if one should convert their monolithic application to a micro frontend using a big bang or phased approach.
- Effective testing strategy: While a monolith creates an all-teams-on-hands approach to releases, micro frontends enable only contributing teams to take part in a given release. This approach requires that teams implement best-in-class regression testing practices to make sure broken features are not released to customers.
- Prepping the legacy application for the upgrade: An existing monolithic application may be on a close-to-archaic framework (say AngularJS 1.3). A significant amount of effort and time may be required to make it upgrade-ready, for which the application should be at least an Angular 2 and above.
- Governance: Teams in the organization may be pulled in multiple directions in terms of organizational and technology strategy, resulting in poor change management.
- Legacy frontend frameworks: With frameworks and newer libraries being released at an exponential rate, the ability to create interoperable UI components between frameworks requires building reusable foundational elements. This is time-consuming as well.
- Speed to market vs optimized tech: Continuous business growth requires the need for spawning new applications to exist with, or within, the monolith. There is a constant struggle trying to balance speed to market vs optimized tech in this scenario.
Considerations for Making Your Current Code Upgrade Friendly
The first step in beginning the upgrade journey is to make your existing AngularJS code ready to be upgraded to Angular. The following describes ways to prepare your ongoing AngularJS development requiring minimal refactoring.
- Move your project from traditional Model-View-Controller architecture to a component-based architecture. Self-contain every View in a directive.
- Configure your directive with restrict:
E, an isolate scope and controllerAs:
$ctrl. This will make your directive’s conversion to an Angular component syntax easier.
- Try to extract commonly used functionality into a service instead of having it in a controller. Reduce the use of factory and instead define your service as a service in a Typescript class.
Updating Legacy Applications
Your current legacy application may be in one of the below versions. If so, the migration path to a micro frontends architecture may take one or more of the below paths.
Version Older Than 1.5
Let’s say you already have a legacy AngularJS application. You can start building components from Angular 2 and above, making it interoperate with the existing AngularJS app so that your current features are not put on hold while the upgrade to micro frontends is completed.
How? Simple. Angular has developed the UpgradeModule that provides upgrade and downgrade providers to help accomplish this. You can bootstrap your Angular application inside your AngularJS application and have both the code bases in one repository, letting the components interoperate. NOTE — stay tuned for the next blog on how to do this!
In this way, you can remove one feature/ module out of the monolithic AngularJS application at a time, while simultaneously building newer components in Angular 2 or above. When you have finally upgraded all AngularJS components to Angular, the code can be pulled out into its own repository to be made into a micro frontend using Angular elements.
Version between 1.5 and 2
Another excellent strategy if you think most of your AngularJS directives and services are already upgrade friendly (see section on considerations, above) is the single-spa approach detailed in this article. Single-spa approach creates an adapter to make apps interoperate and be able to route between each other. This strategy works best for a big bang approach to fragmenting the monolith into micro frontends. It requires refactoring your existing monolithic parent AngularJS application to make it upgrade friendly before features can be removed to create micro frontends. Given the diversity in the complexity of monolithic applications, one could spend considerable time in becoming upgrade friendly.
Version Younger 2 (Angular 2 and above)
If you have already accomplished the amazing feat of upgrading your application from AngularJS to Angular 2, congratulations! Give yourself a pat on the back because most of the foundational work (some may call it grunt work) for achieving a framework agnostic micro frontends has been completed. Although there are multiple ways to implement micro frontends — Single-SPA meta-framework, Multiple SPAs comfortably residing at different URLs, micro frontends isolated via iFrames, Angular Elements released with Angular 6 is I think the most efficient and clean way to a framework agnostic Micro frontends.
I will be covering the pros and cons of each approach, along with a sample implementation, in my next blog — Stay tuned!
Slaying the monolithic beast is no walk in the park, a fact that’s exacerbated by the rapidly evolving web technology domain. In this article, we’ve gone into detail on the challenges faced, as well as tips and strategies to make this walk (rather, a triathlon) easier. The finish line is a micro frontends architecture that equips you to tackle disruptive web technologies or frameworks head on. I hope this article will help you reach it!
DISCLOSURE STATEMENT: These opinions are those of the author. Unless noted otherwise in this post, Capital One is not affiliated with, nor is it endorsed by, any of the companies mentioned. All trademarks and other intellectual property used or displayed are the ownership of their respective owners. This article is © 2019 Capital One.