Polymer/polymer-starter-kit

Uncaught DOMException: Failed to execute 'define' on 'CustomElementRegistry': this name has already been used with this registry

jodekirk opened this issue ยท 22 comments

Description

Insert paper-input into a fresh Polymer 3 polymer-3-starter-kit app.

Expected outcome

App displays with paper-input

Actual outcome

Blank page displayed and due to error:

Uncaught DOMException: Failed to execute 'define' on 'CustomElementRegistry': this name has already been used with this registry
    at Polymer (http://127.0.0.1:8081/node_modules/@polymer/polymer/lib/legacy/polymer-fn.js:43:18)
    at http://127.0.0.1:8081/node_modules/@polymer/iron-input/node_modules/@polymer/iron-meta/iron-meta.js:131:1

IE11 displays this error:

Line: 89
Error: A custom element with name 'iron-meta' has already been defined.

Firefox error:
Error: A custom element with name 'iron-meta' has already been defined. webcomponents-sd-ce.js:2244:32

Steps to reproduce

  1. Put a paper-input element in the page inside app-toolbar in my-app.js
  2. Add import '@polymer/paper-input/paper-input.js'; to my-app.js
  3. npm start
  4. Open the page in a web browser.

Browsers Affected

  • Chrome
  • Edge
  • Firefox
  • IE 11
  • Safari 8
  • Safari 9

Duplicate dependencies - see my comment/thread at PolymerElements/paper-button#174 (comment)

Thanks. Deleting the node_modules folder and package-lock.json and running npm i fixed it. But wonder why it's so easy to get this issue. I added paper-input with npm install --save @polymer/paper-input@next. Does this mean every time the dependencies change I have to delete the node_modules folder?

From my understanding of NPM (which is somewhat limited), the given package-lock.json gives you @polymer/iron-icon@3.0.0-pre.18 which depends on @polymer/iron-meta@^3.0.0-pre.18. Just installing @polymer/paper-input@next gives you @polymer/paper-input@3.0.0-pre.21 (at time of writing) which depends on @polymer/iron-meta@^3.0.0-pre.21, so a duplicate iron-meta is installed (and custom elements don't allow duplicate registrations). If you reset everything, you'll get 3.0.0-pre.21 of everything so no duplicates.

Our current position is to provide package-lock.json because it guarantees that, at least initially, you'll get the same set of dependencies as us when you run npm i. It also helps with testing, since we want to test with the same set of dependencies. We also encourage app developers to check in package-lock.json for these reasons, but this does mean you have to be extra mindful about this step when adding new dependencies. I believe npm update can be used when you're ready to update dependencies.

Wanted to add: some package managers like Yarn will also guarantee no duplicate dependencies, but last I tried it did not work with pwa-starter-kit (another project) because the build/server Node.js dependencies rely on different versions of the same package. Ideally, you want no duplicates for browser code but potentially allow duplicates for Node.js code). There have been some work on the team towards this, but not a satisfying solution yet.

Sorry, what is the process for adding dependencies?

  • rm -rf node_modules package-lock.json
  • npm i

I think new users might find it confusing following the guide. Should there be a note?

Thanks!

Yes, I made a PR for the docs site with a note about this. Looks like it's merged but not deployed yet.

Thank you @keanulee!

I'm on windows and rm -rf node_modules package-lock.json gives me `Remove-Item : A parameter cannot be found that matches parameter name 'rf'.
At line:1 char:4

  • rm -rf node_modules/ package-lock.json
+ CategoryInfo          : InvalidArgument: (:) [Remove-Item], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand`

I deleted the folder in windows explorer and npm i and the problem persisted. I remove manually each subfolder node_modules and edited each pachage.json changing _phantomchildren to empty like
"_phantomChildren": {},

Did you delete the node_modules/ directory AND the package-lock.json file? You shouldn't need to go through each package.json (though I am unfamiliar with NPM on Windows).

yes, but when I npm i the problem continued

I couldn't reproduce the issue with a fresh clone and npm i on my Mac; don't have Windows dev environment to test unfortunately. I don't know if this will help, but I also just updated package/-lock.json to use the stable, non-prerelease 3.x versions of elements. Also, you don't need the @next specifier when adding elements - npm i @polymer/paper-button would do. Make sure you're on latest node/npm version too.

I'll try if i install more elements. I never used @next. and what's the "_phantomChildren" for?

We have a method for resolving these issues, it is to do with removing nested @Polymer modules. Check it out here :
Polymer/polymer#5407

in local dev toss this in a script tag b4 the type modules

const _customElementsDefine = window.customElements.define;
window.customElements.define = (name, cl, conf) => {
  if (!customElements.get(name)) {
    _customElementsDefine.call(window.customElements, name, cl, conf);
  }
  else {
    console.warn(`${name} has been defined twice`);
  }
};

Thanks @btopro I was able to use this solution in an Ionic4/angular project where the elements.module had to be imported into multiple other modules!

I made this a small library that does the same thing and I include it on my demo pages just to be safe -- https://www.npmjs.com/package/@lrnwebcomponents/deduping-fix

in local dev toss this in a script tag b4 the type modules

const _customElementsDefine = window.customElements.define;
window.customElements.define = (name, cl, conf) => {
  if (!customElements.get(name)) {
    _customElementsDefine.call(window.customElements, name, cl, conf);
  }
  else {
    console.warn(`${name} has been defined twice`);
  }
};

not work in safari

I made this a small library that does the same thing and I include it on my demo pages just to be safe -- https://www.npmjs.com/package/@lrnwebcomponents/deduping-fix

For some stuff, it works well. But, for some other I get some problem with the layout and component styles broken.

The one link from @flatmax here Polymer/polymer#5407 is working well, but it's too complex for many dependencies. I dont think to run npm preinstall for every components I created. Very frustrated with this problem over months?

It's a bandaid package for sure, def causes some issues. Polymer/polymer#5407 (comment) is what we do now with much better results

I made this a small library that does the same thing and I include it on my demo pages just to be safe -- https://www.npmjs.com/package/@lrnwebcomponents/deduping-fix

How do you use this library? Just include it in the project?

Add to the page as a script much like a polyfill