Closed joeldenning closed 4 years ago
@joeldenning I can confirm you can have multiple platforms running together. Currently I'm working on a MicroFrontend solution myself. As Macro Frontend/ shell I'm also using angular, this eases up some handling of authentication. As Micro Frontends I have a combination Angular and AngularJS applications. For this I work with angular elements. So mounting an application for me is loading the scripts and styles and adding the custom element. One thing I should mention is that I currently don't share or reuse any framework code, every MicroFrontend is bundled with its framework. This is done to allow Micro Frontends to have different versions of the framework
To decrease the memory consumption, I was looking for some ways to destroy/dispose my client. I do this by raising an event and destroying the Micro Frontend when the unmount event is raised. This code is in my case added in the main.ts file of the Micro Frontend, same place where I bootstrap the application using platformBrowserDynamic().bootstrapModule()
.
The only issue I currently have (and this is due the use of angular elements) is when I go back in history and my Micro Frontend was destroyed. I get an error that the injector was destroyed.
Since you have another setup here, this shouldn't be the case.
There are still some issues:
flush()
manually because destroyPlatform
is a sugar over ngModuleRefs.forEach(ngModuleRef => ngModuleRef.destroy())
, where it keeps references to all bootstrapped modules in the current platformrouter.dispose()
was added because ngModuleRef.destroy()
was not enough and in some situations the non-deterministic behavior of the router was manifested@arturovt, In my case I'm using the v9 version of angular, and in this case I can confirm the dispose()
is called from the onDestroy()
methode in the router
. I checked this by adding debugger to verify they got called. I'll try to check if this is also the case when I just destroy the ÀppModule
I also checked with 9 Angular and dispose is called, but we're talking about previous versions too.
What versions of Angular does this work for? We're about to release single-spa-angular@4, which will only work in angular 9 (and maybe 8). This approach is less hacky than what we currently have - should we switch to it in single-spa-angular@4?
After discussing this with Artur, I am closing this. The reason is that destroying the entire Angular platform would disallow sharing a platform between microfrontends. Sharing a platform is important for performance, since that means that @angular/core
, @angular/common
, etc only have to be downloaded once in the browser, instead of once per microfrontend.
See https://github.com/me-12/single-spa-angular2/commit/f03cc7cc26d1f04e10db6f60453bc652504cf8b3#commitcomment-38483962 which suggests using destroyPlatform for unmounting angular applications.
I've expressed doubt that this would work when multiple Angular applications share the same instance of Angular, and therefore share a platform. However, if I'm wrong about that, this might be a good alternative to our workarounds for Angular Router bugs that are shown below:
https://github.com/single-spa/single-spa-angular/blob/6a7d48741d54e2a451987da17875bf3da9f365f4/src/src/single-spa-angular.ts#L128-L130
@kristofdegrave originally suggested this. Let's verify whether destroying the platform applies only to a single Angular app versus all mounted Angular apps.