it-swarm.com.de

Was ist der Unterschied zwischen Abhängigkeiten, devDependencies und peerDependencies in der Datei npm package.json?

Diese Dokumentation beantwortet meine Frage sehr schlecht. Ich habe diese Erklärungen nicht verstanden. Kann jemand in einfacheren Worten sagen? Vielleicht mit Beispielen, wenn es schwierig ist, einfache Wörter zu wählen?

EDIT fügte außerdem peerDependencies hinzu, das eng verwandt ist und Verwirrung stiften kann.

1653

Zusammenfassung wichtiger Verhaltensunterschiede:

  • dependencies sind auf beiden installiert:

    • npm install aus einem Verzeichnis, das package.json enthält
    • npm install $package in einem anderen Verzeichnis
  • devDependencies sind:

    • wird auch auf npm install in einem Verzeichnis installiert, das package.json enthält, sofern Sie nicht das --production-Flag übergeben (go upvote Gayan Chariths answer ).
    • nicht auf npm install "$package" in einem anderen Verzeichnis installiert, es sei denn, Sie geben die Option --dev an.
    • sind nicht durchgehend installiert.
  • peerDependencies :

    • vor 3.0: werden immer installiert, wenn sie fehlen, und es wird ein Fehler ausgegeben, wenn mehrere inkompatible Versionen der Abhängigkeit von verschiedenen Abhängigkeiten verwendet werden.
    • Start voraussichtlich auf 3.0 (ungeprüft): Wenn npm install fehlt, wird eine Warnung ausgegeben, und Sie müssen die Abhängigkeit manuell lösen. Wenn die Abhängigkeit fehlt, wird beim Ausführen eine Fehlermeldung angezeigt (erwähnt durch @nextgentech ).
  • Transitivität (erwähnt von Ben Hutchison ):

    • dependencies werden durchgehend installiert: Wenn A B erfordert und B C benötigt, wird C installiert, andernfalls könnte B nicht funktionieren, und A würde auch nicht funktionieren.

    • devDependencies wird nicht durchgehend installiert. Z.B. Wir müssen B nicht testen, um A zu testen, so dass die Testabhängigkeiten von B weggelassen werden können.

Verwandte Optionen, die hier nicht behandelt werden:

devDependencies

dependencies sind erforderlich, um ausgeführt zu werden, devDependencies, um z. B. Unit-Tests, CoffeeScript-JavaScript-Transpilierung, Minification, ... zu entwickeln.

Wenn Sie ein Paket entwickeln möchten, laden Sie es herunter (z. B. über git clone), gehen Sie zum Stammverzeichnis, das package.json enthält, und führen Sie Folgendes aus:

npm install

Da Sie über die eigentliche Quelle verfügen, ist es klar, dass Sie sie entwickeln möchten. Daher werden standardmäßig sowohl dependencies (da Sie zum Entwickeln natürlich laufen müssen) als auch devDependency-Abhängigkeiten installiert.

Wenn Sie jedoch nur ein Endbenutzer sind, der nur ein Paket zur Verwendung installieren möchte, können Sie dies von jedem beliebigen Verzeichnis aus tun:

npm install "$package"

In diesem Fall möchten Sie normalerweise keine Entwicklungsabhängigkeiten haben. Sie erhalten also nur das, was zur Verwendung des Pakets erforderlich ist: dependencies.

Wenn Sie in diesem Fall wirklich Entwicklungspakete installieren möchten, können Sie die Konfigurationsoption dev auf true setzen, möglicherweise über die Befehlszeile:

npm install "$package" --dev

Die Option ist standardmäßig false, da dies ein weitaus seltener ist.

peerDependencies

(Vor 3.0 getestet)

Quelle: https://nodejs.org/de/blog/npm/peer-dependencies/

Bei regelmäßigen Abhängigkeiten können Sie mehrere Versionen der Abhängigkeit haben: Sie wird einfach im node_modules der Abhängigkeit installiert.

Z.B. Wenn dependency1 und dependency2 in verschiedenen Versionen von dependency3 abhängen, sieht der Projektbaum folgendermaßen aus:

root/node_modules/
                 |
                 +- dependency1/node_modules/
                 |                          |
                 |                          +- dependency3 v1.0/
                 |
                 |
                 +- dependency2/node_modules/
                                            |
                                            +- dependency3 v2.0/

Plugins sind jedoch Pakete, die normalerweise kein anderes Paket benötigen, das in diesem Kontext Host genannt wird. Stattdessen:

  • plugins sind erforderlich vom Host
  • plugins bieten eine Standardschnittstelle an, die der Host erwartet
  • nur der Host wird direkt vom Benutzer aufgerufen, daher muss es eine einzige Version davon geben.

Z.B. Wenn dependency1 und dependency2 peer von dependency3 abhängen, sieht der Projektbaum folgendermaßen aus:

