¿Confirmo el archivo package-lock.json creado por npm 5?

1397

npm 5 se lanzó hoy y una de las nuevas características incluye instalaciones deterministas con la creación de un package-lock.jsonarchivo.

¿Se supone que este archivo debe mantenerse en el control de origen?

Supongo que es similar a yarn.locky composer.lock, que se supone que deben mantenerse en el control de la fuente.

rink.attendant.6
fuente
20
Respuesta corta: sí. Un comentario: cuando package-lock.json cambia, puede realizar una confirmación de ese cambio, separado de otros cambios de origen. Esto git logfacilita el trato.
Purplejacket
14
Un archivo no puede ayudar a producir una instalación determinista si no existe.
Alan H.
44
Depende del proyecto. github.com/npm/npm/issues/20603
Gajus
3
Si realmente confía en npm seguro, el propósito es informar más explícitamente lo que está utilizando el proyecto. Si realmente desea previsibilidad, ignore este archivo y, en su lugar, instale sus node_modules (consulte .npmrc y la configuración relacionada en las respuestas + comentario) y utilícelo para rastrear lo que realmente está cambiando en lugar de lo que su administrador de paquetes dice que está haciendo. En definitiva: ¿cuál es más importante? Su administrador de paquetes o el código que está utilizando.
jimmont

Respuestas:

1617

Sí, package-lock.jsonestá destinado a ser verificado en el control de fuente. Si está usando npm 5, puede ver esto en la línea de comando: created a lockfile as package-lock.json. You should commit this file.Según npm help package-lock.json:

package-lock.jsonse genera automáticamente para cualquier operación en la que npm modifique el node_modulesárbol o package.json. Describe el árbol exacto que se generó, de modo que las instalaciones posteriores pueden generar árboles idénticos, independientemente de las actualizaciones de dependencia intermedias.

Este archivo está destinado a ser confirmado en repositorios de origen y sirve para varios propósitos:

  • Describa una representación única de un árbol de dependencias de modo que se garantice que los compañeros de equipo, las implementaciones y la integración continua instalen exactamente las mismas dependencias.

  • Proporcione una facilidad para que los usuarios "viajen en el tiempo" a estados anteriores node_modulessin tener que comprometer el directorio en sí.

  • Para facilitar una mayor visibilidad de los cambios de árbol a través de diferencias de control de fuente legible.

  • Y optimice el proceso de instalación permitiendo que npm omita las resoluciones de metadatos repetidos para paquetes instalados previamente.

Un detalle clave package-lock.jsones que no se puede publicar, y se ignorará si se encuentra en otro lugar que no sea el paquete de nivel superior. Comparte un formato con npm-shrinkwrap.json (5), que es esencialmente el mismo archivo, pero permite la publicación. Esto no se recomienda a menos que implemente una herramienta CLI o utilice el proceso de publicación para producir paquetes de producción.

Si ambos package-lock.jsony npm-shrinkwrap.jsonestán presentes en la raíz de un paquete, package-lock.jsonserán completamente ignorados.

vine77
fuente
78
¿En qué tipo de proyectos es realmente útil confirmar el archivo? El punto central de semver y package.json es que las dependencias compatibles actualizadas no deberían ser notadas.
curiousdannii
45
La palabra clave es "no debería ser necesario", pero en la práctica la gente no sigue semver a la perfección. Es por eso que puede usar package-lock.json y package.json juntos para facilitar la actualización de paquetes, pero aún así asegurarse de que cada desarrollador y cada aplicación implementada esté usando el mismo árbol de dependencias.
Panu Horsmalahti
34
@trusktr: Sindre Sorhus recomienda usar "Lockfiles para aplicaciones, pero no para paquetes".
vine77
23
Otra cosa es que se ignora package-lock.json para publicar en NPM, por lo que si un desarrollador lo usa para un desarrollador de biblioteca, entonces están minimizando la posibilidad de que detecte una regresión de una versión de dependencia actualizada y, por lo tanto, pasará eso error en los usuarios finales. Por esta razón, no usar un archivo de bloqueo para el desarrollo de la biblioteca aumenta la posibilidad de enviar menos errores.
trusktr
129129
Personalmente, ahora tuve que recurrir a agregar package-lock.jsona mi .gitignore... me estaba causando muchos más problemas que resolverlos. Siempre entra en conflicto cuando fusionamos o modificamos, y cuando una fusión da como resultado una package-lock.jsoncorrupción en el servidor de CI, es simplemente un dolor tener que seguir reparándolo.
Stefan Z Camilleri
111

