node.js - last - ¿Por qué usar dependencias entre pares en npm para complementos?
npm install--save (3)
¿Por qué, por ejemplo, un plugin de Grunt define su dependencia en grunt como " dependencias de pares "?
¿Por qué no puede el complemento simplemente tener a Grunt como su propia dependencia en grunt-plug / node_modules ?
Las dependencias entre pares se describen aquí: https://nodejs.org/en/blog/npm/peer-dependencies/
Pero realmente no lo entiendo
Ejemplo
Estoy trabajando con AppGyver Steroids en este momento, que usa tareas de Grunt para crear mis archivos fuente en una carpeta / dist / para que se publiquen en un dispositivo local. Soy bastante nuevo en npm y gruñido, así que quiero comprender completamente lo que está pasando.
Hasta ahora entiendo esto:
[rootfolder] /package.json le dice a npm que depende del paquete npm de grunt-steroids
para el desarrollo:
"devDependencies": {
"grunt-steroids": "0.x"
},
Bueno. La ejecución de la instalación de npm en [rootfolder] detecta la dependencia e instala los esteroides roncos en [rootfolder] / node_modules / grunt-steroids .
Npm luego lee [rootfolder] /node_modules/grunt-steroids/package.json para que pueda instalar dependencias propias de grunt-steroids
roncos .
"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"
},
Los paquetes de " dependencias " están instalados en [rootfolder] / node_modules / grunt-esteroids / node_modules, lo cual es lógico para mí.
Las " devDependencies " no están instaladas, lo cual estoy seguro es controlado por npm detectando que estoy tratando de usar grunt-steroids
, y no desarrollo en él.
Pero luego tenemos las " peerDependencies ".
Estos están instalados en [rootfolder] / node_modules , y no entiendo por qué hay y no en [rootfolder] / node_modules / grunt-esteroids / node_modules para evitar conflictos con otros plugins grunt (o lo que sea)?
Como dice el Blueprint oficial. Si ves errores de DEPENDENCIA DE PARPADEO, deberías instalar React manualmente:
npm install --save react react-dom react-addons-css-transition-group
lo puedes encontrar here
Te recomendaría que leyeras el artículo otra vez primero. Es un poco confuso pero el ejemplo con winston-mail te muestra la respuesta por qué:
Por ejemplo, imaginemos que winston-mail 0.2.3 especificó "winston": "0.5.x" en su hash "dependencias", ya que esa es la última versión con la que se probó. Como desarrollador de aplicaciones, desea las últimas y mejores cosas, por lo que busca las últimas versiones de winston y de winston-mail, colocándolas en su paquete. Json como
{ "dependencies": { "winston": "0.6.2", "winston-mail": "0.2.3" } }
Pero ahora, la ejecución de los resultados de instalación de npm en el gráfico de dependencia inesperado de
├── [email protected] └─┬ [email protected] └── [email protected]
En este caso, es posible tener múltiples versiones de un paquete que causarían algunos problemas. PeerDependencies permite a los desarrolladores de npm asegurarse de que el usuario tenga el módulo específico (en la carpeta raíz). Pero está en lo correcto con el hecho de que describir una versión específica de un paquete generaría problemas con otros paquetes que usan otras versiones. Este problema tiene que ver con los desarrolladores de npm, como dicen los artículos
Un consejo: los requisitos de dependencia de los pares, a diferencia de los que tienen las dependencias regulares, deberían ser indulgentes. No debe bloquear sus dependencias entre pares en versiones de parches específicos.
Por lo tanto, los desarrolladores deben seguir a semver para definir peerDependencies. Debería abrir un problema para el paquete grunt-steriods en github ...
TL; DR: peerDependencies
es para dependencias que están expuestas (y se espera que sean utilizadas por) el código de consumo, a diferencia de las dependencias "privadas" que no están expuestas, y son solo un detalle de implementación.
El problema resuelve las dependencias entre iguales
El sistema de módulos de npm es jerárquico. Una gran ventaja para escenarios más simples es que cuando instala un paquete npm, ese paquete trae consigo sus propias dependencias para que funcione de la caja.
Pero los problemas surgen cuando:
- Tanto su proyecto como el módulo que está utilizando dependen del mismo otro módulo.
- Los tres módulos tienen que hablar entre ellos.
Ejemplo
Digamos que estás construyendo YourCoolProject
y estás usando JacksModule 1.0
y JillsModule 2.0
. Y supongamos que JacksModule
también depende de JillsModule
, pero en una versión diferente, digamos 1.0
. Siempre que esas 2 versiones no coincidan, no hay problema. El hecho de que JacksModule
esté utilizando JillsModule
debajo de la superficie es solo un detalle de implementación. Estamos JillsModule
dos veces, pero ese es un pequeño precio a pagar cuando obtenemos un software estable de JillsModule
.
Pero ahora supongamos que JacksModule
expone su dependencia de JillsModule
de alguna manera. Acepta una instanceof
objeto de JillsClass
por ejemplo ... ¿Qué sucede cuando creamos una new JillsClass
usando la versión 2.0
de la biblioteca y la pasamos a jacksFunction
? ¡Todo el infierno se desatará! Cosas simples como la jillsObject instanceof JillsClass
repente devolverá false
, porque jillsObject
es en realidad una instancia de otra JillsClass
, la versión 2.0
.
Cómo las dependencias entre pares resuelven esto
Ellos dicen npm
Necesito este paquete, pero necesito la versión que es parte del proyecto, no una versión privada para mi módulo.
Cuando npm vea que su paquete se está instalando en un proyecto que no tiene esa dependencia, o que tiene una versión incompatible , advertirá al usuario durante el proceso de instalación.
¿Cuándo debería usar las dependencias entre pares?
- Cuando está creando una biblioteca para ser utilizada por otros proyectos, y
- Esta biblioteca está usando alguna otra biblioteca, y
- Usted espera / necesita que el usuario trabaje con esa otra biblioteca también
Los escenarios comunes son complementos para marcos más grandes. Piense en cosas como Gulp, Grunt, Babel, Mocha, etc. Si escribe un plugin de Gulp, quiere que ese complemento funcione con el mismo Gulp que usa el proyecto del usuario, no con su propia versión privada de Gulp.