web-dev-qa-db-fra.com

Quelle est la différence entre les dépendances, devDependencies et peerDependencies dans le fichier npm package.json?

Cette documentation répond très mal à ma question. Je n'ai pas compris ces explications. Quelqu'un peut-il dire avec des mots plus simples? Peut-être avec des exemples s'il est difficile de choisir des mots simples?

EDIT a également ajouté peerDependencies, qui est étroitement liée et pourrait semer la confusion.

1653
Vitalii Korsakov

Résumé des différences de comportement importantes:

  • dependencies sont installés sur les deux:

    • npm install à partir d'un répertoire contenant package.json
    • npm install $package sur n'importe quel autre répertoire
  • devDependencies are:

    • également installé sur npm install sur un répertoire contenant package.json, sauf si vous passez l'indicateur --production (go upvote réponse de Gayan Charith ).
    • pas installé sur npm install "$package" sur un autre répertoire, à moins que vous ne lui donniez l'option --dev.
    • ne sont pas installés de manière transitoire.
  • peerDependencies :

    • les versions antérieures à 3.0: sont toujours installées si elles manquent et génèrent une erreur si plusieurs versions incompatibles de la dépendance sont utilisées par différentes dépendances.
    • devrait démarrer le 3.0 (non testé): donne un avertissement s’il manque sur npm install, et vous devrez résoudre la dépendance vous-même manuellement. Lors de l'exécution, si la dépendance est manquante, vous obtenez une erreur (mentionnée par @nextgentech )
  • Transitivité (mentionné par Ben Hutchison ):

    • dependencies sont installés de manière transitoire: si A requiert B et B nécessite C, alors C est installé, sinon B ne pourrait pas fonctionner et ni A.

    • devDependencies n'est pas installé de manière transitoire. Par exemple. nous n'avons pas besoin de tester B pour tester A, les dépendances de test de B peuvent donc être omises.

Options connexes non abordées ici:

devDependencies

dependencies sont nécessaires pour exécuter, devDependencies uniquement pour développer, par exemple: tests unitaires, transpilation CoffeeScript vers JavaScript, minification, ...

Si vous allez développer un paquet, vous le téléchargez (par exemple, via git clone), allez à la racine qui contient package.json et exécutez:

npm install

Étant donné que vous avez le code source, il est clair que vous souhaitez le développer. Par conséquent, les dépendances dependencies (puisque vous devez bien sûr exécuter le développement) et devDependency sont également installées.

Si toutefois, vous êtes seulement un utilisateur final qui souhaite simplement installer un paquet pour l'utiliser, vous ferez depuis n'importe quel répertoire:

npm install "$package"

Dans ce cas, vous ne voulez généralement pas les dépendances de développement, vous devez donc obtenir ce dont vous avez besoin pour utiliser le package: dependencies.

Si vous voulez vraiment installer des packages de développement dans ce cas, vous pouvez définir l'option de configuration dev sur true, éventuellement à partir de la ligne de commande, comme suit:

npm install "$package" --dev

L'option est false par défaut puisqu'il s'agit d'un cas beaucoup moins courant.

peerDependencies

(Testé avant la 3.0)

Source: https://nodejs.org/en/blog/npm/peer-dependencies/

Avec des dépendances régulières, vous pouvez avoir plusieurs versions de la dépendance: elle est simplement installée dans le node_modules de la dépendance.

Par exemple. si dependency1 et dependency2 dépendent tous deux de dependency3 sous différentes versions, l’arborescence du projet se présentera comme suit:

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

Les plugins, cependant, sont des paquets qui normalement ne nécessitent pas l’autre paquet, appelé Host dans ce contexte. Au lieu:

  • les plugins sont requis par l'hôte
  • les plugins offrent une interface standard que l'hôte s'attend à trouver
  • seul l'hôte sera appelé directement par l'utilisateur, il doit donc exister une version unique.

