Esta documentación responde muy mal a mi pregunta. No he entendido las explicaciones. ¿Puede alguien decirlo con palabras más sencillas? ¿Tal vez con ejemplos si es difícil elegir palabras sencillas?
EDIT también se ha añadido peerDependencies
, que está estrechamente relacionado y podría causar confusión.
Resumen de las diferencias de comportamiento importantes:
dependencias
se instalan en ambos:npm install
desde un directorio que contenga package.json
npm install $paquete
en cualquier otro directoriodevDependencies
se instalannpm install
en un directorio que contenga package.json
, a menos que se pase la bandera --production
(ir a upvote respuesta de Gayan Charith).npm install "$package"
en cualquier otro directorio, a menos que le des la opción --dev
.peerDependencies
:npm install
, y tienes que resolver la dependencia tú mismo manualmente. Cuando se ejecuta, si falta la dependencia, se obtiene un error (mencionado por @nextgentech)devDependencias
no se instalan de forma transitoria. Por ejemplo, no necesitamos probar B para probar A, por lo que las dependencias de prueba de B pueden omitirse.
Opciones relacionadas no discutidas aquí:bundledDependencies
que se discute en la siguiente pregunta: https://stackoverflow.com/questions/11207638/advantages-of-bundleddependencies-over-normal-dependencies-in-npm?lq=1optionalDependencies
(mencionado por Aidan Feldman)Las dependencias
son necesarias para ejecutar, las devDependencias
sólo para desarrollar, por ejemplo: pruebas unitarias, transpilación de CoffeeScript a JavaScript, minificación, ...
Si vas a desarrollar un paquete, lo descargas (por ejemplo vía git clone
), vas a su raíz que contiene package.json
, y ejecutas:
npm install
Ya que tienes el código fuente real, está claro que quieres desarrollarlo, así que por defecto, también se instalan las dependencias dependencies
(ya que debes, por supuesto, ejecutar para desarrollar) y devDependency
.
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 quieres las dependencias de desarrollo, así que sólo obtienes lo necesario para usar el paquete: dependencias
.
Si realmente quieres instalar paquetes de desarrollo en ese caso, puedes establecer la opción de configuración dev
a true
, posiblemente desde la línea de comandos como:
npm install "$package" --dev
La opción es false
por defecto ya que este es un caso mucho menos común.
(Probado antes de la versión 3.0)
Fuente: https://nodejs.org/en/blog/npm/peer-dependencies/
Con las dependencias regulares, puedes tener múltiples versiones de la dependencia: simplemente se instala dentro del node_modules
de la dependencia.
Por ejemplo, si la dependencia1
y la dependencia2
dependen de la dependencia3
en 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 plugins, sin embargo, son paquetes que normalmente no requieren el otro paquete, que se llama el host en este contexto. En su lugar
dependencia1
y dependencia2
dependen de dependencia3
, el árbol del proyecto se verá comoroot/node_modules/
|
+- dependency1/
|
+- dependency2/
|
+- dependency3 v1.0/
Esto sucede a pesar de que nunca se menciona dependencia3
en su archivo package.json
.
Creo que esto es un ejemplo del patrón de diseño Inversión de Control.
Un ejemplo prototípico de dependencias entre pares es Grunt, el anfitrión, y sus plugins.
Por ejemplo, en un plugin de Grunt como https://github.com/gruntjs/grunt-contrib-uglify, verás que
grunt
es una dependencia entre pares
.require('grunt')
está en tests/
: no es usado realmente por el programa.
Entonces, cuando el usuario utilice un plugin, requerirá implícitamente el plugin desde el Gruntfile
añadiendo una línea grunt.loadNpmTasks('grunt-contrib-uglify')
, pero es grunt
el que el usuario llamará directamente.
Esto no funcionaría entonces si cada plugin requiere una versión diferente de Grunt.Creo que la documentación responde bastante bien a la pregunta, tal vez no estés lo suficientemente familiarizado con node / otros gestores de paquetes. Probablemente sólo lo entiendo porque sé un poco sobre Ruby bundler. La línea clave es:
Estas cosas se instalarán al hacer npm link o npm install desde la raíz de un paquete y se pueden gestionar como cualquier otro parámetro de configuración de npm. Ver npm-config(7) para más información sobre el tema. Y luego en npm-config(7) encontrar
dev
:
Default: false
Type: Boolean
Install dev-dependencies along with packages.
Hay algunos módulos y paquetes sólo necesarios para el desarrollo, que no son necesarios en producción. Como se dice en la documentación:
Si alguien está planeando descargar y usar tu módulo en su programa, entonces probablemente no quiera o necesite descargar y construir el framework externo de pruebas o de documentación que utilizas. En este caso, es mejor listar estos elementos adicionales en un hash devDependencias.