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.
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épertoiredevDependencies
are:
npm install
sur un répertoire contenant package.json
, sauf si vous passez l'indicateur --production
(go upvote réponse de Gayan Charith ).npm install "$package"
sur un autre répertoire, à moins que vous ne lui donniez l'option --dev
.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:
bundledDependencies
qui est abordé à la question suivante: Avantages de bundledDependencies par rapport aux dépendances normales dans NPMoptionalDependencies
(mentionné par Aidan Feldman )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.
(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:
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
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.
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
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.
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
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
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.
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
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 codedevDependencies
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,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
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
.
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.
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é.
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.
... 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.
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.
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 automatiquementHostLibraryX
de v4 à v3, kk?"
... ou...
"Hé, je vois que vous utilisez
PluginX v1
. Cela attendHostLibraryX v3
, que vous avez laissé dans la poussière lors de votre dernière mise à jour. Par sécurité, je désinstalle automatiquementPlugin 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
.
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.
En bref
Dépendances - npm install <package> save-prod
instalsl requis par votre application dans un environnement de production.
DevDependencies - npm install <package> --save-dev
installe les packages requis uniquement pour le développement et les tests locaux
npm install
pour installer tous les packages mentionnés dans le package.jsondonc si vous travaillez sur votre ordinateur local, tapez simplement npm install
et continuez :)