Cette documentation répond très mal à ma question. Je n’ai pas compris ces explications. Est-ce que quelqu’un peut dire en termes plus simples? Peut-être avec des exemples s’il est difficile de choisir des mots simples?
Résumé des différences de comportement importantes:
dependencies
sont installées sur les deux:
npm install
partir d’un répertoire contenant package.json
npm install $package
sur tout autre répertoire devDependencies
sont:
npm install
sur un répertoire contenant package.json
, à moins que vous ne passiez le drapeau --production
( remplacez la réponse de Gayan Charith ). npm install "$package"
sur un autre répertoire, sauf si vous lui donnez l’option --dev
. peerDependencies
:
npm install
, et vous devrez résoudre la dépendance 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ées de manière transitoire: si A requirejs B et B requirejs C, alors C est installé, sinon B ne pourrait pas fonctionner, et A.
devDependencies
ne sont pas installées de manière transitoire. Par exemple, nous n’avons pas besoin de tester B pour tester A, donc les dépendances de test de B peuvent être ignorées.
Options connexes non discutées ici:
bundledDependencies
qui est discuté sur la question suivante: Avantages des bundledDependencies sur les dépendances normales dans NPM optionalDependencies
(mentionnées par Aidan Feldman ) dependencies
sont nécessaires pour exécuter, devDependencies
à développer, par exemple: tests unitaires, transpilation Coffeescript en Javascript, minification, …
Si vous envisagez de développer un package, vous le téléchargez (par exemple via git clone
), allez à sa racine qui contient package.json
, et lancez:
npm install
Étant donné que vous avez la source réelle, il est clair que vous voulez la développer, par conséquent, par défaut, les deux dependencies
(puisque vous devez bien sûr vous développer) et les dépendances devDependency
sont également installées.
Si toutefois vous n’êtes qu’un utilisateur final qui veut simplement installer un paquet pour l’utiliser, vous le ferez depuis n’importe quel répertoire:
npm install "$package"
Dans ce cas, vous ne voulez normalement pas les dépendances de développement, vous obtenez donc ce qui est nécessaire 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 de dev
sur true
, éventuellement à partir de la ligne de commande:
npm install "$package" --dev
L’option est false
par défaut car c’est un cas beaucoup moins courant.
(testé avant 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 à l’intérieur des node_modules
de la dépendance.
Par exemple, si dependency1
et dependency2
dépendent tous deux de la dependency3
à différentes versions, l’arborescence du projet ressemblera à:
root/node_modules/ | +- dependency1/node_modules/ | | | +- dependency3 v1.0/ | | +- dependency2/node_modules/ | +- dependency3 v2.0/
Les plugins sont cependant des paquets qui normalement ne requièrent pas l’autre paquetage, appelé l’ hôte dans ce contexte. Au lieu:
Par exemple, si dependency1
et dependency2
peer dépendent de la dependency3
, l’arborescence du projet ressemblera à ceci:
root/node_modules/ | +- dependency1/ | +- dependency2/ | +- dependency3 v1.0/
Cela se produit même si vous ne mentionnez jamais la dependency3
dans votre fichier package.json
.
Je pense que c’est une instance du modèle de conception Inversion of Control .
Un exemple prototypique de dépendances par les pairs est Grunt, l’hôte et ses plugins.
Par exemple, sur un plugin Grunt tel que https://github.com/gruntjs/grunt-consortingb-uglify , vous verrez que:
grunt
est un peerDependency
require('grunt')
est sous tests/
: il n’est pas réellement utilisé par le programme. Ensuite, lorsque l’utilisateur utilisera un plug-in, il exigera implicitement le plug-in de Gruntfile
en ajoutant une ligne grunt.loadNpmTasks('grunt-consortingb-uglify')
, mais il est grunt
que l’utilisateur appelle directement.
Cela ne fonctionnerait pas si chaque plugin nécessitait une version différente de Grunt.
Je pense que le document répond assez bien à la question, peut-être que vous n’êtes pas seulement familiarisé avec les gestionnaires de paquets / autres. Je ne le comprends probablement que parce que je connais un peu le bundle Ruby.
La ligne clé est la suivante:
Ces éléments seront installés lors de l’installation de npm link ou npm install à partir de la racine d’un package et pourront être gérés comme n’importe quel autre paramètre de configuration npm. Voir npm-config (7) pour plus d’informations sur le sujet.
Et puis sous npm-config (7) trouvez dev
:
Default: false Type: Boolean Install dev-dependencies along with packages.
Si vous ne voulez pas installer devDependencies, vous pouvez simplement utiliser npm install --production
Par exemple, mocha serait normalement une devDependency, puisque le test n’est pas nécessaire en production, alors que express serait une dépendance.
Pour enregistrer un package dans package.json en tant que dépendances dev:
npm install "$package" --save-dev
Lorsque vous exécutez npm install
il installe les dependencies
et les dependencies
. Pour éviter l’installation de devDependencies
exécutez:
npm install --production
Certains modules et packages ne sont nécessaires que pour le développement, ce qui n’est pas nécessaire en production. Comme il le dit dans la documentation :
Si quelqu’un prévoit de télécharger et d’utiliser votre module dans son programme, il ne veut probablement pas ou n’a pas besoin de télécharger et de construire le framework de test ou de documentation externe que vous utilisez. Dans ce cas, il est préférable de répertorier ces éléments supplémentaires dans un hachage devDependencies.
dépendances
Des 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, C, Npm install sur A installera B et C).
Exemple: lodash: votre projet appelle des fonctions lodash.
devDependencies
Les dépendances dont vous avez besoin uniquement pendant le développement ou la publication, comme les compilateurs qui prennent votre code et le comstacknt en javascript, en frameworks de test ou en générateurs de documentation.
Ils ne sont pas installés de manière transitoire (si A dépend de B, dev-depend de C, npm install sur A installera uniquement B).
Exemple: grognement: votre projet utilise le grognement pour se construire.
peerDependencies
Les dépendances auxquelles votre projet accède ou modifie dans le projet parent, généralement un plug-in pour une autre bibliothèque ou un autre outil. Il s’agit simplement d’une vérification, en s’assurant que le projet parent (projet qui dépendra de votre projet) dépend du projet auquel vous êtes connecté. Donc, si vous créez un plug-in C qui ajoute des fonctionnalités à la bibliothèque B, alors une personne qui crée un projet A devra avoir une dépendance de B si elle dépend de C.
Ils ne sont pas installés (sauf si npm <3), ils sont uniquement vérifiés.
Exemple: grunt: votre projet ajoute de la fonctionnalité à la grogne et ne peut être utilisé que sur des projets qui utilisent le grunt.
Cette documentation explique très bien les dépendances entre pairs: https://nodejs.org/en/blog/npm/peer-dependencies/
En outre, la documentation npm a été améliorée au fil du temps et contient désormais de meilleures explications sur les différents types de dépendances: https://github.com/npm/npm/blob/master/doc/files/package.json.md#devdependencies
Une explication simple qui m’a rendu plus clair est:
Lorsque vous déployez votre application, les modules dépendants doivent être installés ou votre application ne fonctionnera pas. Les modules dans devDependencies n’ont pas besoin d’être installés sur le serveur de production car vous ne développez pas sur cette machine. lien
Je voudrais append à la réponse mon avis sur ces explications de dépendances
dependencies
sont utilisées pour une utilisation directe dans votre base de code, des choses qui se retrouvent généralement dans le code de production ou des morceaux de code devDependencies
sont utilisées pour le processus de construction, des outils qui vous aident à gérer la manière dont le code de fin se terminera, des modules de test tiers (par exemple, des éléments de webpack) Lorsque vous essayez de dissortingbuer un package npm, vous devez éviter d’utiliser des dependencies
. Au lieu de cela, vous devez envisager de l’append à peerDependencies
ou de le supprimer des dependencies
.
peerDependencies
n’avait pas vraiment de sens pour moi jusqu’à ce que je lise cet extrait d’ un article de blog sur le sujet mentionné ci-dessus :
Ce dont [ plugins ] a besoin, c’est d’une manière d’exprimer ces «dépendances» entre les plugins et leur paquet hôte. Une manière de dire: «Je ne travaille que lorsque branché à la version 1.2.x de mon paquet hôte, donc si vous m’installez, assurez-vous qu’il se trouve à côté d’un hôte compatible.» Nous appelons cette relation une dépendance par les pairs.
peerDependencies
concerne les plugins, les bibliothèques qui nécessitent une bibliothèque “hôte” pour exécuter leur fonction, mais qui peuvent avoir été écrites à la fois avant la publication de la dernière version de l’hôte.
En d’autres PluginX v1
, si j’écris PluginX v1
pour HostLibraryX v3
et que je PluginX v1
HostLibraryX v3
, il n’y a aucune garantie que PluginX v1
fonctionne lorsque HostLibraryX v4
(ou même HostLibraryX v3.0.1
) est disponible.
Du sharepoint vue du plug-in, il ajoute uniquement des fonctions à la bibliothèque hôte. Je n’ai pas vraiment besoin de l’hôte et les plugins ne dépendent pas littéralement de leur hôte. Si vous n’avez pas l’hôte, le plug-in ne fait rien.
Cela signifie que les dependencies
ne sont pas vraiment le bon concept pour les plugins.
Pire encore, si mon hôte était traité comme une dépendance, nous nous retrouverions dans cette situation que le même article de blog mentionne (édité un peu pour utiliser l’hôte et le plugin créés avec cette réponse):
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 graphique de dépendance inattendu de├── [email protected] └─┬ [email protected] └── [email protected]
Je laisserai les échecs subtils provenant du plug-in en utilisant une autre API [HostLibraryX] que l’application principale de votre imagination.
… c’est tout l’intérêt des plugins. Maintenant, si l’hôte était assez sympa pour inclure des informations de dépendance pour tous ses plugins, cela résoudrait le problème, mais cela introduirait également un nouveau problème culturel majeur : la gestion des plugins!
L’intérêt des plugins réside dans le fait qu’ils peuvent être associés de manière anonyme. Dans un monde parfait, le fait que l’hôte les gère tous serait bien rangé, mais nous ne demanderons pas aux bibliothèques de devenir des chats.
Au lieu de cela, nous avons le concept d’être des pairs. Ni l’hôte ni le plug-in ne se trouvent dans le compartiment de dépendance de l’autre. Les deux vivent au même niveau que le graphe de dépendance.
Si je suis PluginX v1
et que j’attends un homologue de HostLibraryX v3
(c’est-à-dire ayant une dépendance à l’égard des HostLibraryX v3
), je le dirai. Si vous avez mis à niveau automatiquement vers la dernière version de HostLibraryX v4
(notez que c’est la version 4 ) ET que Plugin v1
installé, vous devez savoir, non?
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. Pour être sûr, je désinstalle automatiquementPlugin v1
!! 1!
Et si non, npm ?!
Alors npm pas. Il vous avertit de la situation et vous permet de déterminer si HostLibraryX v4
est un pair approprié pour Plugin v1
.
Une bonne gestion peerDependency
dans les plugins rendra ce concept plus intuitif dans la pratique. Du blog , encore une fois …
Un conseil: les exigences de dépendance des pairs, à la différence de celles des dépendances régulières, devraient être indulgentes. Vous ne devez pas verrouiller vos dépendances entre pairs à des versions de correctifs spécifiques. Ce serait vraiment ennuyeux si un plug-in Chai dépendait de Chai 1.4.1, tandis qu’un autre dépendait de Chai 1.5.0, simplement parce que les auteurs étaient paresseux et ne passaient pas leur temps à déterminer la version minimale de Chai. compatible avec.