Par exemple. Si dependency1 et dependency2 peer dépendent de dependency3, l’arborescence du projet se présentera comme suit:

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

Cela se produit même si vous ne mentionnez jamais dependency3 dans votre fichier package.json.

Je pense que ceci est un exemple du modèle Inversion of Control design.

Grunt, l'hôte et ses plugins sont un exemple typique des dépendances entre homologues.

Par exemple, sur un plugin Grunt comme https://github.com/gruntjs/grunt-contrib-uglify , vous verrez que:

  • grunt est un peer-dependency
  • le seul require('grunt') est sous tests/: il n'est pas réellement utilisé par le programme.

Ensuite, lorsque l'utilisateur utilisera un plugin, il le demandera implicitement à partir de la variable Gruntfile en ajoutant une ligne grunt.loadNpmTasks('grunt-contrib-uglify'), mais c'est grunt que l'utilisateur appellera directement.

Cela ne fonctionnerait pas si chaque plugin nécessitait une version Grunt différente.

Manuel

Je pense que la documentation répond assez bien à la question, peut-être que vous n'êtes pas assez familiarisé avec les gestionnaires de noeuds/autres packages. Je ne le comprends probablement que parce que je connais un peu Ruby Bundler.

La ligne clé est:

Ces choses seront installées lors de l'installation de npm link ou npm à partir de la racine d'un paquet et peuvent être gérées comme n'importe quel autre paramètre de configuration npm. Voir npm-config (7) pour plus d'informations à ce sujet.

Et ensuite, sous npm-config (7), trouvez dev:

Default: false
Type: Boolean

Install dev-dependencies along with packages.

Si vous ne souhaitez pas installer devDependencies, vous pouvez utiliser npm install --production 

402
Gayan Charith

Par exemple, le moka serait normalement une devDependency, car les tests ne sont pas nécessaires en production, alors qu'express serait une dépendance. 

95
dankohn

Pour enregistrer un paquet dans package.json en tant que dépendances dev: 

npm install "$package" --save-dev

Lorsque vous exécutez npm install, il installera à la fois devDependencies et dependencies. Pour éviter d'installer devDependencies, lancez:

npm install --production
55
Mohammed Safeer

dépendances
Dépendances que votre projet doit exécuter, comme une bibliothèque qui fournit des fonctions que vous appelez à partir de votre code.
Ils sont installés de manière transitoire (si A dépend de B dépend de C, installer npm sur A installera B et C).
Exemple: lodash: votre projet appelle des fonctions lodash.

devDependencies
Dépendances dont vous n’avez besoin que pendant le développement ou la publication, comme des compilateurs qui prennent votre code et le compilent en javascript, des frameworks de test ou des générateurs de documentation.
Ils ne sont pas installés de manière transitoire (si A dépend de B, dev-dépend de C, installer npm sur A installera B uniquement).
Exemple: grunt: votre projet utilise grunt pour se construire.

peerDependencies
Dépendances auxquelles votre projet est lié ou modifié dans le projet parent, généralement un plug-in pour une autre bibliothèque ou un autre outil. Il s'agit simplement d'un contrôle en s'assurant que le projet parent (projet qui dépend de votre projet) a une dépendance sur le projet auquel vous êtes accroché. Donc, si vous créez un plugin C qui ajoute des fonctionnalités à la bibliothèque B, le créateur d'un projet A devra avoir une dépendance sur B s'il possède une dépendance sur C.
Ils ne sont pas installés (sauf si npm <3), ils sont seulement vérifiés.
Exemple: grunt: votre projet ajoute des fonctionnalités à grunt et ne peut être utilisé que sur des projets utilisant grunt.

Cette documentation explique très bien les dépendances entre pairs: https://nodejs.org/fr/blog/npm/peer-dependencies/

De plus, la documentation de npm a été améliorée au fil du temps et fournit maintenant de meilleures explications sur les différents types de dépendances: https://github.com/npm/cli/blob/latest/doc/files/package.json.md #devdependencies

