1

I'm very new to custom elements. I need to create a custom element to integrate into another app at our company. The problem is my custom element should be a default export I think. I need to make my custom element created by angular somehow accessible as module.default when the host loads it.

There are 2 applications: the HOST app and MY App. I cannot change the host app. The host app is completely outside my control. The Host app is a React app btw.

The host app does something similar to this:

    <script type="module">
      import('/my-angular-bundle.js')
        .then(module => window.customElements.define('unique-custom-element-name', module.default))
        .catch(error => console.error(error))
    </script>

...

    <unique-custom-element-name some-attribute='1' other-attribute='2'>
    </unique-custom-element-name>

Important : I cannot change the host app. The host app has other apps that are loaded like this. The way the script is loaded cannot change. I need to find a way to make the generated angular bundle work with this loading method.


My angular app is a standard angular-cli app except:

  • I'm not bootstrapping a component in AppModule. I just create a custom element and register it.
  • To create a single bundle build I used ngx-build-plus. Which actually created 2 files: main.js and polyfills.js . I used concat-glob-cli to concatenate the two files.
  • in index.html I just include the custom element

In My App The app.module looks like this:

@NgModule({
  declarations: [
    SomeOtherComponent,
    AppComponent
  ],
  entryComponents: [
    AppComponent
  ],
  imports: [
    BrowserModule,
  ],
  providers: [],
})
export class AppModule {

  constructor(private injector: Injector) { }

  ngDoBootstrap() : void {
    const customElement = createCustomElement(AppComponent, { injector: this.injector });
    //*** how do I export customElement here?? ***

    // I define the element here **JUST** to test it locally
    customElements.define('app-root', customElement);
  }
}

And this works perfectly when I'm hosting it myself from index.html:

<body>
  <app-root some-attribute='value'></app-root>
  <script src="micro-frontend.js"></script>
</body>

BUT I MUST load it like this to be compatible with the HOST app which is already in production and cannot change.

    <script type="module">
      import('/my-angular-bundle.js')
        .then(module => window.customElements.define('unique-custom-element-name', module.default))
        .catch(error => console.error(error))
    </script>

But I don't know how to use it with our host app. Because the host app tries to load a default export and tries to define a custom element using the default export. Which I don't have because I don't know how to do a default export. Any help is appreciated.

Tutorials used:

https://www.angulararchitects.io/aktuelles/angular-elements-part-i/

https://www.youtube.com/watch?v=E9i3YBFxSSE

gyozo kudor
  • 6,284
  • 10
  • 53
  • 80
  • Defining the customElement in ngDoBootstrap is correct in production as well. You just need to include "All" the output scripts from angular build a script tag. No need for import, or anything. – Sherif Elmetainy Aug 12 '20 at 21:13
  • @SherifElmetainy the first code sample in my question the one that starts with ` – gyozo kudor Aug 13 '20 at 07:08

1 Answers1

0

Try hosting the custom element js that you got after the build and include that path in your hosted app.

Jobelle
  • 2,717
  • 1
  • 15
  • 26