Search code examples
angularmicroserviceszone.js

Micro apps with Angular 7 - Zone.js and custom elements issues


I'm pretty new in developing Angular (7), because I think about the architecture for a new large web project. So I play a little bit with the possible options, especially using a micro frontend.

I created two angular projects -> "micro-app-shell" and "micro-app-a".

The shell is the outer container of the web application, which manages several micro-apps.

I read some articals about micro apps with angular and want to try the custom-elements approach.

"micro-app-a"

excerpt of "app.module.ts"

@NgModule({
  declarations: [
    AppComponent,
    ClientAComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  // bootstrap: [AppComponent]
  entryComponents: [
    ClientAComponent,
  ]
})
export class AppModule {

  constructor(private injector: Injector) {

  }

  ngDoBootstrap() {
    const appElement = createCustomElement(ClientAComponent, { injector: this.injector });
    customElements.define('client-a', appElement);
  }

}

"app.component.html"

<div style="text-align:center">
  <h1>
    Client A Micro App
  </h1>
</div> 

I build the application with following command:

ng build --output-hashing none --output-path C:/Dev/mdo_workspace/micro-app-test/micro-app-shell/src/assets/scripts

"micro-app-shell"

I added following to of index.html

 <script type="text/javascript" src="./assets/scripts/runtime.js"></script>
  <script type="text/javascript" src="./assets/scripts/polyfills.js"></script>
  <script type="text/javascript" src="./assets/scripts/styles.js"></script>
  <script type="text/javascript" src="./assets/scripts/vendor.js"></script>
  <script type="text/javascript" src="./assets/scripts/main.js"></script>

I extend the app.module.ts with schemas part

schemas: [CUSTOM_ELEMENTS_SCHEMA],

Now my questions/issues

1 a) When I uncomment in "micro-app-a" -> polyfills.js the zone.js import (import 'zone.js/dist/zone'; ) and run the "micro-app-shell" I get the error

Zone already loaded.

1 b) When I comment in "micro-app-a" -> polyfills.js the zone.js import (import 'zone.js/dist/zone'; ) and run the "micro-app-shell" I get the error

In this configuration Angular requires Zone.js

Wat is the right way to prevent this errors? Or can I irgnore it?

2) When I apply changes of question 1a and start the "micro-app-shell" I want to show the "micro-app-a" as custom element in app.comment.html like this:

<div>
  <client-a></client-a>
</div>

The content of "micro-app-shell" - "app.component.html" is shown but I get the error:

Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function.

I following samples like this:

https://www.softwarearchitekt.at/post/2018/05/04/microservice-clients-with-web-components-using-angular-elements-dreams-of-the-near-future.aspx https://www.ngdevelop.tech/angular-elements/

Thanks a lot for your help in advance!


Solution

  • The example above looks like it should work. I was also getting the same error and it looks like there are some browser support issues. I was able to get everything working by adding @webcomponents/custom-elements

    npm install @webcomponents/custom-elements
    

    Then added the following at the end of polyfills.ts

    // Used for browsers with partially native support of Custom Elements
    import '@webcomponents/custom-elements/src/native-shim';
    
    // Used for browsers without a native support of Custom Elements
    import '@webcomponents/custom-elements/custom-elements.min';