Search code examples
cjavascriptasp.netangularwebpack-5

Loading Angular15 MicroFrontend in ASPX page with plain JavaScript


We have Angular15 app (Micro-frontend=MFE) enabled with ModuleFederationPlugin(Webpack), this app easily gets loaded in another Angular app(Host). But we would like to use the same in ASP.Net (.NET 4.0) ASPX WebForm application. Not finding any plain/vanilla JavaScript which can load MFE in classic ASPX page. Is it possible to load with pure JavaScript? Loading with IFrame is not acceptable standard for this application, hence looking at direct integration solution. Help is much appreciated.

Below is the code from webpack.config.js.

module.exports = withModuleFederationPlugin({

  name: 'ss-emr-modules',
  filename:"remoteEntry.js",
  exposes: {
    './ReferralModule': './src/app/referral-mfe/referral-mfe.module.ts',
  },

  shared: {
    ...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
  },

});

Solution

  • Here is the approach, using shadow DOM, why shadow DOM? Below block quote is an answer from https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM

    "Being able to keep the markup structure, style, and behavior hidden and separate from other code on the page so that different parts do not clash, and the code can be kept nice and clean"

    Working code is huge but trying to share core implementation here.

    1. Create post build script: generates JavaScript file having custom element extended from HTLMLElement, should reside in same location where angular main, pollyfill and runtime javascripts files are generated, below is the example code output from post build script/command[create a console app which will do this job for you, can be java, python, c#, go, rust.... ].
    class AppOneMfe extends HTMLElement {
      constructor() {
        super();
      }
      connectedCallback() {
        const shadow = this.attachShadow({ mode: "open" });
      // Add logic to replicate <angular build output>/index.html as body of this custom element
    
    1. Micro-frontend Angular app's AppModule should implement DoBootstarp
      providers: [],
     // bootstrap: [AppComponent] // Remove this line
    })
    export class AppModule implements DoBootstrap {
    ngDoBootstrap(appRef: ApplicationRef): void {
        const element = document.querySelector("app-one-mfe")?.shadowRoot?.querySelector("app-root");
        appRef.bootstrap(AppComponent, element);
    

    OR

    1. If need to toggle MFE, then Angular Element works, here is the code to make MFE as a custom element on host application
    ngDoBootstrap(appRef: ApplicationRef): void { const element =
    createCustomElement(AppComponent, { injector: this.injector, });
    customElements.define("app-one-mfe",element);
    
    1. In host application's HTML, place below code, this will load remote application, in this case Micro-Frontend.
    <div>
    <app-one-mfe></app-one-mfe> <!--This is a custom element tag from step#1  -->
    <script defer src="http://studyground/mfapp1/entry.js"></script> 
    </div>
    

    And this resolved the issue, now Angular app is loaded from ASPX page.