¿Cuál es la diferencia entre dependencias, devDependencies y peerDependencies en el archivo NPM package.json?

Resuelto Vitalii Korsakov asked hace 11 años • 16 respuestas

Esta documentación responde muy mal a mi pregunta. No entendí esas explicaciones. ¿Alguien puede decirlo con palabras más simples? ¿Quizás con ejemplos si es difícil elegir palabras sencillas?

También se agregó peerDependencies, que está estrechamente relacionado y puede causar confusión.

Vitalii Korsakov avatar Sep 18 '13 21:09 Vitalii Korsakov
Aceptado

Resumen de diferencias de comportamiento importantes:

  • dependenciesestán instalados en ambos:

    • npm installde un directorio que contienepackage.json
    • npm install $packageen cualquier otro directorio
  • devDependenciesson:

    • también instalado en npm installun directorio que contiene package.json, a menos que pase la --productionbandera (vote la respuesta de Gayan Charith ), o si la NODE_ENV=productionvariable de entorno está configurada
    • no está instalado npm install "$package"en ningún otro directorio, a menos que le dé la --devopción.
    • no se instalan transitivamente.
  • peerDependencies:

    • anteriores a 3.0: siempre se instalan si faltan y generan un error si diferentes dependencias utilizarían varias versiones incompatibles de la dependencia.
    • Se espera que comience en 3.0 (no probado): envíe una advertencia si falta npm instally deberá resolver la dependencia usted mismo manualmente. Al ejecutar, si falta la dependencia, aparece un error (mencionado por @nextgentech ). Esto lo explica muy bien: https://flaviocopes.com/npm-peer-dependencies/
    • en la versión 7, las peerDependencies se instalan automáticamente a menos que exista un conflicto de dependencia ascendente que no se pueda resolver automáticamente.
  • Transitividad (mencionada por Ben Hutchison ):

    • dependenciesse instalan de forma transitiva: si A requiere B y B requiere C, entonces C se instala; de lo contrario, B no podría funcionar y A tampoco.

    • devDependenciesno está instalado transitivamente. Por ejemplo, no necesitamos probar B para probar A, por lo que las dependencias de prueba de B pueden omitirse.

Opciones relacionadas que no se analizan aquí:

  • bundledDependenciesque se analiza en la siguiente pregunta: Ventajas de las dependencias incluidas sobre las dependencias normales en npm
  • optionalDependencies(mencionado por Aidan Feldman )

devDependencias

dependenciesse requieren para ejecutar, devDependenciessolo para desarrollar, por ejemplo: pruebas unitarias, transpilación de CoffeeScript a JavaScript, minificación, ...

Si va a desarrollar un paquete, lo descarga (por ejemplo, a través de git clone), va a la raíz que contiene package.jsony ejecuta:

npm install

Dado que tiene la fuente real, está claro que desea desarrollarla, por lo que, de forma predeterminada, también se instalan tanto dependencies(ya que, por supuesto, debe ejecutar para desarrollar) como las devDependencydependencias.

Sin embargo, si sólo eres un usuario final que sólo quiere instalar un paquete para usarlo, lo harás desde cualquier directorio:

npm install "$package"

En ese caso, normalmente no deseas las dependencias de desarrollo, por lo que solo obtienes lo que necesitas para usar el paquete: dependencies.

Si realmente desea instalar paquetes de desarrollo en ese caso, puede configurar la devopción de configuración en true, posiblemente desde la línea de comando como:

npm install "$package" --dev

La opción está falsepor defecto ya que este es un caso mucho menos común.

dependencias entre pares

(Probado antes de 3.0)

Fuente: https://nodejs.org/en/blog/npm/peer-dependencies/

Con las dependencias normales, puedes tener múltiples versiones de la dependencia: simplemente se instala dentro node_modulesde la dependencia.

Por ejemplo, si dependency1y dependency2ambos dependen dependency3de diferentes versiones, el árbol del proyecto se verá así:

root/node_modules/
                 |
                 +- dependency1/node_modules/
                 |                          |
                 |                          +- dependency3 v1.0/
                 |
                 |
                 +- dependency2/node_modules/
                                            |
                                            +- dependency3 v2.0/