34
qwertzguy

Certains modules et packages nécessaires uniquement au développement ne sont pas nécessaires en production. Comme il est dit dans la documentation :

Si une personne a l'intention de télécharger et d'utiliser votre module dans son programme, elle ne veut probablement pas ou n'a pas besoin de télécharger et de construire le test externe ou la structure de documentation que vous utilisez. Dans ce cas, il est préférable de répertorier ces éléments supplémentaires dans un hachage devDependencies.

33
Amberlamps

Une explication simple qui l’a éclairci est la suivante:

Lorsque vous déployez votre application, des modules dans des dépendances doivent être installés, sinon votre application ne fonctionnera pas. Les modules de devDependencies n'ont pas besoin d'être installés sur le serveur de production car vous ne développez pas sur cette machine . link

11
Jyoti Duhan

J'aimerais ajouter à la réponse mon point de vue sur les explications de ces dépendances

  • dependencies sont utilisés pour une utilisation directe dans votre base de code, des choses qui finissent généralement dans le code de production, ou des morceaux de code
  • devDependencies sont utilisés pour le processus de construction, des outils pour vous aider à gérer la façon dont le code final se terminera, des modules de test tiers,
8
Sîrbu Nicolae-Cezar

Dépendances vs dépendances dev

Les dépendances de développement sont des modules qui ne sont requis que pendant le développement, alors que les dépendances sont requises au moment de l'exécution. Si vous déployez votre application, des dépendances doivent être installées, sinon votre application ne fonctionnera tout simplement pas. Les bibliothèques que vous appelez à partir de votre code et qui permettent l’exécution du programme peuvent être considérées comme des dépendances.

Par exemple: React, React - dom

Les modules de dépendance de développement ne doivent pas nécessairement être installés sur le serveur de production car vous ne développerez pas dans cette machine. Les compilateurs qui convertissent votre code en javascript, les frameworks de test et les générateurs de documents peuvent être considérés comme des dépendances de développement, car ils ne sont requis que pendant le développement.

Par exemple, 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

Si vous publiez sur npm, il est important que vous utilisiez le bon drapeau pour les bons modules. Si votre module npm a besoin de fonctionner, utilisez le drapeau "--save" pour enregistrer le module en tant que dépendance. Si votre module n'a pas besoin de fonctionner mais qu'il est nécessaire pour le test, utilisez le drapeau "--save-dev".

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

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

Lorsque vous essayez de distribuer un paquet npm, évitez d'utiliser dependencies. Au lieu de cela, vous devez envisager de l'ajouter à peerDependencies ou de le supprimer de dependencies.

0
Melchia

peerDependencies n'avait pas vraiment de sens pour moi jusqu'à ce que je lise cet extrait de un article de blog sur le sujet Ciro mentionné ci-dessus :

Ce dont [plugins] a besoin est un moyen d’exprimer ces «dépendances» entre les plugins et leur paquet Host. Une façon de dire: «Je ne travaille que lorsque je suis connecté à la version 1.2.x de mon package hôte. Par conséquent, si vous installez moi, assurez-vous qu’elle se trouve à côté d’un hôte compatible». Nous appelons cette relation une dépendance entre pairs.

Le plugin attend une version spécifique de l'hôte ...

peerDependencies sont pour les plugins, les bibliothèques qui nécessitent une bibliothèque "Host" pour remplir leur fonction, mais peuvent avoir été écrites à un moment avant que la dernière version de l'hôte ait été publiée. 

Autrement dit, si j'écris PluginX v1 pour HostLibraryX v3 et que je m'en vais, rien ne garantit que PluginX v1 fonctionnera lorsque HostLibraryX v4 (ou même HostLibraryX v3.0.1) sera publié.

... mais le plugin ne dépend pas dépend de l'hôte ...

