Pourquoi utiliser les dépendances par les pairs dans npm pour les plugins?

Pourquoi, par exemple, un plug-in Grunt définit-il sa dépendance à grunt comme ” dépendances par les pairs “?

Pourquoi le plugin ne peut-il pas avoir Grunt comme propre dépendance dans grunt-plug / node_modules ?

Les dépendances entre pairs sont décrites ici: https://nodejs.org/en/blog/npm/peer-dependencies/

Mais je ne comprends pas vraiment.

Exemple

Je travaille actuellement avec les stéroïdes AppGyver qui utilisent les tâches Grunt pour créer mes fichiers sources dans un dossier / dist / afin d’être diffusés sur un périphérique local. Je suis tout à fait nouveau à npm et grunt alors je veux comprendre pleinement ce qui se passe.

Jusqu’à présent, j’ai compris ceci:

[rootfolder] /package.json dit à npm que cela dépend du paquet grunt-steroids npm pour le développement:

  "devDependencies": { "grunt-steroids": "0.x" }, 

D’accord. L’exécution de npm install dans [rootfolder] détecte la dépendance et installe grunt-steroids dans [rootfolder] / node_modules / grunt-steroids .

Npm lit alors [rootfolder] /node_modules/grunt-steroids/package.json pour qu’il puisse installer ses propres dépendances:

 "devDependencies": { "grunt-consortingb-nodeunit": "0.3.0", "grunt": "0.4.4" }, "dependencies": { "wrench": "1.5.4", "chalk": "0.3.0", "xml2js": "0.4.1", "lodash": "2.4.1" }, "peerDependencies": { "grunt": "0.4.4", "grunt-consortingb-copy": "0.5.0", "grunt-consortingb-clean": "0.5.0", "grunt-consortingb-concat": "0.4.0", "grunt-consortingb-coffee": "0.10.1", "grunt-consortingb-sass": "0.7.3", "grunt-extend-config": "0.9.2" }, 

Les paquets ” dependencies ” sont installés dans [rootfolder] / node_modules / grunt-steroids / node_modules, ce qui est logique pour moi.

Les ” devDependencies ” ne sont pas installés, ce qui, j’en suis sûr, est contrôlé par la détection par npm. J’essaie juste d’utiliser grunt-steroids , et de ne pas les développer.

Mais alors nous avons les ” peerDependencies “.

Celles-ci sont installées dans [rootfolder] / node_modules , et je ne comprends pas pourquoi il n’y a pas [rootfolder] / node_modules / grunt-steroids / node_modules pour éviter les conflits avec d’autres plugins (ou autres).

    TL; DR: peerDependencies concerne les dépendances exposées au code utilisateur (et devant être utilisées par ce code), par opposition aux dépendances “privées” qui ne sont pas exposées et ne constituent qu’un détail d’implémentation.

    Le problème que posent les dépendances entre pairs

    Le système de module de npm est hiérarchique. Un grand avantage pour les scénarios plus simples est que lorsque vous installez un paquet npm, ce paquet apporte ses propres dépendances, de sorte qu’il fonctionnera immédiatement.

    Mais des problèmes surviennent lorsque:

    • Votre projet et certains modules que vous utilisez dépendent du même autre module.
    • Les trois modules doivent se parler.

    Exemple

    Disons que vous construisez YourCoolProject et utilisez JacksModule 1.0 et JillsModule 2.0 . Et supposons que JacksModule dépend aussi de JillsModule , mais sur une version différente, disons 1.0 . Tant que ces 2 versions ne se rencontrent pas, il n’y a pas de problème. Le fait que JacksModule utilise JillsModule sous la surface n’est qu’un détail d’implémentation. Nous JillsModule deux fois JillsModule , mais c’est un petit prix à payer lorsque nous obtenons un logiciel stable JillsModule .

    Mais supposons maintenant que JacksModule expose d’une manière ou d’une autre sa dépendance à JillsModule . Il accepte une instanceof object de JillsClass par exemple … Que se passe-t-il lorsque nous créons une new JillsClass aide de la version 2.0 de la bibliothèque et que nous la transmettons à jacksFunction ? Tout l’enfer se déchaînera! Des choses simples comme jillsObject instanceof JillsClass soudainement false , car jillsObject est en fait une instance d’ un autre JillsClass , la version 2.0 .

    Comment les dépendances entre pairs résolvent cela

    Ils disent npm

    J’ai besoin de ce paquet, mais j’ai besoin de la version qui fait partie du projet, pas de la version privée de mon module.

    Lorsque npm voit que votre package est installé dans un projet qui ne possède pas cette dépendance ou dont la version est incompatible , il avertit l’utilisateur lors du processus d’installation.

    Quand devriez-vous utiliser les dépendances entre pairs?

    • Lorsque vous construisez une bibliothèque à utiliser par d’autres projets, et
    • Cette bibliothèque utilise une autre bibliothèque et
    • Vous attendez / avez besoin de l’utilisateur pour travailler avec cette autre bibliothèque aussi

    Les scénarios courants sont des plugins pour les plus grands frameworks. Pensez à des choses comme Gulp, Grunt, Babel, Mocha, etc. Si vous écrivez un plugin Gulp, vous voulez que ce plugin fonctionne avec la même Gulp que le projet de l’utilisateur, pas avec votre propre version privée de Gulp.

    Je vous recommande de relire l’article en premier. C’est un peu déroutant mais l’exemple avec Winston-mail vous montre la raison pour laquelle:

    Par exemple, supposons que winston-mail 0.2.3 a spécifié “winston”: “0.5.x” dans son hash “dépendances”, puisque c’est la dernière version contre laquelle il a été testé. En tant que développeur d’applications, vous souhaitez obtenir les dernières nouveautés, vous pouvez donc rechercher les dernières versions de winston et de winston-mail, en les plaçant dans votre package.json

     { "dependencies": { "winston": "0.6.2", "winston-mail": "0.2.3" } } 

    Mais maintenant, l’exécution de npm install se traduit par le graphique de dépendance inattendu de

     ├── winston@0.6.2 └─┬ winston-mail@0.2.3 └── winston@0.5.11 

    Dans ce cas, il est possible d’avoir plusieurs versions d’un package, ce qui pourrait causer des problèmes. Le paramètre peerDependencies permet aux développeurs npm de s’assurer que l’utilisateur dispose du module spécifique (dans le dossier racine). Mais vous avez raison de dire que décrire une version spécifique d’un paquet entraînerait des problèmes avec d’autres paquets utilisant d’autres versions. Ce problème concerne les développeurs npm, comme l’indiquent les articles.

    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.

    Par conséquent, les développeurs doivent suivre plusieurs étapes pour définir des interdépendances. Vous devriez ouvrir un problème pour le paquet grunt-steriods sur github …

    Comme le dit le Blueprint officiel Si vous voyez des erreurs UNMET PEER DEPENDENCY, vous devez installer manuellement React:

    npm install --save react react-dom react-addons-css-transition-group

    vous pourriez le trouver ici