webentwicklung-frage-antwort-db.com.de

Wie vermeide ich zwei geladene React-Fehler beim Entwickeln einer externen Komponente?

Ich entwickle gerade eine externe Komponente (sagen wir my-component, die ich mit npm link mit dem Projekt verknüpfe (da es gerade in Bearbeitung ist und ich das Paket brauche, um Änderungen zu berücksichtigen).

Im Ordner my-component befinden sich node_modules/react und node_modules/react-dom als Abhängigkeiten. Sie sind jedoch peerDependences, daher habe ich nicht angenommen, sie in das Projekt einzubinden, das dieses Paket verlinkt.

Bei der Verwendung von npm link wird jedoch das gesamte Verzeichnis einschließlich node_modules verknüpft. Wenn das Projekt erstellt wird, enthält es also zwei Mal Pakete: von node_modules/* und von node_modules/my-component/node_modules/*.

Dies wirkt sich dann aus, wenn die Komponente ReactDOM.findDOMNode verwendet. Dies verursacht diesen Fehler:

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.

Es kann auch hilfreich sein zu verstehen, was passiert: Das Problem tritt nur auf, wenn sowohl node_modules/my-component/node_modules/react als auch node_modules/my-component/node_modules/react-dom vorhanden sind. Wenn es nur eine davon gibt, wird keine Fehlermeldung angezeigt.

Die übliche Paketinstallation führt nicht zu einem Fehler, da dort kein node_modules/react-dom vorhanden ist.

Wie soll eine externe Komponente und das Projekt gleichzeitig entwickelt werden?

25

Ich glaube, die Antwort ist, react und react-dom als peerDependencies in package.json Ihrer externen Komponente anzugeben. So gut ich kann hier und hier folgen, sollte npm link (ab [email protected]) peerDependencies (oder devDependencies) nicht mehr installieren.

Aaaund ich habe gerade Ihren Beitrag genauer gelesen und festgestellt, dass Sie sie bereits als peerDependencies angeben. Ich denke, die Antwort läuft darauf hinaus:

Upgrade auf [email protected]:

npm install -g [email protected]

5
ericsoco

Behebung des Problems durch Hinzufügen von react-dom als Alias ​​zu meiner Webpack-Konfiguration

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

Jemand schlauer als ich (@mojodna) hat diese Lösung gefunden: Entfernen Sie die doppelten Abhängigkeiten von der externen Komponente und lösen Sie sie mit den Kopien dieser Abhängigkeiten in Ihrem Projekt auf.

Schritt 1: Entfernen Sie die Abhängigkeiten von der externen Komponente node_modules

Wie @ cleong notiert , können Sie die Deps nicht einfach aus dem node_modules Der externen Komponente entfernen, da der Build-Schritt Ihres Projekts fehlschlägt, wenn die jetzt fehlenden Abhängigkeiten in der externen Komponente erreicht werden .

Schritt 2: Fügen Sie den node_modules Ihres Projekts zu NODE_PATH Hinzu

Um dies zu beheben, können Sie den node_modules - Wert des Projekts an die Umgebungsvariable NODE_PATH Anhängen, wenn Sie Ihren Erstellungsschritt ausführen. So etwas wie z.B. diese:

NODE_PATH=$(pwd)/node_modules/ npm start

(wobei npm start Ihr Skript ist, das Ihre externe Komponente bündelt, z. B. über Browserify, Webpack usw.)

Tatsächlich könnten Sie diesen NODE_PATH - Zusatz immer an Ihre Build-Skripte anhängen, und es würde funktionieren, ob Sie npm link Irgendetwas bearbeitet haben oder nicht. (Ich frage mich, ob dies nicht das Standardverhalten von npm sein sollte ...)

Hinweis: Ich habe meine bestehende Antwort verlassen, weil dort eine Unterhaltung stattfindet und dies eine andere (und bessere) Lösung ist.

3
ericsoco

Das Problem ist zweifach: 

  1. Sie können nicht zwei Kopien der Reaktion laden.
  2. der npm-Link erstellt einen Symlink, jedoch respektiert "Requirement" den Symlink nicht. Wenn er versucht, im Verzeichnis nach oben zu navigieren, findet er niemals die Reaktion des übergeordneten Projekts.

Lösung:

Alles, was Sie tun müssen, ist die Verbindung von "react" und "react" in Ihrer Komponente mit dem Ordner "node_modules" des übergeordneten Projekts zu verknüpfen.

Gehen Sie zu Ihrem Komponentenprojekt und entfernen Sie das Reagieren und Reagieren und tun Sie es dann 

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

Folgendes in meinem webpack.config.js hinzugefügt hat für mich funktioniert:

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

Ich experimentierte auch mit DedupePlugin (als mögliches Mittel hier erwähnt), aber ich konnte es nicht zum Laufen bringen.

Interessant ist auch, dass ich verschiedene (und vielleicht heimtückischere) Manifestationen desselben Problems gesehen habe, wenn ein Modul an mehreren Stellen im Abhängigkeitsgraphen gefunden wird.

Ein solcher Fall war, dass meine Einschränkungen von React.PropTypes.instanceOf(SomeType) Warnungen ausgeben würden, obwohl der von mir übergebene Typ korrekt war. Dies lag daran, dass das Modul an mehreren Stellen im Verzeichnisbaum node_modules vorhanden war. Durch das Eingeben der Ente funktionierte der Code immer noch, aber meine Konsole war voll mit diesen Warnungen. Durch den resolve.alias-Weg wurden auch diese zum Schweigen gebracht.

YMMV

Das Problem liegt bei npm link. https://github.com/npm/npm/issues/5875

npm behandelt das verknüpfte Verzeichnis nicht als untergeordnetes Element des übergeordneten Projekts.

Versuche Alternativen zu npm link:

1) Verwende relative Pfadabhängigkeiten in package.json

2) Fügen Sie Ihre Abhängigkeiten manuell in das Projektverzeichnis node_modules ein

3) Verwenden Sie den URL-Pfad

Im Grunde alles andere als npm link

1
Thomas Kagan

Ich verwende ReactJS.net und setze das Webpack aus dem Tutorial dort ein und begann mit react-bootstrap, als ich diesen Fehler bekam. Ich fand das Hinzufügen von 'react-dom': 'ReactDOM' zur Liste von externals in webpack.config.js das Problem behoben. Die Liste der Externals sah dann so aus:

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

Dies scheint der erste Stack-Überlauf-Link auf Google für diesen Fehler zu sein. Ich dachte, diese Antwort könnte hier jemandem helfen.

0
user1641172

Wenn Sie Webpack im Hauptprojekt verwenden, kann diese Lösung funktionieren. In meinem Fall erfordert project-aproject-b. Beide erfordern React und ReactDOM 0.14.x

Ich habe das in project-a/webpack.config.js:

resolve: {
  modulesDirectories: ['node_modules'],
  fallback: path.join(__dirname, 'node_modules')
},
resolveLoader: {
  fallback: path.join(__dirname, 'node_modules')
},
  • project-b erfordert React und ReactDOM als peerDependencies in project-b/package.json
  • project-a erfordert project-b als devDependency (sollte auch als dependency erforderlich sein) in project-a/package.json
  • local project-b ist wie folgt mit project-a verknüpft: cd project-a; npm link ../project-b

Wenn ich nun npm run build innerhalb von project-b ausführen, werden die Änderungen sofort in project-a angezeigt.

0
ncherro

Ich bekam dies, weil ich react und react-dom bereits als externe Skripts in mein HTML-Markup aufgenommen hatte.

Der Fehler wurde durch Hinzufügen eines import ReactDOM from 'react-dom' zu einem Komponentenmodul verursacht. Der Fehler wurde behoben, nachdem ich den Import entfernt hatte. Das Modul funktionierte einwandfrei, da die Komponenten bereits verfügbar waren.

0
Ben