Du point de vue du plugin, seul ajoute des fonctions à la bibliothèque de l'hôte. Je n'ai pas vraiment "besoin" de l'hôte pour ajouter une dépendance à un plugin, et les plugins ne sont souvent pas littéralement dépendants de leur hôte. Si vous n'avez pas l'hôte, le plugin ne fait rien inoffensif.

Cela signifie que dependencies n'est pas vraiment le bon concept pour les plugins. 

Pire encore, si mon hôte était traité comme une dépendance, nous nous retrouverions dans la même situation que le même article de blog mentionne (édité un peu pour utiliser cette réponse composée: hôte et plugin):

Mais maintenant, [si nous traitons la version contemporaine de HostLibraryX comme une dépendance pour PluginX,] l'exécution de npm install entraîne le graphe de dépendance inattendu de

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

Je laisserai les imperfections subtiles du plug-in en utilisant une API [HostLibraryX] différente de celle de l'application principale.

... et l'hôte ne dépend évidemment pas du plugin ...

... c'est tout l'intérêt des plugins. Maintenant, si l'hôte était assez gentil pour inclure des informations de dépendance pour tous de ses plugins, cela résoudrait le problème, mais cela introduirait également un nouveau problème culturel énorme: la gestion des plugins! 

L'intérêt des plugins est qu'ils peuvent s'associer anonymement. Dans un monde parfait, laisser l'hôte les gérer serait bien rangé, mais nous n'allons pas avoir besoin de bibliothèques, de troupeaux de chats.

Si nous ne sommes pas dépendants hiérarchiquement, nous sommes peut-être des pairs intradépendants ...

Au lieu de cela, nous avons le concept d'être des pairs. Ni l'hôte ni le plugin ne se trouvent dans le compartiment de dépendance de l'autre. Les deux vivent au même niveau du graphique de dépendance.

... mais ce n'est pas une relation automatisable.

Si je suis PluginX v1 et j'attends un pair de (c'est-à-dire que ai une dépendance à pair de) HostLibraryX v3, je le dirai. Si vous avez mis à niveau automatiquement le dernier HostLibraryX v4 (notez que la version 4) ET dispose de Plugin v1, vous devez le savoir, n'est-ce pas? 

npm ne peut pas gérer cette situation pour moi - 

"Hé, je vois que vous utilisez PluginX v1! Je rétrograde automatiquement HostLibraryX de v4 à v3, kk?" 

... ou...

"Hé, je vois que vous utilisez PluginX v1. Cela attend HostLibraryX v3, que vous avez laissé dans la poussière lors de votre dernière mise à jour. Par sécurité, je désinstalle automatiquement Plugin v1!! 1!

Pourquoi pas npm?! 

Donc, NPM ne le fait pas. Il vous avertit de la situation et vous permet de déterminer si HostLibraryX v4 est un homologue approprié pour Plugin v1.


Coda

Une bonne gestion peerDependency dans les plugins permettra à ce concept de fonctionner de manière plus intuitive dans la pratique. De l'article de blog , encore une fois ...

Un conseil: les exigences de dépendance des pairs, contrairement à celles des dépendances régulières, devraient être indulgentes. Vous ne devez pas verrouiller vos dépendances entre homologues sur des versions de correctif spécifiques. Il serait vraiment agaçant qu'un plugin Chai dépendant de Chai 1.4.1, tandis qu'un autre dépend de Chai 1.5.0, tout simplement parce que les auteurs étaient paresseux et ne prenaient pas le temps de déterminer la version minimale réelle de Chai qu'ils sont compatible avec.

0
ruffin

En bref

  1. Dépendances - npm install <package> save-prod instalsl requis par votre application dans un environnement de production.

  2. DevDependencies - npm install <package> --save-dev installe les packages requis uniquement pour le développement et les tests locaux

  3. Il suffit de taper npm install pour installer tous les packages mentionnés dans le package.json

donc si vous travaillez sur votre ordinateur local, tapez simplement npm install et continuez :)

0
cherankrish