Sí, está destinado a ser registrado. Quiero sugerir que obtenga su propia confirmación única. Descubrimos que agrega mucho ruido a nuestras diferencias.

xer0x
fuente
19
es justo debatir si debe verificarse en su repositorio de código fuente, pero publicar este archivo en npm no está realmente en discusión: debe incluir su paquete-lock.json o su archivo retráctil en su registro npm. si no lo hace, su paquete publicado estará sujeto a cambios no anclados de dependencias de sus dependencias de primera generación. no notará que esto es un problema hasta que una de esas dependencias de segunda generación publique un cambio importante y su paquete publicado se rompa misteriosamente. Este archivo package-lock.json se creó para resolver ese problema.
guerillapresident
99
@BetoAveiga por ruido quiero decir que los commits con package-lock.json pueden tener tantas líneas de versiones de paquetes de nodos, que cualquier otro trabajo en ese commit se oculta.
xer0x
77
Usualmente mantengo las instalaciones de paquetes separadas de otros trabajos. Nunca necesito una confirmación como "Instalado chai y mocha", porque ya sé lo que cambió.
Keith
3
¿Algún consejo sobre el package-lock.jsonarchivo cuando se trabaja en un sistema SCM con troncales y ramificaciones? Estoy haciendo algunos cambios en una rama que deben fusionarse con el tronco ... ¿ahora tengo que (de alguna manera) resolver los conflictos entre los dos package-lock.jsonarchivos? Esto se siente doloroso.
kmiklas
3
@guerillapresident Según tengo entendido, estás parcialmente en lo correcto. Publicar este archivo en npm no está en debate. No puedes publicarlo.
Tim Gautier
66

Si deberías:

  1. cometer el package-lock.json.
  2. use en npm cilugar denpm install cuando crea sus aplicaciones tanto en su CI como en su máquina de desarrollo local

El npm ciflujo de trabajo requiere la existencia de a package-lock.json.


Una gran desventaja del npm installcomando es su comportamiento inesperado que puede mutar package-lock.json, mientras que npm cisolo usa las versiones especificadas en el archivo de bloqueo y produce un error

  • si el package-lock.jsony no package.jsonestán sincronizados
  • si package-lock.jsonfalta un

Por lo tanto, ejecutándose npm installlocalmente, esp. en equipos más grandes con múltiples desarrolladores, puede generar muchos conflictos dentro de los package-lock.jsondesarrolladores y decidir eliminarlos por completo package-lock.json.

Sin embargo, existe un fuerte caso de uso para poder confiar en que las dependencias del proyecto se resuelven repetidamente de manera confiable en diferentes máquinas.

De a package-lock.jsonobtienes exactamente eso: un estado conocido de trabajo.

En el pasado, tenía proyectos sin archivos package-lock.json/ npm-shrinkwrap.json/ yarn.lockcuya construcción fallaría algún día porque una dependencia aleatoria recibió una actualización de última hora.

Esos problemas son difíciles de resolver ya que a veces tienes que adivinar cuál fue la última versión de trabajo.

Si desea agregar una nueva dependencia, aún ejecuta npm install {dependency}. Si desea actualizar, use cualquiera npm update {dependency}o npm install ${dependendency}@{version}y confirme el cambio package-lock.json.

Si falla una actualización, puede volver al último trabajo conocido package-lock.json.


Para citar npm doc :

Se recomienda encarecidamente que confirme el bloqueo del paquete generado al control de origen: esto permitirá que cualquier otra persona en su equipo, sus implementaciones, su CI / integración continua y cualquier otra persona que ejecute npm install en su fuente de paquete para obtener exactamente el mismo árbol de dependencias que estabas desarrollando Además, los diferenciales de estos cambios son legibles por humanos y le informarán de cualquier cambio que npm haya realizado en sus node_modules, para que pueda notar si alguna dependencia transitiva se actualizó, izó, etc.

