Pourquoi, par exemple, un plugin Grunt définit-il sa dépendance à grunt comme "dépendances entre homologues "?
Pourquoi le plugin ne peut-il pas simplement avoir Grunt comme sa propre dépendance dans grunt-plug/node_modules ?
Les dépendances entre homologues sont décrites ici: https://nodejs.org/fr/blog/npm/peer-dependencies/
Mais je ne comprends pas vraiment.
Exemple
Je travaille actuellement avec AppGyver Steroids, qui utilise des tâches Grunt pour créer mes fichiers source dans un dossier/dist/qui sera servi sur un périphérique local. Je suis tout à fait nouveau chez NPM et Grunt, alors je veux bien comprendre ce qui se passe.
Jusqu'à présent, j'ai ceci:
[dossier root] /package.json indique à npm que cela dépend du package grunt-steroids
npm pour le développement:
"devDependencies": {
"grunt-steroids": "0.x"
},
D'accord. L'exécution de npm install dans [dossier root] détecte la dépendance et installe grunt-steroids dans [dossier root]/node_modules/grunt. -stéroïdes .
Npm lit alors [dossier racine] /node_modules/grunt-steroids/package.json pour pouvoir installer grunt-steroids
propres dépendances:
"devDependencies": {
"grunt-contrib-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-contrib-copy": "0.5.0",
"grunt-contrib-clean": "0.5.0",
"grunt-contrib-concat": "0.4.0",
"grunt-contrib-coffee": "0.10.1",
"grunt-contrib-sass": "0.7.3",
"grunt-extend-config": "0.9.2"
},
Les paquetages " dépendances " sont installés dans [dossier racine]/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 de npm. J'essaie juste d'utiliser grunt-steroids
, et ne pas développer sur elle.
Mais alors nous avons le " peerDependencies ".
Ceux-ci sont installés dans [dossier root]/node_modules , et je ne comprends pas pourquoi et pas dans [dossier root ]/node_modules/grunt-steroids/node_modules afin d'éviter les conflits avec d'autres plugins Grunt (ou autre)?
TL; DR:[1] peerDependencies
sont destinés aux dépendances exposées au code consommateur et devant être utilisées par celui-ci, par opposition aux dépendances "privées" qui ne sont pas exposés et ne constituent qu'un détail de la mise en œuvre.
Le système de modules de NPM est hiérarchique. Un gros avantage pour les scénarios plus simples est que, lorsque vous installez un package npm, celui-ci comporte ses propres dépendances, de sorte qu'il fonctionne immédiatement.
Mais des problèmes se posent lorsque:
Supposons que vous construisez YourCoolProject
et que vous utilisiez à la fois JacksModule 1.0
et JillsModule 2.0
. Et supposons que JacksModule
dépend aussi de JillsModule
, mais d'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 de la mise en œuvre. Nous groupons JillsModule
deux fois, mais c'est un petit prix à payer lorsque nous obtenons un logiciel stable immédiatement.
Mais maintenant, que se passe-t-il si JacksModule
expose sa dépendance à JillsModule
d'une manière ou d'une autre. Il accepte une instance de JillsClass
par exemple ... Que se passe-t-il lorsque nous créons un new JillsClass
en utilisant la version 2.0
de la bibliothèque et le transmettons à jacksFunction
? Tout l'enfer va se déchaîner! Des choses simples comme jillsObject instanceof JillsClass
renverront subitement false
parce que jillsObject
est en fait une instance de ne autreJillsClass
, la version 2.0
.
Ils disent npm
J'ai besoin de ce paquet, mais j'ai besoin de la version qui fait partie du projet, pas d'une version privée de mon module.
Quand npm voit que votre paquet est en train d'être installé dans un projet qui ne possède pas cette dépendance, ou qui possède un version incompatible , il en avertira l’utilisateur pendant le processus d’installation.
Les scénarios courants sont des plugins pour des cadres plus grands. Pensez à des choses comme Gulp, Grunt, Babel, Mocha, etc. Si vous écrivez un plugin Gulp, vous voulez que ce plugin fonctionne avec le même Gulp que le projet de l'utilisateur utilise, pas avec votre propre version privée de Gulp.
Je vous recommande de lire l'article à nouveau en premier. C'est un peu déroutant, mais l'exemple avec winston-mail vous montre pourquoi:
Par exemple, supposons que
[email protected]
ait spécifié"winston": "0.5.x"
dans son objet"dependencies"
, car il s'agit de la dernière version sur laquelle il a été testé. En tant que développeur d’applications, vous souhaitez disposer des éléments les plus récents et les plus performants. Vous devez donc rechercher les dernières versions dewinston
et dewinston-mail
, puis les mettre dans votre package.json.{ "dependencies": { "winston": "0.6.2", "winston-mail": "0.2.3" } }
Mais maintenant, l’exécution de l’installation de npm a pour résultat le graphe de dépendance inattendu de
├── [email protected] └─┬ [email protected] └── [email protected]
Dans ce cas, il est possible d'avoir plusieurs versions d'un package, ce qui poserait problème. Les dépendances entre homologues permettent 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 la description d'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 indiqué dans les articles
Un conseil : les exigences de dépendance entre pairs, contrairement à celles des dépendances régulières, doivent être indulgentes . Vous ne devez pas verrouiller vos dépendances entre homologues sur des versions de correctif spécifiques.
Par conséquent, les développeurs doivent suivre semver pour définir peerDependencies. Vous devriez ouvrir un problème pour le paquet grunt-steroids sur GitHub ...
peerDependencies
expliqué avec l'exemple le plus simple possible:
{
"name": "myPackage",
"dependencies": {
"foo": "^4.0.0",
"react": "^15.0.0"
}
}
{
"name": "foo"
"peerDependencies": {
"react": "^16.0.0"
}
}
exécuter npm install dans myPackage provoquera une erreur car il tente d’installer React version ^15.0.0
ET foo
qui n’est compatible qu’avec React ^16.0.0
.
peerDependencies ne sont PAS installés.