Esta documentación responde muy mal a mi pregunta. No entendí esas explicaciones. ¿Alguien puede decir en palabras más simples? ¿Quizás con ejemplos si es difícil elegir palabras simples?
EDIT también agregó peerDependencies , que está estrechamente relacionado y puede causar confusión.
Para guardar un paquete en package.json como dependencias de desarrollo:
npm install "$package" --save-dev Cuando ejecute npm install , instalará tanto devDependencies como dependencies . Para evitar instalar devDependencies , ejecute:
npm install --productionResumen de diferencias de comportamiento importantes:
Las dependencies están instaladas en ambos:
npm install desde un directorio que contiene package.jsonnpm install $package en cualquier otro directorio devDependencies son:
npm install en un directorio que contiene package.json , a menos que pase el indicador --production (vaya a favor de la respuesta de Gayan Charith ).npm install "$package" en cualquier otro directorio, a menos que le dé la opción --dev .npm install y tendrá que resolver la dependencia manualmente. Cuando se ejecuta, si falta la dependencia, aparece un error (mencionado por @nextgentech ). Esto lo explica muy bien: https://flaviocopes.com/npm-peer-dependencies/Transitividad (mencionado por Ben Hutchison ):
Las dependencies se 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.
devDependencies no se instala de forma transitiva. 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 analiza en la siguiente pregunta: Ventajas de bundledDependencies sobre las dependencias normales en npmoptionalDependencies (mencionado por Aidan Feldman ) se requieren dependencies para ejecutar, devDependencies solo 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 su raíz que contiene package.json y ejecuta:
npm install Dado que tiene la fuente real, está claro que desea desarrollarla, por lo que, de manera predeterminada, también se instalan las dependencies (dado que, por supuesto, debe ejecutar para desarrollar) y las dependencias devDependency .
Sin embargo, si solo es un usuario final que solo quiere instalar un paquete para usarlo, lo hará desde cualquier directorio:
npm install "$package" En ese caso, normalmente no desea las dependencias de desarrollo, por lo que solo obtiene lo que se necesita para usar el paquete: dependencies .
Si realmente desea instalar paquetes de desarrollo en ese caso, puede establecer la opción de configuración dev en true , posiblemente desde la línea de comando 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 3.0)
Fuente: https://nodejs.org/en/blog/npm/peer-dependencies/
Con las dependencias regulares, puede tener varias versiones de la dependencia: simplemente se instala dentro de los node_modules de la dependencia.
Por ejemplo, si dependency1 y dependency2 dependen de dependency3 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 complementos, sin embargo, son paquetes que normalmente no requieren el otro paquete, que se denomina host en este contexto. En lugar de:
Por ejemplo, si dependency1 y dependency2 peer dependen de dependency3 , el árbol del proyecto se verá así:
root/node_modules/ | +- dependency1/ | +- dependency2/ | +- dependency3 v1.0/ Esto sucede aunque nunca mencione dependency3 en su archivo package.json .
Creo que esta es una instancia 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á que:
grunt es una peer-dependencyrequire('grunt') está bajo tests/ : en realidad no lo usa el programa. Luego, cuando el usuario use un complemento, implícitamente requerirá el complemento del Gruntfile agregando una grunt.loadNpmTasks('grunt-contrib-uglify') , pero es grunt que el usuario llamará directamente.
Esto no funcionaría si cada complemento requiriera una versión diferente de Grunt.
Creo que la documentación responde bastante bien a la pregunta, tal vez no esté lo suficientemente familiarizado con los administradores de nodos/otros paquetes. Probablemente solo lo entiendo porque sé un poco sobre Ruby Bundler.
La línea clave es:
Estas cosas se instalarán al hacer el enlace npm o la instalación npm desde la raíz de un paquete y se pueden administrar como cualquier otro parámetro de configuración 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.Hay algunos módulos y paquetes solo necesarios para el desarrollo, que no son necesarios en producción. Como dice en la documentación :
Si alguien planea descargar y usar su módulo en su programa, probablemente no quiera o no necesite descargar y compilar el marco de prueba o documentación externo que usa. En este caso, es mejor enumerar estos elementos adicionales en un hash devDependencies.
Como ejemplo, mocha normalmente sería una dependencia de desarrollo, ya que las pruebas no son necesarias en producción, mientras que express sería una dependencia.
Si no desea instalar devDependencies, puede usar npm install --production
Estos son los paquetes que su paquete necesita para ejecutarse, por lo que se instalarán cuando las personas ejecuten
npm install PACKAGE-NAMEUn ejemplo sería si usara jQuery en su proyecto. Si alguien no tiene jQuery instalado, entonces no funcionaría. Para guardar como una dependencia, use
npm install --save Estas son las dependencias que usa en el desarrollo, pero no son necesarias cuando las personas las usan, por lo que cuando las personas ejecutan npm install , no las instalará ya que no son necesarias. Por ejemplo, si usa mocha para probar, las personas no necesitan mocha para ejecutarse, por lo que npm install no lo instala. Para guardar como una dependencia de desarrollo, use
npm install PACKAGE --save-devEstos se pueden usar si desea crear y publicar su propia biblioteca para que pueda usarse como una dependencia. Por ejemplo, si desea que su paquete se use como dependencia en otro proyecto, estos también se instalarán cuando alguien instale el proyecto que tiene su proyecto como dependencia. La mayoría de las veces no usará dependencias de pares.
En breve
Dependencias : npm install <package> --save-prod instala los paquetes requeridos por su aplicación en el entorno de producción.
DevDependencies - npm install <package> --save-dev instala paquetes requeridos solo para desarrollo y pruebas locales
Simplemente escribiendo npm install instala todos los paquetes mencionados en el paquete.json
así que si está trabajando en su computadora local, simplemente escriba npm install y continúe :)
Dependencias vs dependencias de desarrollo
Las dependencias de desarrollo son módulos que solo se requieren durante el desarrollo, mientras que las dependencias se requieren en tiempo de ejecución. Si está implementando su aplicación, se deben instalar las dependencias o, de lo contrario, su aplicación simplemente no funcionará. Las bibliotecas a las que llama desde su código que permite que el programa se ejecute pueden considerarse dependencias.
Por ejemplo, reaccionar, reaccionar - dom
Los módulos de dependencia de desarrollo no necesitan instalarse en el servidor de producción, ya que no desarrollará en esa máquina. Los compiladores que convierten su código en javascript, los marcos de prueba y los generadores de documentos pueden considerarse dependencias de desarrollo, ya que solo se requieren durante el desarrollo.
Por ejemplo, ESLint, Babel, webpack
@Para tu información,
mod-a dev-dependents: - mod-b dependents: - mod-c mod-d dev-dependents: - mod-e dependents: - mod-a ---- npm install mod-d installed modules: - mod-d - mod-a - mod-c ---- checkout the mod-d code repository npm install installed modules: - mod-a - mod-c - mod-eSi está publicando en npm, es importante que use el indicador correcto para los módulos correctos. Si es algo que su módulo npm necesita para funcionar, use el indicador "--save" para guardar el módulo como una dependencia. Si es algo que su módulo no necesita para funcionar pero es necesario para la prueba, entonces use el indicador "--save-dev".
# For dependent modulesnpm install dependent-module --save# For dev-dependent modules npm install development-module --save-devEncontré una explicación sencilla.
Respuesta corta:
dependencias "...son las que realmente necesita tu proyecto para poder trabajar en producción."
devDependencies "...son las que necesita durante el desarrollo".
peerDependencies "si desea crear y publicar su propia biblioteca para que pueda usarse como una dependencia"
Más detalles en esta publicación: https://code-trotter.com/web/dependencies-vs-devdependencies-vs-peerdependencies
peerDependencies no tenía mucho sentido para mí hasta que leí este fragmento de una publicación de blog sobre el tema que Ciro mencionó anteriormente :
Lo que [los complementos ] necesitan es una forma de expresar estas "dependencias" entre los complementos y su paquete de host. Una forma de decir: "Solo trabajo cuando estoy conectado a la versión 1.2.x de mi paquete de host, así que si me instala, asegúrese de que sea junto con un host compatible". A esta relación la llamamos dependencia entre pares.
peerDependencies son para complementos, bibliotecas que requieren una biblioteca "anfitrión" para realizar su función, pero pueden haber sido escritas antes de que se lanzara la última versión del host.
Es decir, si escribo PluginX v1 para HostLibraryX v3 y me voy, no hay garantía de que PluginX v1 funcione cuando se HostLibraryX v4 (o incluso HostLibraryX v3.0.1 ).
Desde el punto de vista del complemento, solo agrega funciones a la biblioteca del host. Realmente no "necesito" que el host agregue una dependencia a un complemento, y los complementos a menudo no dependen literalmente de su host. Si no tiene el host, el complemento no hace nada de manera inofensiva.
Esto significa que dependencies no son realmente el concepto correcto para los complementos.
Peor aún, si mi host fuera tratado como una dependencia, terminaríamos en esta situación que menciona la misma publicación de blog (editada un poco para usar el host y el complemento inventados de esta respuesta):
Pero ahora, [si tratamos la versión contemporánea de HostLibraryX como una dependencia para PluginX,] ejecutar
npm installda como resultado el gráfico de dependencia inesperado de├── HostLibraryX@4.0.0 └─┬ PluginX@1.0.0 └── HostLibraryX@3.0.0Dejaré a su imaginación las fallas sutiles que provienen del complemento que usa una API [HostLibraryX] diferente a la aplicación principal.
... ese es el objetivo de los complementos. Ahora bien, si el host fuera lo suficientemente amable como para incluir información de dependencia para todos sus complementos, eso resolvería el problema, pero también introduciría un gran problema cultural nuevo : ¡la administración de complementos!
El objetivo de los complementos es que pueden emparejarse de forma anónima. En un mundo perfecto, hacer que el host los maneje a todos sería limpio y ordenado, pero no vamos a requerir que las bibliotecas arreen a los gatos.
En cambio, tenemos el concepto de ser pares. Ni el host ni el complemento se encuentran en el depósito de dependencia del otro. Ambos viven en el mismo nivel del grafo de dependencia.
Si soy PluginX v1 y espero un par de (es decir, tengo una dependencia de pares de ) HostLibraryX v3 , lo diré. Si se actualizó automáticamente a la última HostLibraryX v4 (tenga en cuenta que es la versión 4 ) Y tiene instalado el Plugin v1 , necesita saberlo, ¿verdad?
npm no puede manejar esta situación por mí --
"Oye, ¡veo que estás usando
PluginX v1! Estoy degradando automáticamenteHostLibraryXde v4 a v3, kk?"
... o...
"Oye, veo que estás usando
PluginX v1. Eso esperaHostLibraryX v3, que dejaste en el polvo durante tu última actualización. Para estar seguro, ¡estoy desinstalando automáticamentePlugin v1! 1!
¡¿Qué tal no, npm?!
Entonces npm no lo hace. Le alerta sobre la situación y le permite averiguar si HostLibraryX v4 es un par adecuado para Plugin v1 .
Una buena gestión de peerDependency en los complementos hará que este concepto funcione de manera más intuitiva en la práctica. De la entrada del blog , una vez más...
Un consejo: los requisitos de dependencia entre pares, a diferencia de los de las dependencias regulares, deben ser indulgentes. No debe bloquear las dependencias de sus compañeros a versiones de parches específicas. Sería realmente molesto si un par de complementos de Chai dependiera de Chai 1.4.1, mientras que otro dependiera de Chai 1.5.0, simplemente porque los autores fueron perezosos y no dedicaron tiempo a averiguar la versión mínima real de Chai que son. compatible con.
Cuando intente distribuir un paquete npm, debe evitar el uso dependencies . En su lugar, debe considerar agregarlo a peerDependencies .
La mayoría de las veces, las dependencias son solo un montón de bibliotecas que describen su ecosistema. A menos que realmente esté usando una versión específica de una biblioteca, debe permitir que el usuario elija si instalar o no esa biblioteca y qué versión elegir al agregarla a las dependencias de pares.
Me gustaría agregar a la respuesta mi punto de vista sobre estas explicaciones de dependencias
dependencies se usan para uso directo en su base de código, cosas que generalmente terminan en el código de producción o fragmentos de códigodevDependencies se utilizan para el proceso de compilación, herramientas que lo ayudan a administrar cómo terminará el código final, módulos de prueba de terceros (por ejemplo, material de paquete web)Una explicación simple que me dejó más claro es:
Cuando implementa su aplicación, los módulos en las dependencias deben instalarse o su aplicación no funcionará. Los módulos en devDependencies no necesitan instalarse en el servidor de producción ya que no está desarrollando en esa máquina. Enlace
dependencias
Dependencias que su proyecto necesita para ejecutarse, como una biblioteca que proporciona funciones a las que 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 de lodash.
devDependencias
Dependencias que solo necesita durante el desarrollo o el lanzamiento, como compiladores que toman su código y lo compilan en javascript, marcos de prueba o generadores de documentación.
No se instalan transitivamente (si A depende de B dev-depende de C, npm install en A solo instalará B).
Ejemplo: gruñido: tu proyecto usa gruñido para construirse a sí mismo.
peerDependencies
Dependencias que su proyecto vincula 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) tenga una dependencia en el proyecto al que se conecta. Entonces, si crea un complemento C que agrega funcionalidad a la biblioteca B, entonces alguien que haga un proyecto A deberá tener una dependencia en B si tiene una dependencia en C.
No están instalados (a menos que npm < 3), solo se verifican.
Ejemplo: grunt: su proyecto agrega funcionalidad a grunt y solo se puede usar en proyectos que usan grunt.
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#devdependencias
dependencias : paquetes que su proyecto/paquete necesita para funcionar en producción.
devDependencies : paquetes que su proyecto/paquete necesita para funcionar durante el desarrollo pero que no son necesarios en producción (p. ej.: paquetes de prueba)
peerDependencies : paquetes con los que su proyecto/paquete necesita trabajar en conjunto ("colaborando" con ellos) o como base, útil principalmente cuando está desarrollando un complemento/componente para saber con qué versión del paquete "principal" su complemento Se supone que /component funciona con (por ejemplo: React 16)
La diferencia entre estos dos es que devDependencies son módulos que solo se requieren durante el desarrollo , mientras que las dependencias son módulos que también se requieren en tiempo de ejecución .
Para guardar una dependencia como devDependency en la instalación, debemos hacer una #npm install --save-dev , en lugar de solo una #npm install --save
Una buena abreviatura para instalar una devDependency que me gusta usar es #npm i -D . La abreviatura para guardar una dependencia normal es -S en lugar de -D.
Algunos buenos ejemplos de dependencias que serían necesarias en tiempo de ejecución incluyen React, Redux, Express y Axios .
Algunos buenos ejemplos de cuándo instalar devDependencies serían Nodemon, Babel, ESLint y marcos de prueba como Chai, Mocha, Enzyme, etc.
Se requieren dependencias para ejecutar, devDependencies solo para desarrollar