Y en lo que respecta a la diferencia entre npm civsnpm install :

  • El proyecto debe tener un paquete-lock.json o npm-shrinkwrap.json existentes.
  • Si las dependencias en el bloqueo del paquete no coinciden con las del paquete.json, npm cisaldrá con un error, en lugar de actualizar el bloqueo del paquete.
  • npm ci solo puede instalar proyectos completos a la vez: las dependencias individuales no se pueden agregar con este comando.
  • Si node_modulesya está presente, se eliminará automáticamente antes de npm cicomenzar su instalación.
  • Nunca escribirá en package.jsonninguno de los paquetes bloqueados: las instalaciones están esencialmente congeladas.

Nota: publiqué una respuesta similar aquí

k0pernikus
fuente
10
Esta respuesta merece más crédito, especialmente usando npm ci. Usar esto mitiga la mayoría de los problemas que las personas han experimentado con el bloqueo de paquetes.
JamesB
He encontrado que usar la versión fija en package.json (sin caret o tilde) es una opción mucho más limpia. Esto me salva de algún whose build would fail one day because a random dependency got a breaking updatetipo de problema. Aunque deja la posibilidad de que la dependencia del niño cause el mismo problema.
Ashwani Agarwal
58

Sí, la mejor práctica es hacer el check-in (SÍ, CHECK-IN)

Estoy de acuerdo en que causará mucho ruido o conflicto al ver la diferencia. Pero los beneficios son:

  1. Garantizar exactamente la misma versión de cada paquete . Esta parte es la más importante cuando se construye en diferentes entornos en diferentes momentos. Puede usarlo ^1.2.3en su package.json, pero ¿cómo puede asegurarse de que cada vez npm installelija la misma versión en su máquina de desarrollo y en el servidor de compilación, especialmente esos paquetes de dependencia indirectos? Bueno, package-lock.jsonse asegurará de eso. (Con la ayuda de npm cique instala paquetes basados ​​en el archivo de bloqueo)
  2. Mejora el proceso de instalación.
  3. ayuda con la nueva función de auditoría npm audit fix(creo que la función de auditoría es de npm versión 6).
