I am doing some research on how to split a huge single-page-monolith into a micro-frontend architecture.
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.
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
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?
single-spa is a javascript framework for front-end microservices and can be implemented with all three popular frameworks/libraries such as Angular, React and Vue. js. It can lazy load the applications based on the need and You can check out their website for more information.
Micro frontends are a new pattern where web application UIs (front ends) are composed from semi-independent fragments that can be built by different teams using different technologies. Micro-frontend architectures resemble back-end architectures where back ends are composed from semi-independent microservices.
Module Federation allows loading separately compiled and deployed code (like micro frontends or plugins) into an application. This plugin makes Module Federation work together with Angular and the CLI.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With