root/node_modules/
                 |
                 +- dependency1/
                 |
                 +- dependency2/
                 |
                 +- dependency3 v1.0/

Dies geschieht auch, wenn Sie dependency3 in Ihrer package.json-Datei nie erwähnen.

Ich denke, das ist ein Beispiel des Inversion of Control Design-Musters.

Ein prototypisches Beispiel für Peer-Abhängigkeiten ist Grunt, der Host und seine Plugins.

Auf einem Grunt-Plugin wie https://github.com/gruntjs/grunt-contrib-uglify sehen Sie beispielsweise Folgendes:

  • grunt ist ein peer-dependency
  • das einzige require('grunt') ist unter tests/: es wird vom Programm nicht wirklich verwendet.

Wenn der Benutzer ein Plugin verwendet, fordert er das Plugin implizit aus der Gruntfile an, indem es eine grunt.loadNpmTasks('grunt-contrib-uglify')-Zeile hinzufügt. Es ist jedoch grunt, die der Benutzer direkt anruft.

Dies würde dann nicht funktionieren, wenn jedes Plugin eine andere Grunt-Version benötigt.

Handbuch

Ich denke, die Dokumentation beantwortet die Frage ziemlich gut, vielleicht kennen Sie sich mit Knoten/anderen Paketmanagern nicht genug aus. Ich verstehe es wahrscheinlich nur, weil ich etwas über Ruby Bundler weiß.

Die Schlüsselzeile lautet:

Diese Komponenten werden bei der Ausführung von npm link oder npm vom Stammverzeichnis eines Pakets aus installiert und können wie alle anderen npm-Konfigurationsparameter verwaltet werden. Weitere Informationen zum Thema finden Sie unter npm-config (7).

Und dann unter npm-config (7) dev finden:

Default: false
Type: Boolean

Install dev-dependencies along with packages.

Wenn Sie devDependencies nicht installieren möchten, können Sie npm install --production verwenden. 

402
Gayan Charith

Mokka wäre zum Beispiel normalerweise eine devDependency, da das Testen in der Produktion nicht erforderlich ist, während express eine Abhängigkeit darstellt. 

95
dankohn

So speichern Sie ein Paket in package.json as dev-Abhängigkeiten: 

npm install "$package" --save-dev

Wenn Sie npm install ausführen, werden sowohl devDependencies als auch dependencies installiert. Um zu vermeiden, dass devDependencies installiert wird, führen Sie Folgendes aus:

npm install --production
55
Mohammed Safeer

Abhängigkeiten
Abhängigkeiten, die Ihr Projekt ausführen muss, z. B. eine Bibliothek, die Funktionen enthält, die Sie mit Ihrem Code aufrufen.
Sie werden durchgehend installiert (wenn A von B abhängt, hängt von npm Install auf A B und C ab).
Beispiel: lodash: Ihr Projekt ruft einige lodash-Funktionen auf.

devDependencies
Abhängigkeiten, die Sie nur während der Entwicklung oder Veröffentlichung benötigen, wie Compiler, die Ihren Code in Javascript, Test-Frameworks oder Dokumentationsgeneratoren kompilieren.
Sie werden nicht durchgehend installiert (wenn A von B abhängt oder von C abhängt, installiert npm auf A nur B).
Beispiel: grunt: Ihr Projekt verwendet grunt, um sich selbst zu erstellen.

peerDependencies
Abhängigkeiten, die Ihr Projekt in das übergeordnete Projekt einbindet oder ändert, in der Regel ein Plug-In für eine andere Bibliothek oder ein anderes Tool. Es ist nur eine Überprüfung, um sicherzustellen, dass das übergeordnete Projekt (Projekt, das von Ihrem Projekt abhängt) von dem Projekt abhängig ist, in das Sie einbinden. Wenn Sie also ein Plugin C erstellen, das die Bibliothek B um Funktionalität erweitert, muss jemand, der ein Projekt A erstellt, eine Abhängigkeit von B haben, wenn er von C abhängig ist.
Sie werden nicht installiert (es sei denn, npm <3), sie werden nur geprüft.
Beispiel: grunt: Ihr Projekt fügt Grunt Funktionalität hinzu und kann nur für Projekte verwendet werden, die Grunt verwenden.

Diese Dokumentation erklärt Peer-Abhängigkeiten sehr gut: https://nodejs.org/de/blog/npm/peer-dependencies/

Die npm-Dokumentation wurde im Laufe der Zeit verbessert und bietet nun bessere Erklärungen zu den verschiedenen Arten von Abhängigkeiten: https://github.com/npm/cli/blob/latest/doc/files/package.json.md #devdependencies

34
qwertzguy

