Reputation: 355
I've created two custom elements using Angular Elements.
<capp-customtag1>
is defined in customtag1.js
<capp-customtag2>
is defined in customtag2.js
I load <capp-customtag1>
with <script type="text/javascript" src="assets/customtag1.js"></script>
.
Similarly, for <capp-customtag2>
.
Separately, they work as intended. However, if I try to use both of them in the same project (an Angular 6 project), when I attempt to load the second script, I get the following error:
ERROR DOMException: Failed to execute 'define' on 'CustomElementRegistry': this name has already been used with this registry.
The calls to CustomElementRegistry are made in customtag1.js
and customtag2.js
.
This is the code I use to create capp-customtag1
in the Angular Element AppModule constructor:
const el = createCustomElement(CustomTag1Component, {injector: this.injector});
customElements.define('capp-customtag1', el);
This is the code to create capp-customtag2
in the second project's AppModule constructor:
const el = createCustomElement(CustomTag2Component, {injector: this.injector});
customElements.define('capp-customtag2', el);
Why do both elements have the same custom element name? And, how can I fix the problem?
Upvotes: 5
Views: 12434
Reputation: 539
I kept running into this error and I added a check to make sure the customElement was not already defined. Simply adding the following before defining the element should fix this error:
if (!customElements.get('webtest')) {
customElements.define('webtest', e3);
}
Upvotes: 6
Reputation: 425
I know this is quite late to answer but I faced the issue last night and these are my observations. Hope it helps others with this problem ahead.
The error is because of webpack conflict between the various angular applications on your page.
The solution is to change the jsonpFunction name in webpack.config.js of each of your web component applications.
Example:
module.exports = {
//...
output: {
jsonpFunction: '<unique name for your application's json function>'
}
};
Do this for both of your projects related to capp-customtag1
and capp-customtag1
.
Upvotes: 4
Reputation: 2984
As suspected, it's a bundling issue. The root cause is that webpack (which drives the CLI) uses a runtime: webpackJsonp
global, and you're overwriting that each time you load another bundle (which also defines webpackJsonp) - See webpack/webpack#3791 (comment). The CLI doesn't expose this option (things like this are why angular are not supporting this use case yet). You could (though I don't recommend it) manually rename that global webpackJsonp
in each bundle to something unique.
You're also duplicating all the polyfills
, which is likely to cause all kinds of unexpected results, as they're shimming native APIs and overwriting them at various times. Further, bundling a copy of all the angular packages into each bundle seems suboptimal.
For the moment, if you want to do this sort of use case, your likely best option is going to be to use something like rollup to build UMD bundles
, that rely on angular's UMD bundles and exclude the angular source from each element's package. It's going to take some manual work.
Alternately, don't use the CLI to build the individual elements into binaries, treat them as libraries and bring them into the build properly, so you only have one webpack runtime.
Upvotes: 7
Reputation: 500
I am facing similar kind of issue, what I have done is I put a hyphen in between the selector name.
my element selector name webtest to web-test
in app.module.js
before
const e3 = createCustomElement(WebelementTestComponent, { injector: this.injector });
customElements.define('webtest', e3);
after
const e3 = createCustomElement(WebelementTestComponent, { injector: this.injector });
customElements.define('web-test', e3);
then my problem has been solved.
Upvotes: 1