Xin
fuente
3
Hasta donde sé, nunca usar semver (que los desarrolladores de npm no entienden de todos modos) debería producir el mismo comportamiento que tener un archivo de bloqueo al menos en el 99% de los casos. Mi propia experiencia es que las caídas de semver suceden principalmente con paquetes primarios (dependencias directas, citas jquery, etc.). Mi experiencia personal con npm ha sido que los archivos de bloqueo eran ruido para siempre. Espero que esta sabiduría no haya cambiado con las versiones recientes.
Svend
13
+1 por mencionar npm ci. ¡La gente frecuentemente menciona que a package-lock.jsonpermite una instalación determinista de paquetes, pero casi nunca menciona el comando que facilita este comportamiento! Mucha gente probablemente asumen incorrectamente npm installinstala exactamente lo que está en el archivo de bloqueo ...
ahaurat
npm ci no está en npm 5.
dpurrington
¡Gracias! Solo tiene sentido confirmar package-lock.json si está utilizando npm ci. Su equipo / desarrollador principal puede decidir cuándo actualizar. Si todos lo cometen arbitrariamente, no tiene sentido, y solo está creando ruido en su repositorio. La documentación de NPM debería aclarar esto. Creo que la mayoría de los desarrolladores están confundidos por esta característica.
adampasz
@adampasz en realidad cada desarrollador puede confirmar el archivo de bloqueo, y una vez que pasa la prueba y se fusiona, la segunda rama simplemente renueva el archivo de bloqueo si de alguna manera se cambian los paquetes (no cambiamos el paquete.json a menudo, nos enfrentamos menos a este problema (
Xin
38

No confirmo este archivo en mis proyectos. Cuál es el punto de ?

  1. Es generado
  2. Es la causa de un error de integridad del código SHA1 en gitlab con compilaciones gitlab-ci.yml

Aunque es cierto que nunca uso ^ en mi package.json para libs porque tuve malas experiencias con él.

Deunz
fuente
11
Desearía que esto se exponga más desde npm docs. Sería útil tener un resumen de lo que específicamente pierde al no comprometerse package-lock.json. Es posible que algunos repositorios no requieran los beneficios que se obtienen al tenerlo y prefieran no tener contenido generado automáticamente en la fuente.
PotatoFarmer el
2
Puedo ver cómo puede ser útil para la depuración (una diferencia entre dos bloqueos, por ejemplo) para ayudar a resolver problemas. Supongo que también se puede usar para prevenir este tipo de cosas, pero también puede ser un dolor tenerlo en un repositorio compartido donde puede experimentar conflictos de fusión debido a eso. Para empezar quiero mantener las cosas simples, solo usaré package.json por sí solo hasta que vea que hay una necesidad real de package-lock.json.
radtek
66
No puede usar ^ en su package.json, pero puede estar seguro de que sus dependencias no lo usan.
Neiker
35

Para las personas que se quejan del ruido al hacer git diff:

git diff -- . ':(exclude)*package-lock.json' -- . ':(exclude)*yarn.lock'

Lo que hice fue usar un alias:

alias gd="git diff --ignore-all-space --ignore-space-at-eol --ignore-space-change --ignore-blank-lines -- . ':(exclude)*package-lock.json' -- . ':(exclude)*yarn.lock'"

Para ignorar package-lock.json en diffs para todo el repositorio (todos los que lo usan), puede agregar esto a .gitattributes:

package-lock.json binary
yarn.lock binary

Esto dará como resultado diferencias que muestran "Los archivos binarios a / package-lock.json y b / package-lock.json difieren cada vez que se modifica el archivo de bloqueo del paquete. Además, algunos servicios de Git (especialmente GitLab, pero no GitHub) también excluirán estos archivos (¡no se han cambiado más de 10k líneas!) desde los diferenciales cuando se visualizan en línea al hacer esto.

Raza
fuente
1
Tengo gd() { git diff --color-words $1 $2 -- :!/yarn.lock :!/package-lock.json; }en mi .bashrc en lugar de un alias.
apostl3pol
16

Sí, puedes confirmar este archivo. De los documentos oficiales de npm :

package-lock.jsonse genera automáticamente para cualquier operación en la que se npmmodifique el node_modulesárbol o package.json. Describe el árbol exacto que se generó, de modo que las instalaciones posteriores pueden generar árboles idénticos, independientemente de las actualizaciones de dependencia intermedias.

Este archivo está destinado a ser confirmado en repositorios de origen [.]

Bablu Singh
fuente
13
¿Una instalación no siempre actualizará node_modules y, por lo tanto, actualizar package-lock.json?
Tim Gautier
2
No, puede ejecutar la npm ciinstalación desde el paquete-lock.json
William Hampshire
Debe resaltar en su respuesta que DEBE usar npm ci en su compilación de integración continua si tiene package-lock.json en el repositorio
MagicLAMP
6

Deshabilitar globalmente package-lock.json

escriba lo siguiente en su terminal:

npm config set package-lock false

esto realmente funciona para mí como magia

Balogun Ridwan Ridbay
fuente
2
esto crea ~/.npmrc(al menos en mis macos) con contenido package-lock=falsey lo mismo se puede hacer en cualquier proyecto específico junto node_modules/(por ejemploecho 'package-lock=false' >> .npmrc
jimmont
66
Es algo gracioso para mí que esto sea negativo. la comunidad npm simplemente no puede aceptar que la generación automática de package-lock.json haya sido una mala participación de la comunidad. No debe hacer cosas que puedan afectar el proceso de un equipo. debería haber sido una opción para habilitar, no forzado. cuántas personas simplemente hacen "git add *" y ni siquiera lo notan y arruinan las construcciones Si tiene algún tipo de flujo basado en fusión, sé que git flow es como la biblia para las personas que lo usan, esto no funcionará. ¡no puedes tener generación en fusión! El control de versiones de npm está roto, el paquete: 1.0.0 debe ser determinista.
Eric Twilegar
3
¿Por qué se baja esto? Esta es claramente una forma legítima de deshabilitar una característica que no funciona. Y aunque no responde la pregunta per se, discute la pregunta. es decir, ya no necesita respuesta. Pulgares arriba de mí :)
Superole
La razón por la que se está rechazando es porque simplemente está deshabilitando una función.
Raza
5

Sí, es una práctica estándar comprometer package-lock.json

La razón principal para cometer package-lock.json es que todos en el proyecto están en la misma versión del paquete.

Pros: -

  • Si sigue un control de versiones estricto y no permite la actualización a versiones principales automáticamente para evitar cambios incompatibles con versiones anteriores en paquetes de terceros, la confirmación de paquetes de bloqueo ayuda mucho.
  • Si actualiza un paquete en particular, se actualiza en package-lock.json y todos los que usan el repositorio se actualizan a esa versión en particular cuando toman el tirón de sus cambios.

Contras:-

  • Puede hacer que tus solicitudes de extracción se vean feas :) '

Editar: - npm install no asegurará que todos en el proyecto estén en la misma versión del paquete. npm ci te ayudará con esto.

Nikhil Mohadikar
fuente
44
Los contras desaparecerían si lo usaras en npm cilugar de npm install.
k0pernikus
2
El alcance se arrastra un poco, pero aquí hay más información sobre ese excelente consejo de @ k0pernikus .
ruffin
1
"Todos en el proyecto estarán en la misma versión del paquete, todo lo que tienes que hacer es instalar npm" No es cierto, debes usar "npm ci" en su lugar
reggaeguitar
Gracias, @reggaeguitar. Actualizando mi respuesta para esto.
Nikhil Mohadikar
2

Mi uso de npm es generar css / js minified / uglified y generar el javascript necesario en las páginas servidas por una aplicación django. En mis aplicaciones, Javascript se ejecuta en la página para crear animaciones, algunas veces realizar llamadas ajax, trabajar dentro de un marco VUE y / o trabajar con el CSS. Si package-lock.json tiene un control superior sobre lo que está en package.json, entonces puede ser necesario que haya una versión de este archivo. En mi experiencia, no afecta lo que instala npm install, o si lo hace, hasta la fecha no ha afectado negativamente las aplicaciones que despliegue a mi conocimiento. No uso mongodb u otras aplicaciones que tradicionalmente son clientes ligeros.

Elimino package-lock.json del repositorio porque npm install genera este archivo, y npm install es parte del proceso de implementación en cada servidor que ejecuta la aplicación. El control de versiones de nodo y npm se realiza manualmente en cada servidor, pero tengo cuidado de que sean iguales.

Cuando npm installse ejecuta en el servidor, cambia package-lock.json, y si hay cambios en un archivo que el repositorio registra en el servidor, el próximo despliegue WONT le permitirá extraer nuevos cambios desde el origen. Es decir, no se puede implementar porque la extracción sobrescribirá los cambios que se han realizado en package-lock.json.

Ni siquiera puede sobrescribir un paquete-lock.json generado localmente con lo que está en el repositorio (restablecer el maestro de origen duro), ya que npm se quejará cuando emita un comando si el paquete-lock.json no refleja lo que está en node_modules debido a la instalación de npm, rompiendo así la implementación. Ahora, si esto indica que se han instalado versiones ligeramente diferentes en node_modules, una vez más, eso nunca me ha causado problemas.

Si node_modules no está en su repositorio (y no debería estarlo), se debe ignorar package-lock.json.

Si me falta algo, corríjame en los comentarios, pero el punto de que se toma la versión de este archivo no tiene sentido. El archivo package.json tiene números de versión, y supongo que este archivo es el que se usa para construir paquetes cuando se produce la instalación de npm, ya que cuando lo elimino, la instalación de npm se queja de la siguiente manera:

jason@localhost:introcart_wagtail$ rm package.json
jason@localhost:introcart_wagtail$ npm install
npm WARN saveError ENOENT: no such file or directory, open '/home/jason/webapps/introcart_devtools/introcart_wagtail/package.json'

y la compilación falla, sin embargo, al instalar node_modules o aplicar npm para compilar js / css, no se presenta ninguna queja si elimino package-lock.json

jason@localhost:introcart_wagtail$ rm package-lock.json 
jason@localhost:introcart_wagtail$ npm run dev

> introcart@1.0.0 dev /home/jason/webapps/introcart_devtools/introcart_wagtail
> NODE_ENV=development webpack --progress --colors --watch --mode=development

 10% building 0/1 modules 1 active ...
Lampara magica
fuente
Solo para agregar, ahora he enviado mi paquete-lock.json a mi repositorio, y estoy usando npm ci en mi despliegue ansible, que creo que elimina node_modules, e instala todo en package-lock.json sin actualizarlo. Esto le permite a mi chico de front-end actualizar cosas de JavaScript sin necesidad de intervención manual en la implementación.
MagicLAMP