web-dev-qa-db-fra.com

Comment éviter les erreurs "chargées en deux copies" lors du développement d'un composant externe?

Je développe un composant externe (disons my-component, que je relie au projet avec npm link (car il est en cours de traitement et j'ai besoin du package pour refléter les modifications).

Dans le dossier my-component, il y a node_modules/react et node_modules/react-dom, car ce sont ses dépendances. Cependant, ils sont peerDependences, donc je n’ai pas supposé les inclure dans le projet reliant ce paquet.

Cependant, lorsque vous utilisez npm link, il relie tout le répertoire, y compris node_modules. Ainsi, lorsque le projet est construit, il inclut les packages 2 fois: de node_modules/* et de node_modules/my-component/node_modules/*.

Cela commence à affecter lorsque le composant utilise ReactDOM.findDOMNode, il provoque cette erreur:

Warning: React can't find the root component node for data-reactid value `.0.2.0`. If you're seeing this message, it probably means that you've loaded two copies of React on the page. At this time, only a single copy of React can be loaded at a time.

En outre, il peut être utile de comprendre ce qui se passe: le problème n'apparaît que s'il existe à la fois node_modules/my-component/node_modules/react et node_modules/my-component/node_modules/react-dom. S'il n'y en a qu'un, il n'y a pas de message d'erreur.

L’installation habituelle du paquet n’apporte pas cette erreur car il n’y a pas de node_modules/react-dom.

Comment est-il supposé développer un composant externe et le projet en même temps?

25
Varvara Stepanova

Je crois que la réponse est de spécifier react et react-dom en tant que peerDependencies dans le package.json de votre composant externe. Aussi bien que je puisse suivre ici et ici , npm link ne devrait plus (à partir du npm@3) installer peerDependencies (ou `devDependencies non plus).

Aaaand, je viens de lire votre message plus attentivement et je me suis aperçu que vous les spécifiiez déjà comme peerDependencies. Par conséquent, je pense que la réponse se résume à:

Mise à niveau vers npm@3:

npm install -g [email protected]

5
ericsoco

Corrigé en ajoutant react-dom comme alias à ma config webpack

alias: {

    react$: require.resolve(path.join(constants.NODE_MODULES_DIR, 'react')),
    'react-dom': require.resolve(path.join(constants.NODE_MODULES_DIR, 'react-dom'))

}
4
Yuri

Le problème est double: 

  1. Vous ne pouvez pas avoir 2 copies de react chargé.
  2. le lien npm crée un lien symbolique. Toutefois, le paramètre "require" ne respecte pas le lien symbolique Lorsqu'il tente de naviguer dans le répertoire, il ne trouve jamais la réaction du projet parent.

Solution:

Tout ce que vous avez à faire est de lier les réactions de votre composant à celles du fichier node_modules du projet parent.

Accédez à votre projet de composant et retirez le réactif puis réagissez puis faites 

npm link ../myproject/node_modules/react
npm link ../myproject/node_modules/react-dom
2
abhisekpaul

Ajouter ce qui suit dans mon webpack.config.js a fonctionné pour moi:

resolve: {
    alias: {
        react: path.resolve(__dirname, 'node_modules', 'react')
    }
}

J'ai aussi expérimenté DedupePlugin (mentionné comme un remède possible ici ) mais je ne pouvais pas le faire fonctionner.

Ce qui est également intéressant, c’est que j’ai rencontré différentes manifestations (et peut-être plus insidieuses) du même problème lorsqu’un module est trouvé à plusieurs endroits dans le graphique de dépendance.

Un de ces cas était que mes contraintes React.PropTypes.instanceOf(SomeType) émettraient des avertissements même si le type que je passais était correct. Cela était dû au fait que le module était présent à plusieurs endroits dans l'arborescence de répertoires node_modules. En raison de la frappe de canard, le code fonctionnerait toujours, mais ma console était encombrée de ces avertissements. Aller dans le sens resolve.alias les a aussi réduits au silence.

YMMV

1

Le problème est avec le lien npm. https://github.com/npm/npm/issues/5875

npm ne considère pas le répertoire lié comme un enfant du projet parent.

Essayez des alternatives au lien npm:

1) Utiliser les dépendances de chemin relatives dans package.json

2) Incluez manuellement vos dépendances dans le répertoire de vos projets node_modules

3) Utiliser le chemin de l'URL

Fondamentalement tout sauf le lien npm

1
Thomas Kagan

J'utilise ReactJS.net et installe Webpack à partir du tutoriel. J'ai commencé à utiliser react-bootstrap aswell quand j'ai commencé à avoir cette erreur. J'ai trouvé que l'ajout de 'react-dom': 'ReactDOM' à la liste de externals dans webpack.config.js corrigeait le problème, la liste des données externes ressemblait alors à ceci:

  externals: {
    // Use external version of React (from CDN for client-side, or
    // bundled with ReactJS.NET for server-side)
      react: 'React',
      'react-dom': 'ReactDOM'

Cela semble être le premier lien de débordement de pile sur Google pour cette erreur, alors je pensais que cette réponse pourrait aider quelqu'un ici.

0
user1641172

Si vous utilisez Webpack dans le projet principal, cette solution peut fonctionner. Dans mon cas, project-a requiert project-b. Les deux nécessitent React et ReactDOM 0.14.x

J'ai ceci dans project-a/webpack.config.js:

resolve: {
  modulesDirectories: ['node_modules'],
  fallback: path.join(__dirname, 'node_modules')
},
resolveLoader: {
  fallback: path.join(__dirname, 'node_modules')
},
  • project-b requiert React et ReactDOM sous la forme peerDependencies dans project-b/package.json
  • project-a requiert project-b en tant que devDependency (devrait également fonctionner en tant que dependency) dans project-a/package.json
  • project-b local est lié à project-a comme suit: cd project-a; npm link ../project-b

Maintenant, lorsque je lance npm run build dans project-b, les modifications apparaissent immédiatement dans project-a

0
ncherro

J'obtenais ceci parce que j'avais déjà inclus react et react-dom en tant que scripts externes dans mon balisage HTML.

L'erreur a été causée par l'ajout d'un import ReactDOM from 'react-dom' à un module de composant. L'erreur a disparu une fois que j'ai supprimé l'importation et le module a bien fonctionné, car les composants étaient déjà disponibles.

0
Ben