Multiple Angular Elements from different scripts
Asked Answered
S

4

5

Is it possible to use Angular Elements generated from diffrent scripts?

I have 2 projects weather-widget and clock widget which generates their own script(concated all required ones).

When I use these widgets individually it works fine but when these are used on same page it gives error shown as below:

DOMException: Failed to execute 'define' on 'CustomElementRegistry': this name has already been used with this registry
at CustomElementRegistry.define (http://172.27.147.64:8080/node_modules/document-register-element/build/document-register-element.js:2:18538)
at new AppModule (http://172.27.147.64:8080/dist/weather-widget/main.js:115:24)
Solenoid answered 31/5, 2018 at 8:17 Comment(2)
Do you have access to project source code where you define your custom element? If yes, change the HTML tag names in the define phase. customElements.define('weather-widget', customElement);Heall
Publish your define code. You must be using the same tag name for both widgets resulting in registration errorHeall
C
3

The feature to have multiple angular micro apps on the same page is currently not supported.

The error that you see actually describes the issue well. When you load your second micro app, bootstrap will run and try to bootstrap the module by calling it's ngDoBootstrap method. If you do some detailed logging though, you will notice that it tries to invoke ngDoBootstrap on the first micro app for the second time. If you want to make this work, you would need to do some manual work to control the bootstrap process yourself and make sure to bootstrap the correct module when it is introduced on the page.

Resource

Caren answered 25/9, 2018 at 6:10 Comment(0)
H
4

Just to update this so other users will find a solution. This is now possible using the Angular Custom Webpack Builder.

In angular.json

      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./apps/custom-elements/extra-webpack.config.js",
              "mergeStrategies": { "externals": "replace" }
            },
            ...

And in the extra-webpack.config.js file add something like this:

module.exports = {
  output: {
    jsonpFunction: 'webpackJsonpElements',
    library: 'elements',
  },
}

If it still doesn't work have a go at adding/removing the polyfills from the Polyfills.ts file and adding/removing the custom-elements-es5-adapter.js which you can pull from here

Handbarrow answered 15/7, 2019 at 19:17 Comment(1)
I am getting an error because webpack says jsonpFunction is not a valid key in output.Macadam
C
3

The feature to have multiple angular micro apps on the same page is currently not supported.

The error that you see actually describes the issue well. When you load your second micro app, bootstrap will run and try to bootstrap the module by calling it's ngDoBootstrap method. If you do some detailed logging though, you will notice that it tries to invoke ngDoBootstrap on the first micro app for the second time. If you want to make this work, you would need to do some manual work to control the bootstrap process yourself and make sure to bootstrap the correct module when it is introduced on the page.

Resource

Caren answered 25/9, 2018 at 6:10 Comment(0)
M
0

The building of the distribution assets webpack assigns by default the window.webpackJsonp variable, however with multiple Elements wrapped up that way you will when it parses the bundle this variable is already assigned and runs with the existing code.

You can monkey patch that by giving this variable in your bundle process a more unique name. I just added the Element name to the name of the webpackJsonp, which solved this issue.

Monopode answered 13/3, 2019 at 23:7 Comment(0)
C
0

Incase this helps anyone in the future, resetting the global variable that webpack creates solved the issue for me. For example load page A which is a angular element app and then loading page B which is another angular element app. At the being of the page load be sure to reset webpackJsonp = [].

C answered 26/8, 2021 at 20:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.