Los complementos, sin embargo, son paquetes que normalmente no requieren el otro paquete, que en este contexto se denomina host . En cambio:

  • Los complementos son requeridos por el anfitrión.
  • Los complementos ofrecen una interfaz estándar que el anfitrión espera encontrar.
  • El usuario solo llamará directamente al host, por lo que debe haber una única versión del mismo.

Por ejemplo, si dependency1un dependency2par depende de dependency3, el árbol del proyecto se verá así:

root/node_modules/
                 |
                 +- dependency1/
                 |
                 +- dependency2/
                 |
                 +- dependency3 v1.0/

Esto sucede aunque nunca lo menciones dependency3en tu package.jsonexpediente.

Creo que este es un ejemplo del patrón de diseño de Inversión de Control .

Un ejemplo prototípico de dependencias entre pares es Grunt, el host y sus complementos.

Por ejemplo, en un complemento de Grunt como https://github.com/gruntjs/grunt-contrib-uglify , verás eso:

  • gruntes unpeer-dependency
  • el único require('grunt')está debajo tests/: en realidad el programa no lo utiliza.

Luego, cuando el usuario use un complemento, implícitamente requerirá el complemento agregando Gruntfileuna grunt.loadNpmTasks('grunt-contrib-uglify')línea, pero gruntel usuario lo llamará directamente.

Esto no funcionaría si cada complemento requiriera una versión diferente de Grunt.

Manual

Creo que la documentación responde bastante bien a la pregunta, tal vez simplemente no esté lo suficientemente familiarizado con los administradores de nodos/otros paquetes. Probablemente solo lo entiendo porque sé un poco sobre el paquete Ruby.

La línea clave es:

Estas cosas se instalarán al realizar npm link o npm install desde la raíz de un paquete y se pueden administrar como cualquier otro parámetro de configuración de npm. Consulte npm-config(7) para obtener más información sobre el tema.

Y luego, en npm-config(7), busque dev:

Default: false
Type: Boolean

Install dev-dependencies along with packages.

Si no desea instalar devDependencies, puede utilizarnpm install --production

Gayan Charith avatar Jul 05 '2015 10:07 Gayan Charith

dependencias
Dependencias que su proyecto necesita para ejecutarse, como una biblioteca que proporciona funciones que usted llama desde su código.
Se instalan de forma transitiva (si A depende de B depende de C, npm install en A instalará B y C).
Ejemplo: lodash: su proyecto llama a algunas funciones lodash.

devDependencies
Dependencias que solo necesitas durante el desarrollo o el lanzamiento, como compiladores que toman tu código y lo compilan en javascript, marcos de prueba o generadores de documentación.
No se instalan de forma transitiva (si A depende del desarrollo B, depende de C, npm install en A instalará B solo).
Ejemplo: gruñido: su proyecto utiliza gruñido para construirse.

peerDependencies
Dependencias que su proyecto conecta o modifica en el proyecto principal, generalmente un complemento para alguna otra biblioteca o herramienta. Solo pretende ser una verificación, asegurándose de que el proyecto principal (proyecto que dependerá de su proyecto) dependa del proyecto al que se conecta. Entonces, si crea un complemento C que agrega funcionalidad a la biblioteca B, entonces alguien que realice un proyecto A necesitará tener una dependencia de B si tiene una dependencia de C.
No están instalados (a menos que npm <3), solo están comprobado.
Ejemplo: gruñido: su proyecto agrega funcionalidad a gruñido y solo puede usarse en proyectos que usan gruñido.

Esta documentación explica muy bien las dependencias entre pares: https://nodejs.org/en/blog/npm/peer-dependencies/

Además, la documentación de npm se ha mejorado con el tiempo y ahora tiene mejores explicaciones de los diferentes tipos de dependencias: https://github.com/npm/cli/blob/latest/docs/content/configuring-npm/package-json .md#dependenciasdev

qwertzguy avatar Sep 05 '2017 17:09 qwertzguy

Como ejemplo, mocha normalmente sería una dependencia dev, ya que las pruebas no son necesarias en producción, mientras que express sería una dependencia.

Dan Kohn avatar Sep 18 '2013 18:09 Dan Kohn

Para guardar un paquete en package.json como dependencias de desarrollo:

npm install "$package" --save-dev

Cuando lo ejecute npm install, instalará tanto devDependenciescomo dependencies. Para evitar la instalación devDependencies, ejecute:

npm install --production
Mohammed Safeer avatar Jan 08 '2016 06:01 Mohammed Safeer