Es gibt einige Module und Pakete, die nur für die Entwicklung erforderlich sind und nicht in der Produktion benötigt werden. Wie sagt es in der Dokumentation :

Wenn jemand plant, Ihr Modul herunterzuladen und in seinem Programm zu verwenden, möchte oder will es wahrscheinlich nicht das von Ihnen verwendete externe Test- oder Dokumentations-Framework herunterladen und erstellen. In diesem Fall sollten Sie diese zusätzlichen Elemente am besten in einem devDependencies-Hash auflisten.

33
Amberlamps

Eine einfache Erklärung, die mir klarer wurde, ist:

Wenn Sie Ihre App bereitstellen, müssen Module in Abhängigkeiten installiert werden, ansonsten funktioniert Ihre App nicht. Module in devDependencies müssen nicht auf dem Produktionsserver installiert werden, da Sie nicht auf diesem Computer entwickeln . link

11
Jyoti Duhan

Ich möchte meine Antwort auf diese Abhängigkeiten erklären

  • dependencies werden für die direkte Verwendung in Ihrer Codebase verwendet, Dinge, die normalerweise im Produktionscode enden, oder Codeabschnitte
  • devDependencies werden für den Build-Prozess verwendet, Tools, mit denen Sie den End-Code verwalten können, Testmodule von Drittanbietern (z. B. Webpack-Zeug).

peerDependencies ergab für mich keinen Sinn, bis ich diesen Ausschnitt aus einem Blogbeitrag zum oben genannten Thema Ciro las :

Was [ Plugins ] benötigen, ist eine Möglichkeit, diese „Abhängigkeiten“ zwischen Plugins und ihrem Host-Paket auszudrücken. Eine Art zu sagen: "Ich arbeite nur, wenn ich mit Version 1.2.x meines Host-Pakets verbunden bin. Wenn Sie mich also installieren, stellen Sie sicher, dass es sich neben einem kompatiblen Host befindet." Diese Beziehung wird als Peer-Abhängigkeit bezeichnet.

Das Plugin hat expect ​​eine bestimmte Version des Hosts ...

peerDependencies sind für Plugins gedacht, Bibliotheken, für deren Ausführung eine "Host" -Bibliothek erforderlich ist, die jedoch möglicherweise zu einem Zeitpunkt geschrieben wurde bevor die neueste Version des Hosts veröffentlicht wurde.

Das heißt, wenn ich PluginX v1 Für HostLibraryX v3 Schreibe und weggehe, gibt es keine Garantie, dass PluginX v1 Funktioniert, wenn HostLibraryX v4 (Oder sogar HostLibraryX v3.0.1) ) es ist veröffentlicht worden.

... aber das Plugin ist nicht abhängig vom Host ...

Aus der Sicht des Plugins ist es nur fügt ​​Funktionen zur Host-Bibliothek hinzu. Ich brauche den Host nicht wirklich, um einem Plugin eine Abhängigkeit hinzuzufügen, und Plugins sind oft nicht buchstäblich abhängig von ihrem Host. Wenn Sie den Host nicht haben, führt das Plugin harmlos nichts aus.

Dies bedeutet, dass dependencies nicht das richtige Konzept für Plugins ist.

Schlimmer noch, wenn mein Host wie eine Abhängigkeit behandelt würde, würden wir in dieser Situation enden, dass derselbe Blog-Beitrag erwähnt (ein wenig bearbeitet, um die Antwort zu verwenden, die aus Host & besteht. Plugin):

Wenn wir jedoch die aktuelle Version von HostLibraryX als Abhängigkeit für PluginX betrachten, führt das Ausführen von npm install Zu dem unerwarteten Abhängigkeitsdiagramm von

├── [email protected]
└─┬ [email protected]
  └── [email protected]

Ich überlasse die subtilen Fehler, die vom Plug-in mit einer anderen [HostLibraryX] -API als der Hauptanwendung ausgehen, Ihrer Vorstellungskraft.

... und der Host hängt natürlich nicht vom Plugin ab ...

... das ist der springende Punkt bei Plugins. Wenn der Host nun so nett wäre, Abhängigkeitsinformationen für alle seiner Plugins aufzunehmen, würde dies das Problem lösen, aber das würde auch ein riesiges neues kulturelles Problem einführen: Plugin-Verwaltung!

Der springende Punkt bei Plugins ist, dass sie anonym gepaart werden können. In einer perfekten Welt wäre es ordentlich, wenn der Host sie alle verwalten würde, aber wir werden keine Bibliotheken für Herdenkatzen benötigen.

Wenn wir nicht hierarchisch abhängig sind, sind wir vielleicht unabhängige Kollegen ...

Stattdessen haben wir das Konzept, Gleichaltrige zu sein. Weder Host noch Plugin befinden sich im Abhängigkeitsbereich des anderen. Beide leben auf der gleichen Ebene des Abhängigkeitsgraphen.

