Cli: [FUNCIÓN] No elimine node_modules en npm ci

Creado en 6 dic. 2019  ·  53Comentarios  ·  Fuente: npm/cli

Qué? Por qué

Realmente me gustaría ver una bandera como npm ci --keep para hacer una actualización incremental en nuestro servidor de compilación, ya que esto aceleraría mucho nuestras implementaciones. Como se sugirió antes en github y en la comunidad . La última actualización fue el 7 de octubre que estaba siendo revisada por el equipo de cli. ¿Alguien podría publicar una actualización sobre esto? :-)

Enhancement

Comentario más útil

Así es como me gustaría que funcionara en un mundo perfecto:

  • npm install - mismo comportamiento que hoy
  • npm install --from-lockfile - instalar desde el archivo de bloqueo (como hace ci )
  • npm install --clean - mismo comportamiento que npm install pero elimina el contenido node_modules
  • npm ci - un alias para npm install --from-lockfile --clean

Todos 53 comentarios

Esto no es lo que debe hacer ci / cleaninstall. El comportamiento actual es correcto. Lo que quiere usar es npm shrinkwrap .

Agregamos una actualización para evitar eliminar la _contenido_ (como se solicitó originalmente en esa publicación). El propósito del comando npm ci es eliminar todo para comenzar desde cero. Si desea conservar sus antiguos módulos node_modules, lo que necesita es npm i .

