Polymer / polymer-starter-kit

A starting point for Polymer apps
2.46k stars 660 forks source link

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

Closed jodekirk closed 6 years ago

jodekirk commented 6 years ago

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

keanulee commented 6 years ago

Duplicate dependencies - see my comment/thread at https://github.com/PolymerElements/paper-button/issues/174#issuecomment-388918681

jodekirk commented 6 years ago

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?

keanulee commented 6 years ago

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.

keanulee commented 6 years ago

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.

allthesignals commented 6 years ago

Sorry, what is the process for adding dependencies?

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

Thanks!

keanulee commented 6 years ago

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

allthesignals commented 6 years ago

Thank you @keanulee!

emersonbottero commented 6 years ago

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

emersonbottero commented 6 years ago

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": {},

keanulee commented 6 years ago

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).

emersonbottero commented 6 years ago

yes, but when I npm i the problem continued

keanulee commented 6 years ago

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.

emersonbottero commented 6 years ago

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

flatmax commented 6 years ago

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

btopro commented 6 years ago

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`);
  }
};
PurpleEdge2214 commented 5 years ago

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!

btopro commented 5 years ago

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

WYCAaron commented 5 years ago

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

mahdiridho commented 5 years ago

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 https://github.com/Polymer/polymer/issues/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?

btopro commented 5 years ago

It's a bandaid package for sure, def causes some issues. https://github.com/Polymer/polymer/issues/5407#issuecomment-478994182 is what we do now with much better results

GRRedWings commented 4 years ago

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?

btopro commented 4 years ago

Add to the page as a script much like a polyfill