Angular and Micro-Frontends

H W picture H W · Dec 13, 2017 · Viewed 15.3k times · Source

I am doing some research on how to split a huge single-page-monolith into a micro-frontend architecture.

The idea:

  • the page consists of several components which would be running autonomously
  • each component is managed by one dev-team
  • each team can change, update and deploy their components without breaking components of other teams
  • each team chooses its own toolstack

The reason

To efficiently develop large applications you need to have many people working on it. However the number of developers per app/team does not scale well. Parallel development of multiple independent apps by independent teams however can be scaled arbitrarily

With this in mind it is imperative that teams can choose their own toolstack and especially perform independent version-upgrades of third party-libraries (like angular, react, jquery). If this was not the case a framework-update would need to be compatible with every single component before you could deploy it to production.

Does this work with Angular?

While independent version-upgrades are necessary, it would be reasonable to restrict the teams to a few supported frameworks (Angular, React, Vue, Polymer...) and for now I try to build a demo purely consisting of Angular-Apps.

However even though Angular 5 is supposedly a platform-framework which supports huge multi-module apps, it seems to be almost impossible to have several independent angular-apps running in the same browser window.

I managed to bootstrap several Angular-Apps (different versions, each hosted on its own server) on a single webapp by utilizing HTML-Imports. However there are several global dependencies which need to be shared between apps

  • zone.js can only be started once
  • routing requires url-changes
  • Browser-stuff like cookies, sessionstorage, etc...

There are several articles in the net on how to bootstrap multiple angular-modules but they all refer to multiple modules in the same core-app, which in turn means they all are running on the same framework-version and an update means you have to rebuild and deploy the whole monolith.

Is there any solution other than "iframes" to get multiple Angular (5) Apps running on the same Page?

Answer

bhantol picture bhantol · Feb 4, 2018

Instead of outright suggesting AGAINST this idea mainly due to separate stack requirements I will lay out the trade offs and provide some restrictions which will make this possible.

the page consists of several components which would be running autonomously

We all know this is offered out of box in Angular components with clear demarcation of inputs and output.

Small CAVEAT: When/If you pass objects for @Input and emit event objects with @Output() interacting components must agree on a defined interface upfront.

Workaround: Create another TypeScript project which just defines these artifacts. All other "component projects" would depend on a specific version of this.

each component is managed by one dev-team

Dev Teams can distribute the components just like other Angular projects in the opensource are doing. They can publish their artifacts to some npm repository. To develop attributable components I recommend you refer to Angular Material2 which may be overwhelming or you may use something like ngx-library-builder (based on Angular Team Member filipesilva/angular-quickstart-lib ) that each component team uses.

CAVEAT: Till this date angular team does not have a quick component library sharing project setup as evident in Angular CLI. But numerous developers have created some sort of library builders to fill the gap in Angular CLI.

each team can change, update and deploy their components without breaking components of other teams

Have your main project pull all the components and perform a periodic/change triggered build/deploy on some CI server. This is essentially producing AOT production builds with all the latest component releases. As an added bonus you can have some abstract e2e tests built to do some automated integration testing ensuring side effects of one component does not break other components.

CAVEAT: It will be difficult to govern how each team develops the components i.e. they are doing optimal usage and disposition of memory, CPU, and other resources. e.g. what if one team starts creating subscriptions and does not remove them. Using some static code analysis can be useful but you will not have this source code available at this time - unless they also publish their source code.

each team chooses its own toolstack

This is a complete deal breaker unless if you mean "toolstack" as in developer tools such as IDEs and some of the "devDependencies". Although certain parts of "devDependencies" of each team must have the same exact versions of angular dev kits such as compilers etc.

At the least each team must use same Angular, RxJS etc.

Most importantly care should be taken that each of the team does not bootstrap any components - only the main projects will have a bootstrap module and that will bootstrap the root component. This will help answer your zone.js issue

Does this work with Angular?

If you recognize the limitations and provide governance I suggest go for it.