¡Gracias por tus respuestas! Lo siento por mi respuesta tardía. He mirado npm shrinkwrap pero ¿está destinado a ejecutarse en nuestro servidor de compilación para una integración continua? Al ejecutar este comando, cambia el nombre de mi package-lock.json a npm-shrinkwrap.json pero ¿qué debo ejecutar durante CI? ¿Solo npm install para tener una actualización incremental? ¿O debería ejecutar npm ci pero eso eliminará todos los paquetes nuevamente :-( Lo que estoy buscando es un comando que realice una actualización incremental pero instalará exactamente lo que está en nuestro package-lock.json

@claudiahdz; Tengo entendido que ejecutar npm install durante CI actualizará package-lock.json y eso podría significar que ejecutar la misma compilación un par de semanas después instalaría diferentes paquetes. ¿Eso es incorrecto?

PD: pensé que npm ci era la abreviatura de Integración continua

Como se menciona aquí: https://github.com/npm/npm/issues/20104#issuecomment -403321557

El comportamiento actual es problemático si está usando npm ci dentro de un contenedor Docker (que es bastante común para la integración continua) y tiene un montaje de enlace en node_modules

Provoca el siguiente error:

webpack_1   | npm ERR! path /var/www/project/docker-config/webpack-dev-devmode/node_modules
webpack_1   | npm ERR! code EBUSY
webpack_1   | npm ERR! errno -16
webpack_1   | npm ERR! syscall rmdir
webpack_1   | npm ERR! EBUSY: resource busy or locked, rmdir '/var/www/project/docker-config/webpack-dev-devmode/node_modules'

que luego resulta en abortar el contenedor Docker.

Sería estupendo tener una bandera --no-delete o si npm ci pudiera borrar el _contenido_ de node_modules pero no el directorio en sí.

ci = instalación limpia

Se esperaba esto. ¿Por qué no usas el npm i normal con un archivo de bloqueo?

Sería maravilloso tener un indicador --no-delete o si npm ci pudiera eliminar el contenido de node_modules pero no el directorio en sí.

rm -rf node_modules/* && npm i

ci = instalación limpia

Se esperaba esto. ¿Por qué no usa el npm i normal con un archivo de bloqueo?

... porque: https://docs.npmjs.com/cli/ci.html

Este comando es similar a npm-install, excepto que está destinado a ser utilizado en entornos automatizados como plataformas de prueba, integración e implementación Puede ser significativamente más rápido que una instalación normal de npm omitiendo ciertas funciones orientadas al usuario. También es más estricto que una instalación regular, lo que puede ayudar a detectar errores o inconsistencias causadas por los entornos locales instalados de forma incremental de la mayoría de los usuarios de npm.

Las instalaciones más rápidas y el enfoque de pizarra limpia lo hacen ideal para entornos de CI como el que mencioné anteriormente.

rm -rf módulos_nodo / * && npm i

Esto es lo que hago ahora, pero vea arriba el deseo de usar npm ci

Me parece razonable presentar un RFC solicitando un indicador de configuración que haga que npm ci elimine el contenido de node_modules y no el directorio en sí. Esto también es un problema para mí, ya que configuré Dropbox para ignorar selectivamente un directorio node_modules , pero si lo elimino, esa configuración selectiva desaparece y la próxima vez node_modules se crea, se sincroniza.

Me parece razonable presentar un RFC solicitando una marca de configuración que haga que npm ci elimine el _contents_ de node_modules y no el directorio en sí. Esto también es un problema para mí, ya que configuré Dropbox para ignorar selectivamente un directorio node_modules , pero si lo elimino, esa configuración selectiva desaparece y la próxima vez node_modules se crea, se sincroniza.

¿No es esto también lo que se describe en otro problema, para permitir que npm cree archivos para ignorar el directorio (para OSX Spotlight y otros)? Creo que también hubo otros que necesitan esta función.

ci = instalación limpia

Se esperaba esto. ¿Por qué no usas el npm i normal con un archivo de bloqueo?

npm i sería genial, pero solo si no cambiara el archivo de bloqueo. He visto que el package-lock.json se ha actualizado durante un npm i o ¿no debería suceder eso?

Apoyo esta característica. Como se indicó, npm i modifica package-lock.json. Una bandera sería la solución ideal.

lo mismo, una bandera sería genial

Apoyo esta característica. Como se indicó, npm i modifica package-lock.json. Una bandera sería la solución ideal.

¿Por qué no agregar una bandera para npm i entonces? Porque esto no tendría mucho sentido para ci = clean install en mi sentido.

¿Qué parte de la "instalación limpia" es incompatible con mantener intacto el directorio principal node_modules/ (mientras se realiza una instalación limpia del contenido real)?

Me doy cuenta de que CI no significa Integración Continua en este caso; pero una instalación limpia suele ser bastante útil en un entorno de integración continua, como deja claro la documentación.

Este comando es similar a npm-install, excepto que está destinado a ser utilizado en entornos automatizados como plataformas de prueba, integración e implementación continuas, o cualquier situación en la que desee asegurarse de que está realizando una instalación limpia de sus dependencias. Puede ser significativamente más rápido que una instalación normal de npm omitiendo ciertas funciones orientadas al usuario. También es más estricto que una instalación regular, lo que puede ayudar a detectar errores o inconsistencias causadas por los entornos locales instalados de forma incremental de la mayoría de los usuarios de npm.

npm ci está diseñado específicamente para usarse en entornos automatizados, muchas veces esto significa una configuración basada en Docker.

El comportamiento de eliminar el directorio node_module/ es problemático en una configuración basada en Docker, por las razones mencionadas en este hilo.

Por lo tanto, estamos solicitando una opción que haga que este comando sea útil para su propósito y entorno previstos.

Apoyo esta característica. Como se indicó, npm i modifica package-lock.json. Una bandera sería la solución ideal.

¿Por qué no agregar una bandera para npm i entonces? Porque esto no tendría mucho sentido para ci = clean install en mi sentido.

Tengo que hacer esta pregunta si hay otras diferencias entre npm install y npm ci si no, ¿por qué no están disponibles ambas opciones en npm install tal vez ci necesidades para convertirse en un alias como npm install --no-update-package-lock --clean-node-modules

El comportamiento de eliminar el directorio node_module/ es problemático en una configuración basada en Docker, por las razones mencionadas en este hilo.

En mi opinión, esto solo debería suceder una vez cuando se construye la imagen. Después de eso, npm i debe usarse durante el desarrollo.

tal vez ci necesita convertirse en un alias como npm install --no-update-package-lock --clean-node-modules

Personalmente, eso tiene más sentido para mí, banderas adicionales para el comando normal npm i .

Soy indiferente a cuál, y honestamente, demasiado n00b con js land para tener un argumento concreto de que debe ser ci , todo lo que sé es que no debería actualizar el package-lock.json y no debe eliminar node_modules

npm ci no actualiza el archivo de bloqueo, se instala desde el archivo de bloqueo. Esto se introdujo para realizar una instalación limpia porque antes se recomendaba a estas personas que rm -rf node_modules y ejecutaran npm i nuevamente. Y la gente de afaik quería que no cambiara el archivo de bloqueo, sino que se instalara desde él.

Así nació npm ci . Y también omite algunas cosas como la lista de paquetes instalados y el árbol y algunas cosas más.

Consulte https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable

Cubre un caso de uso específico.

Para otros casos de uso, debemos agregar nuevos indicadores a npm i con los que también podemos emular npm ci que es una solución más flexible y mejor que los indicadores de npm ci que aún deberían cubrir solo el caso de uso actual en mi humilde opinión. Lo que los usuarios solicitan aquí es un poco similar a yarn install --frozen-lockfile o yarn --frozen-lockfile .

De lo contrario, las banderas se distribuyen en npm ci , npm i y así sucesivamente, lo que lo hace un poco más difícil (documentación, código, ...). Al menos esto es lo que pienso. Pongámoslo en npm i t tienen formas más poderosas y flexibles de configurar su comportamiento.

Para otros casos de uso, deberíamos agregar nuevos indicadores a npm i con los que también podemos emular npm ci, que es una solución más flexible y mejor que los indicadores para npm ci, que aún debería cubrir solo el caso de uso actual en mi humilde opinión. Lo que los usuarios solicitan aquí es un poco similar a yarn install --frozen-lockfile o yarn --frozen-lockfile.

Estaría muy feliz si la función se agregara a npm i . ¿Debo actualizar la publicación original?

npm ci no actualiza el archivo de bloqueo, se instala desde el archivo de bloqueo. Esto se introdujo para realizar una instalación limpia porque antes se recomendaba a estas personas que rm -rf node_modules y ejecutaran npm i nuevamente. Y la gente de afaik quería que no cambiara el archivo de bloqueo, sino que se instalara desde él.

Así nació npm ci . Y también omite algunas cosas como la lista de paquetes instalados y el árbol y algunas cosas más.

Consulte https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable

Cubre un caso de uso específico.

Para otros casos de uso, debemos agregar nuevos indicadores a npm i con los que también podemos emular npm ci que es una solución más flexible y mejor que los indicadores de npm ci que aún deberían cubrir solo el caso de uso actual en mi humilde opinión. Lo que los usuarios solicitan aquí es un poco similar a yarn install --frozen-lockfile o yarn --frozen-lockfile .

¿Por qué rm -rf node_modules/* no califica como "limpieza"? La función solicitada aquí es muy similar a la presente en npm ci. En mi opinión, tiene más sentido agregar una bandera a npm ci, por lo que usa rm -rf node_modules/* lugar de rm -rf node_modules lugar de importar todo el comportamiento de npm ci a npm i.

Por cierto, este problema debería recibir más atención y los mantenedores deberían expresar sus opiniones y planes al respecto, el uso de Docker se usa básicamente siempre en CI (integración continua), que es uno de los principales casos de uso de npm ci.

Abra una RFC para este cambio, en lugar de un problema en este repositorio.

Para evitar confusiones, cambiaría el nombre de este problema como "vacío en lugar de eliminar el directorio node_modules en npm CI"

Mi intención con este problema nunca fue eliminar la carpeta node_modules o solo su contenido. Siempre fue para preservar el contenido de node_modules pero asegúrese de que esté actualizado y sincronizado con package-lock.json . Entonces, una actualización incremental que se adhiere al package-lock.json .

Tal vez me equivoque, pero creo que hay dos problemas aquí. ¿Quizás alguien podría iniciar otro problema o RFC sobre eliminar solo el contenido de node_modules en lugar de eliminar la carpeta por completo? ¿O me estoy perdiendo algo?

@Zenuka la razón por la que npm CI es rápido, y existe, es porque ignora el directorio node_modules existente, por lo que es bastante poco probable que eso cambie.

En nuestro caso de uso, creo que sería más rápido comprobar si la carpeta nodes_modules está actualizada o no. Y si no es así, solo actualice los paquetes que deberían actualizarse (como npm i hace) Tengo algunas VM dedicadas que se ejecutan como agentes de compilación, por lo que ejecuto una compilación y conservo la carpeta nodes_modules y todo su contenido debería ser más rápido que eliminar todo y volver a instalarlo. Ejecutamos nuestra compilación y pruebas para cambios de código mucho más que cambios en nuestro package.json o package-lock.json .

En nuestro caso de uso, creo que sería más rápido comprobar si la carpeta nodes_modules está actualizada o no.

Bueno, esto (el cálculo del árbol de paquetes) es lo que lleva más tiempo. Esta comprobación haría que npm ci realmente lento.

ejecutar una compilación y mantener la carpeta nodes_modules y todo su contenido debería ser más rápido que eliminar todo y volver a instalarlo.

Probablemente no, por eso se introdujo npm ci que omite lo que hace npm i (verifique el árbol de paquetes).

@Zenuka npm install ya es la forma más rápida posible de hacer lo que quieres. npm ci solo tiene un propósito: hacerlo más rápido, eliminando node_modules para que no tenga que calcular una diferencia.

Probablemente no, es por eso que se introdujo npm ci que omite lo que hace npm i (verifique el árbol de paquetes).

Probé esto solo en mi máquina (lo cual, por supuesto, no es una buena medida), pero ejecutando npm install en una carpeta node_modules actualizada termina en 10 segundos. Ejecutar npm ci lleva unos minutos. ¿Esperarías resultados diferentes?

Soy fanático de tu sugerencia de agregar una bandera para congelar el archivo de bloqueo con npm install .

Verificar que lo que hay en package-lock.json está realmente presente es muy rápido, incluso en Windows. Consulte https://github.com/fuzzykiller/verify-node-modules.

Verificar que no haya nada más en node_modules ciertamente tomaría un poco más de tiempo, pero probablemente aún menos de un segundo.

Sobre esta base, se podría crear fácilmente una versión incremental de npm ci . El árbol ya está calculado y guardado en package-lock.json , después de todo.

Además, básicamente la única razón por la que existe npm ci es para instalar lo que está en package-lock.json . Sin escabullirse en actualizaciones sorpresa, como hace npm install .

solo mis 2 centavos, personalmente cambié nuestra infraestructura a npm ci ya que también estaba harto de la implementación de una etiqueta vieja npm i no se adheriría al archivo de bloqueo ... así que si es en serio un problema tan grande para agregar la bandera en el nivel npm ci (que obtengo ... es clean install está haciendo lo que se le dice) entonces npm i REALLLLLYLYY necesita esta bandera. pero recuerdo haber investigado esto y también había un hilo problemático en el npm i que tenía más de 2 años (y aún estaba abierto) donde el equipo de npm sugirió que las personas usaran npm ci lol ... esto es un poco la razón por la que la gente se ha dado por vencida con NPM en el pasado y simplemente se ha pasado a la lana.

de nuevo, solo otra perspectiva de los desarrolladores

Puse mi voto para agregar la posibilidad de mantener los módulos: heavy_plus_sign:.

+1 aquí - como dijeron @phyzical y @fuzzykiller , no hay un "punto npm install y npm ci que MANTENGA node_modules, pero aún respete package-lock.json y corra más rápido.
Simplemente ejecute lo más rápido posible: busque dependencias de package-lock que ya existan en node_modules, y luego instale todo lo que falta ... sin actualizaciones, sin eliminación.

Personalmente, no me importa cuál sea ( install o ci ) que tenga esto, pero todo esto suena como que npm install debería tener banderas para todo y npm ci no necesita ser un comando separado.

Esto es algo frustrante, dado que npm ci se promocionó originalmente como la solución al mismo problema que plantea este problema.

El comportamiento original que varias personas querían para npm install era mirar package-lock.json lugar de package.json . Queríamos una bandera en npm install para activar ese comportamiento. Lo que obtuvimos en cambio fue npm ci , porque:

el package.json describe las dependencias requeridas de su proyecto. Si el archivo de bloqueo actual no puede satisfacerlos, el archivo de bloqueo debe ceder. El propósito del archivo de bloqueo es crear una instalación repetible en diferentes máquinas, no dejar obsoleto el package.json.

Bien. npm install no es el lugar adecuado para esa opción, npm ci es. Excepto que npm ci agrega comportamientos adicionales (limpiando la carpeta node_modules ) que evitan que sea una solución útil al problema original. Y la razón por la que no puede haber una bandera en npm ci ahora es porque:

ci = instalación limpia

Se esperaba esto. ¿Por qué no usa el npm i normal con un archivo de bloqueo?

Que ... bien. Realmente no me importa dónde se agregue la bandera. No tengo ningún interés en la filosofía subyacente detrás de la interfaz. Pero, ¿podría agregarse la bandera en algún lugar ?

Diablos, no plantearía objeciones incluso si la gente quisiera un tercer comando completamente separado, no podría importarme menos. Lo único que me importa es que 3 años después de que comenzara esta conversación sobre el respeto de package-lock.json para las instalaciones normales, todavía no hay forma de obtener el comportamiento que pedíamos originalmente.

En mi lugar de trabajo, hemos visto errores de actualizaciones de versiones menores y de corrección de errores para paquetes. Realmente solo queremos buscar esos errores durante las actualizaciones de paquetes intencionales, no queremos que nuestros entornos de desarrollo utilicen versiones de paquetes diferentes a las de nuestros entornos de producción. La coherencia es muy importante. Como quiera que alguien quiera llamarlo o donde quiera que alguien quiera ponerlo, queremos una forma rápida de obtener paquetes del archivo de bloqueo que tampoco nos obligue a realizar compilaciones de node-gyp para módulos ya instalados cada vez que ejecutar el comando.

Así es como me gustaría que funcionara en un mundo perfecto:

  • npm install - mismo comportamiento que hoy
  • npm install --from-lockfile - instalar desde el archivo de bloqueo (como hace ci )
  • npm install --clean - mismo comportamiento que npm install pero elimina el contenido node_modules
  • npm ci - un alias para npm install --from-lockfile --clean

@jdussouillez Esto es exactamente lo que debería suceder. ¡Muy bien dicho! Me encantaría ver implementada esta solución.

Es constantemente frustrante encontrarnos con este problema en el que tenemos que decidir entre la velocidad y la coherencia para una canalización de CI. Me he encontrado con él 3 o 4 veces por diferentes razones solo en los últimos 2 meses.

Esta característica sería excelente para Azure Pipelines y otras arquitecturas de nube.

https://docs.microsoft.com/en-us/azure/devops/pipelines/release/caching?view=azure-devops#tip

Debido a que npm ci elimina la carpeta node_modules para garantizar que se utilice un conjunto de módulos coherente y repetible, debe evitar almacenar en caché node_modules al llamar a npm ci.

Cierre: como mencionó @claudiahdz , enviamos una solución a este comportamiento en el que npm ci ya no elimina la carpeta node_nodules sí, sino solo su contenido (ref. Https://github.com/npm /libcipm/blob/latest/CHANGELOG.md#407-2019-10-09). Esto se envió en [email protected] el 21 de julio (ref. Https://github.com/npm/cli/blob/v6/CHANGELOG.md#6147-2020-07-21) y hemos mantenido la misma experiencia en npm@7 .

Si tiene un problema separado con npm ci o cualquier otro comando, utilice una de nuestras plantillas de problemas para presentar un error: https://github.com/npm/cli/issues/new/choose


Notas al margen ...

@jdussouillez agradece los comentarios; En términos de instalar directamente desde un archivo de bloqueo, puede hacerlo hoy con la bandera --package-lock-only (ex. npm install --package-lock-only ). En términos de agregar una bandera --clean a install , no creo que esto agregue mucho valor, pero podría estar equivocado. Si está convencido de ello, nos encantaría que envíe una RFC a https://github.com/npm/rfcs

El comentario hecho por @claudiahdz hace casi un año parece estar relacionado con asegurarse de que el comportamiento de npm ci sea ​​eliminar el contenido node_modules , en lugar de la carpeta en sí. Lo cual es útil al montarlo en un contenedor docker (por ejemplo), pero aún así no cambia el resultado final: npm ci descargará todas las dependencias desde cero.

El uso de npm install --package-lock-only parece estar haciendo exactamente lo contrario de lo que trata el problema original (si lo entiendo correctamente): solo actualizará el archivo package-lock.json y no descargará ninguna dependencia.

Lo que entiendo del problema original es la necesidad de tener una opción que obtenga un estado actual de la carpeta node_modules y un archivo package-lock.json , y descargue solo los paquetes necesarios para obtener el node_modules versiones para que coincidan con package-lock.json . Así que será mucho más rápido que descargar todo cada vez, con el mismo resultado neto al final.

¿No es eso lo que siempre hace npm install ?

¿No es eso lo que siempre hace npm install ?

HASTA DONDE SE -
npm install resolverá todas las dependencias de acuerdo con el archivo package.json (ignorando el package-lock.json ), compare con lo que está actualmente en la carpeta node_modules y descargue el dependencias que deben descargarse para cumplir con los requisitos. También actualizará el package-lock.json consecuencia.

Definitivamente no ignora el archivo de bloqueo, solo tiene en cuenta el árbol existente, que npm ci no lo hace.

Tienes razón, lo siento.
Lo recordé incorrectamente (¿tal vez ese fue el comportamiento en el pasado?). Acabo de hacer algunas pruebas con un árbol de depuración simple, y cuando el archivo package-lock.json está presente, npm i instala exactamente las versiones que especifica y no cambia nada. Este era el comportamiento que estaba buscando, así que estoy contento con él. 👍
Pido disculpas por publicar sobre un problema cerrado.

Mi solicitud original fue de hecho lo que describe ATGardner:

Lo que entiendo del problema original es la necesidad de tener una opción que obtenga un estado actual de la carpeta node_modules y un archivo package-lock.json , y descargue solo los paquetes necesarios para obtener el node_modules versiones para que coincidan con package-lock.json . Así que será mucho más rápido que descargar todo cada vez, con el mismo resultado neto al final.

Mi experiencia con npm install es que a veces actualiza el archivo package-lock.json . Probé esto nuevamente esta mañana con un repositorio que no había actualizado en un tiempo y ejecuté git pull y npm i . En realidad, esta vez no actualizó ninguna versión, solo agregó algunas dependencias y paquetes adicionales.
image
Desafortunadamente, este es un repositorio privado, pero ¿tal vez alguien más como un repositorio público reproducible? Donde hay varias confirmaciones y cambiar entre ellas hace que npm install actualice el package-lock.json ?

Me doy cuenta de que podría haber algún error de usuario involucrado al no cometer el package-lock.json al actualizar el package.json pero mis colegas saben que también deberían actualizar el package-lock.json . Voy a investigar esto.

No pude obtener mi ejemplo simple para que npm i cambie el archivo package-lock.json . Pero lo probaré un poco más.

Si npm i siempre termina descargando exactamente las mismas versiones especificadas en package-lock.json , manteniendo tanto como pueda del actual node_modules , ¿por qué necesitaría ejecutar npm ci ? ¿Cuál sería el beneficio de eliminar todo antes de volver a descargar?

Pido disculpas de nuevo por no ser este el lugar para esta discusión. ¿Hay algún otro lugar más preferible?

Todavía no lo entiendo. Si el estado de node_modules después de ejecutar npm i coincide exactamente con package-lock.json , y el estado de node_modules después de ejecutar npm ci tiene exactamente lo mismo resultado final: en casi todos los escenarios, suponiendo que la computadora en la que está construyendo ya tenga algunas / la mayoría de las dependencias en la carpeta, ¿ npm i no sería más rápido? Simplemente no descargará lo que ya está presente localmente y coincide con la versión requerida.

¿Por qué prefiero eliminar y descargar todo desde cero?

No, npm ci sigue siendo más rápido ya que no vuelve a comprobar el departamento, algunos resultados de la consola no se realizan.

¿Por qué prefiero eliminar y descargar todo desde cero?

Para evitar problemas y ci es para entornos específicos como implementaciones.
Creo que los documentos ya mencionan las diferencias.

Puede ser significativamente más rápido que una instalación normal de npm omitiendo ciertas funciones orientadas al usuario. También es más estricto que una instalación regular, lo que puede ayudar a detectar errores o inconsistencias causadas por los entornos locales instalados de forma incremental de la mayoría de los usuarios de npm.

Consulte también https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable

npm ci es aún más rápido.

Por lo tanto, cuando se usa npm i , el tiempo que se tarda en leer el node_modules actual y averiguar qué paquetes deben descargarse es significativamente mayor que el tiempo que se tarda en descargar todos los paquetes de npm. servidores? Me encantaría ver un experimento real que lo mida.

Y tampoco entiendo este párrafo -

npm ci bypasses a package’s package.json to install modules from a package’s lockfile. This ensures reproducible builds—you are getting exactly what you expect on every install.

¿No acabamos de concluir aquí mismo que la ejecución de npm i usa las versiones exactas en el archivo package-lock.json , y el estado de node_modules después de la ejecución es idéntico al estado en que lo haría? estar después de ejecutar npm ci ? Por lo tanto, las compilaciones serán igualmente reproducibles.

ACTUALIZAR:

He realizado la siguiente prueba -
Creé un nuevo proyecto create-react-app . Después de completar su inicialización, tenía un package.json con 7 dependencias directas y un package-lock.json que contenía paquetes de 1982.
En este estado ( node_modules contiene todas las dependencias) - ejecutar npm i toma

real    0m2.548s
user    0m2.659s
sys     0m0.182s

Cuando eliminé una sola carpeta de paquete ( node_modules/babel-eslint ) y luego ejecuté npm i nuevamente, tomó

real    0m3.295s
user    0m3.543s
sys     0m0.434s

para volver a descargar la dependencia que falta

Cuando eliminé toda la carpeta node_moduels y ejecuté npm i nuevamente, tomó

real    0m16.701s
user    0m19.251s
sys     0m10.379s

Cuando ejecuté npm ci , me tomó

real    0m20.997s
user    0m23.844s
sys     0m14.857s

Esto no difirió mucho cuando intenté eliminar un solo paquete, o incluso eliminar toda la carpeta node_modules manualmente antes de la llamada. No fue sorprendente, ya que npm ci comienza eliminando el contenido de node_modules todos modos.

Después de cada ejecución, ejecuté diff -q -r node_modules_orig/ node_modules/ para asegurarme de que el resultado sea idéntico a las dependencias originales. Siempre lo fue.

Entonces, para concluir, parece que usar npm ci toma ~ 21 segundos en mi máquina, independientemente del estado actual de node_modules . Usar npm i en un proyecto recientemente clonado (sin node_modules ) toma ~ 18 segundos y ejecutarlo en un proyecto que no ha cambiado de dependencias (el actual node_modules coincide con las dependencias requeridas ) tarda ~ 3 segundos.

Entonces, ¿cuándo sería preferible usar npm ci ? No parece más rápido (aunque, por supuesto, esta es solo una prueba), y el resultado final es idéntico a npm i , por lo que la compilación posterior sería igual de confiable.

npm ci es preferible cuando necesita _exactamente_ lo que está en package-lock.json y nada más. npm i no garantiza que instalará exactamente lo que está en package-lock.json . Esto es por diseño. Si bien package-lock.json es una entrada para npm i , también es una salida.

Creo que solo quedan unos pocos casos en los que npm i instalaría algo diferente (y por lo tanto modificaría package-lock.json ), como quizás versiones de paquetes que se eliminaron temporalmente.

Cuando npm ci se introdujo por primera vez, npm i ignoraba package-lock.json completo o al menos era mucho más proactivo en la instalación de diferentes versiones.

De cualquier manera, realmente no importa. npm ci solo está bien cuando la carpeta node_modules aún no existe. De lo contrario, es prohibitivamente lento, especialmente en Windows. Entonces npm i simplemente necesita una bandera que _garantiza_ que no modificará package-lock.json e instalará exactamente lo que está dentro de package-lock.json .

No veo ningún sentido en seguir discutiendo el por qué y el cómo. O lo conseguiremos o no. Como está, npm ci apesta.

/actualizar:
Aquí hay un repositorio donde ejecutar npm i cambiará package-lock.json : https://github.com/fuzzykiller/npm-install-demo

Aunque los cambios son solo de naturaleza técnica, todavía no son aceptables.

Solo para reiterar rápidamente:

  • npm ci siempre elimina el contenido de node_modules por diseño, lo cual no es deseable para compilaciones que no son de producción porque es lento. Sin embargo, utiliza versiones exactas de paquetes que se encuentran en package-lock.json , lo cual es deseable para múltiples situaciones.

  • npm install solo actualiza el contenido de node_modules , que es muy eficaz, pero por diseño ignora el contenido de package-lock.json si los números de versión de package.json difieren, que es indeseable para múltiples situaciones.

  • npm install --package-lock-only se describe en los documentos :

    El argumento --package-lock-only solo actualizará el package-lock.json, en lugar de verificar node_modules y descargar dependencias.

    Esto no parece útil para ninguno de los escenarios descritos anteriormente.

Lo que la gente ha estado pidiendo durante los últimos 3 años:

  1. Un comando (en cualquier lugar) que ignorará package.json y _only_ respetará package-lock.json como la fuente definitiva de los paquetes que se instalarán.

  2. Eso no eliminará todo el contenido de node_modules y volverá a descargar todo desde cero.

Por lo que puedo ver tanto en los documentos como en las pruebas locales, npm install satisface el punto 2, pero no 1. npm ci satisface el punto 1, pero no 2. npm install --package-lock-only no satisface ninguno de esos requisitos.

No estoy completamente seguro de por qué se ha resuelto este problema, todavía no hay forma de obtener el comportamiento deseado.


Editar: Para ampliar el ejemplo de package-lock.json se actualice. Eso sería molesto, pero no rompería ninguna de mis configuraciones. Pero si package.json tiene dependencias difusas enumeradas en cualquier lugar, y se libera una versión de corrección de errores de esas dependencias, se cambiarán cuando ejecute npm install en una nueva máquina. De repente, instalé diferencias entre dos máquinas. Nos hemos encontrado con errores en mi empresa debido exactamente a este comportamiento, no es solo que package-lock.json deba registrarse nuevamente en Git.

Es deseable en esa situación tener un comando que se comporte como npm ci - que haga una instalación reproducible basada _sólo_ en el contenido de package-lock.json . Sin embargo, eliminar el contenido de la carpeta node_modules ralentiza demasiado las compilaciones para algunos entornos y situaciones, aunque es un comportamiento apropiado para una compilación de producción final.

Podría haber una bandera en cualquier lugar para abordar este problema. Podría ser npm install --from-lockfile . Podría ser npm ci --preserve-existing . Pero en este momento parece que estamos en un círculo donde cualquiera que pida una bandera para agregar a npm install es señalado a npm ci como la solución, y cualquiera que pida una bandera en npm ci apunta a npm install como la solución. Este problema se cerró apuntando a npm install --package-lock-only , pero esa bandera es casi lo contrario de lo que la gente está pidiendo. No respeta package-lock.json como fuente autorizada, y tampoco actualiza ni instala ninguna de las dependencias en la carpeta node_modules :)

Este problema debería reabrirse.

¿Fue útil esta página
0 / 5 - 0 calificaciones