... aber das ist keine automatisierbare Beziehung.

Wenn ich PluginX v1 Und erwarte ein Peer von (das heißt habe eine Peer-Abhängigkeit von) HostLibraryX v3 Bin, sage ich das auch . Wenn Sie automatisch auf den neuesten HostLibraryX v4 Aktualisiert haben (beachten Sie, dass dies die Version ist 4) UND haben Plugin v1 installiert, das müssen Sie wissen, oder?

npm kann diese Situation für mich nicht bewältigen -

"Hey, ich sehe, dass Sie PluginX v1 Verwenden! Ich stufe HostLibraryX automatisch von v4 auf v3 herunter, kk?"

... oder...

"Hey, ich sehe, dass Sie PluginX v1 Verwenden. Das erwartet HostLibraryX v3, Das Sie während Ihres letzten Updates im Staub gelassen haben. Um sicherzugehen, deinstalliere ich Plugin v1!! 1!

Wie wäre es mit nein, npm ?!

Npm also nicht. Es macht Sie auf die Situation aufmerksam und lässt Sie herausfinden, ob HostLibraryX v4 Ein geeigneter Partner für Plugin v1 Ist.


Koda

Gutes peerDependency Management in Plugins lässt dieses Konzept in der Praxis intuitiver funktionieren. Aus dem Blogbeitrag nochmal ...

Ein Tipp: Peer-Abhängigkeitsanforderungen sollten im Gegensatz zu denen für reguläre Abhängigkeiten nachsichtig sein. Sie sollten Ihre Peer-Abhängigkeiten nicht auf bestimmte Patch-Versionen beschränken. Es wäre wirklich ärgerlich, wenn ein Chai-Plugin von Chai 1.4.1 abhängen würde, während ein anderes von Chai 1.5.0 abhängen würde, einfach weil die Autoren faul waren und nicht die Zeit damit verbrachten, die tatsächliche Mindestversion von Chai herauszufinden kompatibel mit.

3
ruffin

Abhängigkeiten vs dev Abhängigkeiten

Dev-Abhängigkeiten sind Module, die nur während der Entwicklung benötigt werden, während Abhängigkeiten zur Laufzeit benötigt werden. Wenn Sie Ihre Anwendung bereitstellen, müssen Abhängigkeiten installiert werden, sonst funktioniert Ihre Anwendung einfach nicht. Bibliotheken, die Sie aus Ihrem Code aufrufen, der die Ausführung des Programms ermöglicht, können als Abhängigkeiten betrachtet werden.

zB- React, React - dom

Dev-Abhängigkeitsmodule müssen nicht auf dem Produktionsserver installiert werden, da Sie auf diesem Computer keine Compiler entwickeln werden. Compiler, die Ihren Code auf Javascript umwandeln, Test-Frameworks und Dokumentgeneratoren können als Dev-Abhängigkeiten betrachtet werden, da sie nur während der Entwicklung erforderlich sind.

ZB ESLint, Babel, Webpack

@FYI,

mod-a
  dev-dependents:
    - mod-b
  dependents:
    - mod-c

mod-d
  dev-dependents:
    - mod-e
  dependents:
    - mod-a

----

npm install mod-d

installed modules:
  - mod-d
  - mod-a
  - mod-c

----

checkout the mod-d code repository

npm install

installed modules:
  - mod-a
  - mod-c
  - mod-e

Wenn Sie in npm veröffentlichen, ist es wichtig, dass Sie das richtige Flag für die richtigen Module verwenden. Wenn Ihr npm-Modul funktionieren soll, verwenden Sie das Flag "--save", um das Modul als Abhängigkeit zu speichern. Wenn Ihr Modul nicht funktionieren muss, aber zum Testen benötigt wird, verwenden Sie das Flag "--save-dev".

# For dependent modules
npm install dependent-module --save

# For dev-dependent modules
npm install development-module --save-dev
2
Selva Ganapathi

Wenn Sie versuchen, ein npm-Paket zu verteilen, sollten Sie die Verwendung von dependencies vermeiden. Stattdessen müssen Sie in Betracht ziehen, es in peerDependencies hinzuzufügen oder aus dependencies zu entfernen.

0
Melchia

Zusamenfassend

  1. Abhängigkeiten - npm install <package> save-prod installierte Pakete, die von Ihrer Anwendung in der Produktionsumgebung benötigt werden.

  2. DevDependencies - npm install <package> --save-dev installiert Pakete, die nur für die lokale Entwicklung und das Testen erforderlich sind

  3. Durch Eingabe von npm install werden alle in package.json genannten Pakete installiert

wenn Sie also auf Ihrem lokalen Computer arbeiten, geben Sie einfach npm install ein und fahren Sie fort :)

0
cherankrish