Yarn: hacer `--pure-lockfile` predeterminado para` install`

Creado en 10 oct. 2016  ·  54Comentarios  ·  Fuente: yarnpkg/yarn

¿Quieres solicitar una _feature_ o informar de un _bug_?

_característica_

¿Cuál es el comportamiento actual?

No pasar --pure-lockfile por install comando me confunde porque modifica el archivo de bloqueo al instalar node_modules.
Acordamos en la semántica que add/upgrade/remove son para cambiar dependencias y install es para reconstruir consistentemente node_modules desde lockfile.

La consistencia se pierde cuando se modifica el archivo de bloqueo según el entorno (versión de hilo instalada actualmente).

¿Cuál es el comportamiento esperado?

No escriba yarn.lock o package.json al hacer yarn install .
Para actualizar yarn.lock use yarn upgrade

Por favor, mencione su versión de node.js, yarn y sistema operativo.

hilo 0.14

cat-feature needs-discussion

Comentario más útil

Hay un montón de cosas diferentes que están sucediendo aquí que quería tratar de desentrañar (sin juego de palabras).

Primero, la gente ha planteado una serie de requisitos diferentes que creo que no son controvertidos (y que hacen que algunos de los comportamientos existentes sean fallidos, a los que llegaré pronto).

Del informe de error original.

La consistencia se pierde cuando se modifica el archivo de bloqueo según el entorno (versión de hilo instalada actualmente).
¿Cuál es el comportamiento esperado?
No escriba yarn.lock o package.json cuando realice la instalación de hilo.
Para actualizar yarn.lock use yarn upgrade

Para ser más precisos, la semántica esperada, en mi opinión, es:

  • si package.json no ha cambiado desde la última vez que yarn.lock cambió, yarn.lock es la fuente de la verdad y no debe actualizarse.
  • si package.json ha cambiado desde la última vez, yarn.lock cambió, actualice yarn.lock para que satisfaga package.json y actualice node_modules .
  • si se ejecuta yarn update , vuelva a resolver todas las dependencias y obtenga la última versión de todo lo que satisfaga los package.json .

Esto significa que cuando un repositorio se clona por primera vez en una máquina , si se registró yarn.lock , el hilo siempre debe tratarlo como la fuente de la verdad, no generar actualizaciones para yarn.lock y saltar directamente al paso de búsqueda.

En la medida en que este no sea el comportamiento actual del hilo, creo que sería un error.


@esphen escribió:

Estoy de acuerdo. Debería haber una discusión sobre por qué yarn install escribe un archivo de bloqueo por defecto en primer lugar, ya que parece estar en desacuerdo con todo el concepto de archivo de bloqueo. ¿Por qué tener un archivo de bloqueo si no bloquea las versiones de forma predeterminada?

Creo que lo que esto está tratando de decir es que el hilo no debería escribir un nuevo archivo de bloqueo si el existente todavía está actualizado. Estoy de acuerdo con eso.

Estoy de acuerdo con la opinión de @bestander de que solo las acciones mutantes deberían actualizar el archivo de bloqueo de forma predeterminada, es decir, agregar / actualizar / eliminar.

El problema principal aquí es si un cambio en package.json debería hacer que yarn.lock se actualice. En mi opinión, si el cambio al package.json no es satisfecho por el yarn.lock , debe actualizar el yarn.lock .

Un invariante importante de los sistemas de archivos de bloqueo como yarn es que, utilizando el flujo de trabajo normal, los desarrolladores pueden estar seguros de que los paquetes que realmente se utilizan cuando ejecutan su aplicación coinciden con las versiones especificadas en su package.json . Si se permite que el package.json esté sincronizado con el yarn.lock , esto no será cierto, y la única forma de saberlo será que los lectores humanos lean cuidadosamente el yarn.lock .

La mejor manera para que la mayoría de los usuarios piensen en el archivo de bloqueo es que es un artefacto del hilo en ejecución que representa las versiones precisas de todos los paquetes que se usaron para el actual package.json . Al registrarlo, otros colaboradores, CI y el código de producción tienen la seguridad de usar esas mismas versiones.


@Guuz dijo:

Entonces, para verificar si entiendo esto correctamente:
yarn instala todas las dependencias y también modifica el archivo de bloqueo. En un servidor CI debería usar yarn install --pure-lockfile?

Esta pregunta se hace eco de un sentimiento que algunas personas han expresado en este hilo.

La carga tiene una bandera --locked que dice "si el package.json no está satisfecho con el yarn.lock , es un error grave". Bundler tiene una bandera similar ( --frozen ), que se agregó cuando Heroku adoptó Bundler, para dar a las personas un error grave si realizaban cambios locales en sus Gemfile y se olvidaban de registrar los Gemfile.lock .

La idea es que durante su desarrollo normal, le gustaría poder realizar cambios en el package.json y hacer que el hilo se asegure de que el yarn.lock permanezca sincronizado (nuevamente, para asegurarse de que las versiones especificadas en package.json siempre coincide con lo que se usa en la práctica).

Pero al implementar, virtualmente siempre es un error haber divergido, porque significa que hizo un cambio a package.json , ejecutó un comando local yarn y olvidó registrar yarn.lock . Esto significa que las versiones en su package.json no coinciden con las versiones reales utilizadas cuando se ejecuta la aplicación , lo que dijimos viola un invariante fundamental de hilo.


@esphen dijo:

En mi opinión, una de las funciones que desempeña un administrador de paquetes es hacer que sea lo más fácil posible comenzar con el desarrollo de un proyecto. Una instalación simple de hilo debería obtener todos los paquetes que necesita para comenzar a desarrollar, sin ninguna confusión involucrada.

Creo que esto no es controvertido.

Con npm, he tenido muchas instancias de desarrolladores que se unieron a un proyecto, solo para descubrir que un proyecto no funciona en su máquina. Estas instancias se han producido debido a dependencias transitorias que desplazan versiones a versiones con cambios importantes o simplemente no siguen a semver. Tenía la esperanza de que yarn resolvería estos problemas, pero si la conclusión es que todos los desarrolladores de un proyecto deberían ejecutar yarn install --pure-lockfile para estar 100% seguros de que el proyecto se va a construir, entonces ese no es el caso.

Ejecutar yarn install --pure-lockfile significará que el archivo de bloqueo será respetado incluso si las versiones dentro del archivo de bloqueo entran en conflicto con las versiones especificadas en package.json . Esto solo debería surgir en primer lugar si un desarrollador se olvida de registrar su yarn.lock después de realizar cambios en el package.json .

Otra función de un administrador de paquetes es dar a los proyectos el control de sus dependencias. Si se hace puro de forma predeterminada, los desarrolladores pueden echar un vistazo al hilo desactualizado para ver las versiones desactualizadas y luego revisar las notas de cambio, evitando cambios importantes. Esto le daría a los desarrolladores un control total para solo ejecutar versiones en un período de tiempo de lanzamiento dado en lugar de prohibir a los desarrolladores hacer git commit -a para evitar confirmaciones accidentales de archivos de bloqueo.

Si package.json no ha cambiado, en mi opinión, es un error si yarn.lock se está actualizando. Al menos un caso del error parece estar en el informe original:

El archivo de bloqueo se modifica según el entorno (versión del hilo instalada actualmente).

Creo que esto es un error y debería corregirse.

Más adelante en el hilo, @thejameskyle dijo:

Imagine una función memoize donde la entrada es un package.json y la salida es yarn.lock.

Ese es exactamente el modelo mental correcto, en mi opinión (" yarn.lock puede cambiar si y solo si package.json cambió"), y si la abstracción tiene fugas, deberíamos arreglarlo.


@adamchainz dijo:

Más información sobre lo anterior: nuestra compilación tiene coffeescript de Github como subdependencia. coffeescript presionó algunas confirmaciones y obtuvimos un yarn.lock modificado en nuestro proceso de compilación al ejecutar solo yarn install

y después:

Pero tiene el mal comportamiento si se instala una dependencia desde github, como informé anteriormente

El problema aquí es que yarn no trata a git sha como parte de la versión bloqueada de las dependencias de git. Cargo y Bundler tienen el concepto de una versión "precisa" que se serializa en el archivo de bloqueo; para las fuentes de git, la versión "precisa" es el SHA. Luego, cuando crea un clon nuevo con solo package.json y yarn.lock y ejecuta yarn , toda la información necesaria para obtener precisamente el código que necesita está ahí.

Debo confesar que me perdí esta interacción al revisar el código git original; hay algún seguimiento SHA en el código, pero yarn install no asegura que el gráfico de dependencia hidratada lo respete.


TL; DR

Estoy de acuerdo con @thejameskyle y @kittens en que yarn.lock debe mantenerse sincronizado con package.json automáticamente, porque creo que los usuarios deben poder asumir que las versiones especificadas en su package.json alinearse con lo que se usa cuando se ejecuta su aplicación.

Sin embargo, parece haber algunos errores que están causando una rotación inapropiada en el yarn.lock incluso cuando el package.json no ha cambiado:

  • los cambios en la versión de hilo en las máquinas actualizan el archivo de bloqueo
  • Las dependencias de git se actualizan incluso si package.json no se ha actualizado, lo que luego actualiza el archivo de bloqueo

También deberíamos considerar algo como la bandera --locked Cargo, que puede usar en CI para fallar rápidamente en la compilación si un desarrollador actualiza package.json y se olvida de registrar el yarn.lock actualizado

Todos 54 comentarios

Estoy de acuerdo. Debería haber una discusión sobre por qué yarn install escribe un archivo de bloqueo por defecto en primer lugar, ya que parece estar en desacuerdo con todo el concepto de archivo de bloqueo. ¿Por qué tener un archivo de bloqueo si no bloquea las versiones de forma predeterminada?

Existe un caso para que yarn install cree un archivo de bloqueo si no hay ninguno presente, es decir, cuando alguien está convirtiendo un proyecto para usar yarn , pero la razón para escribirlo siempre no está clara. Estoy de acuerdo con la opinión de @bestander de que solo las acciones mutantes deberían actualizar el archivo de bloqueo de forma predeterminada, es decir, add/upgrade/remove .

¿Debería haber una forma de modificar el archivo de bloqueo sin add/remove/upgrade ex: en el escenario en el que actualiza Yarn y usa una nueva versión del archivo de bloqueo?

Supongo que se podría inventar la opción

yarn install --save-lockfile

El 17 de octubre de 2016 a las 18:53, James Ide [email protected] escribió:

¿Debería haber una forma de modificar el archivo de bloqueo sin agregar / eliminar / actualizar?
Ej: en el escenario cuando actualiza Yarn y usa un nuevo archivo de bloqueo
¿versión?

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/yarnpkg/yarn/issues/570#issuecomment -254282256, o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/ACBdWJLpdvqiwcBwqE4KB3x3f4oCn_nVks5q07YYgaJpZM4KSlSw
.

También estoy confundido por esto. ¿Cuál es el razonamiento del comportamiento predeterminado actual?

Afaik, no hubo razones sólidas para el comportamiento predeterminado.
La idea, supongo, es mantener los archivos de bloqueo de las personas "siempre verdes".

Por cierto, PR es bienvenido

Creo que la razón fue que el hilo se diseñó originalmente con un solo comando install que se dividió en install/add/upgrade

Entonces, para verificar si entiendo esto correctamente:

yarn instala todas las dependencias y también modifica el archivo de bloqueo. En un servidor de CI debería usar yarn install --pure-lockfile ?
¿Por qué se modifica el archivo de bloqueo durante una instalación? Dado que no está actualizando nada ... Yarn debería instalar los paquetes como se describe en el archivo de bloqueo, ¿verdad?

¡Gracias por la explicación!

El problema es que si el archivo de bloqueo es puro de forma predeterminada, la gente se olvidará de actualizarlo, ya que sería un comando separado.

@kittens ¿No debería el archivo de bloqueo solo actualizarse al agregar / eliminar / actualizar algún paquete? Esos siempre deben actualizar el archivo de bloqueo, así como una instalación inicial.

El problema es que si el archivo de bloqueo es puro de forma predeterminada, la gente se olvidará de actualizarlo, ya que sería un comando separado.

Ser un problema depende de lo que consideres que es el objetivo principal de un administrador de paquetes.

En mi opinión, una de las funciones que desempeña un administrador de paquetes es hacer que sea lo más fácil posible comenzar con el desarrollo de un proyecto. Un simple yarn install debería obtener todos los paquetes que necesita para comenzar a desarrollar, sin confusión alguna.

Con npm , he tenido muchas instancias de desarrolladores que se unieron a un proyecto, solo para descubrir que un proyecto no funciona en su máquina. Estas instancias se han producido debido a dependencias transitorias que desplazan versiones a versiones con cambios importantes o simplemente no siguen a semver. Esperaba que yarn resolviera estos problemas, pero si la conclusión es que todos los desarrolladores de un proyecto deben ejecutar yarn install --pure-lockfile para estar 100% seguros de que el proyecto se va a construir, entonces eso no es el caso.

Otra función de un administrador de paquetes es dar a los proyectos el control de sus dependencias. Si se hace puro de forma predeterminada, los desarrolladores pueden echar un vistazo a yarn outdated para ver las versiones desactualizadas y luego revisar las notas de cambio, evitando cualquier cambio importante. Esto le daría a los desarrolladores un control total para solo ejecutar versiones en un período de tiempo de lanzamiento dado en lugar de prohibir a los desarrolladores hacer git commit -a para evitar confirmaciones accidentales de archivos de bloqueo.

Estoy de acuerdo con todo lo que dice

Nos sorprendió totalmente romper la compilación después de que comenzamos a usar yarn durante unos días. Honestamente, pensé que --pure-lockfile era el comportamiento predeterminado después de leer gran parte de la documentación y sobre cómo es mejor que npm con shrinkwrap. Por favor, establezca el valor predeterminado :)

@ide Imagina un escenario en el que alguien está usando npm y actualiza package.json , ¿cómo se actualizará yarn.lock ?

¿Alguien puede escribir los escenarios que conducen a que el archivo de bloqueo se modifique inesperadamente? Este cambio es grave y hace que el fichero de bloqueo de un ciudadano de segunda clase, al exigir cambios a que sea explícita lo que significa un montón de gastos generales en recordar lo que las operaciones dan lugar a que se actualiza etc.

Más información sobre lo anterior: nuestra compilación tiene coffeescript de Github como subdependencia. coffeescript presionó algunas confirmaciones y obtuvimos un yarn.lock modificado en nuestro proceso de compilación al ejecutar solo yarn install :

diff --git a/foo/yarn.lock b/foo/yarn.lock
index ec667fa..bb1f6ae 100644
--- a/foo/yarn.lock
+++ b/foo/yarn.lock
@@ -930,9 +930,9 @@ code-point-at@^1.0.0:
   version "1.6.3"
   resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.6.3.tgz#6355d32cf1b04cdff6b484e5e711782b2f0c39be"

-"coffee-script<strong i="8">@github</strong>:jashkenas/coffeescript":
+coffee-script@jashkenas/coffeescript:
   version "1.11.1"
-  resolved "https://codeload.github.com/jashkenas/coffeescript/tar.gz/887052de079b2f0af9f080031a00bb7544eaca08"
+  resolved "https://codeload.github.com/jashkenas/coffeescript/tar.gz/0d132318ce8f7116a436d97db1f2a5c8b1dedf28"

 [email protected]:
   version "0.3.0"

¿Alguien puede escribir los escenarios que conducen a que el archivo de bloqueo se modifique inesperadamente? Este cambio es serio y convierte al archivo de bloqueo en un ciudadano de segunda clase al requerir que las actualizaciones sean explícitas, lo que significa una gran cantidad de gastos generales para recordar qué operaciones dan como resultado que se actualice, etc.

Percibo yarn install como un comando que construye node_modules para mí.
Es opuesto a yarn add y yarn remove que modifican package.json, yarn.lock y cleanup node_modules.
En oposición a add y remove , corro install 100 veces más a menudo, especialmente en CI, donde nunca espero tener efectos secundarios.

Ejemplos en los que no espero que las cosas cambien:

  1. Estoy en Yarn 0.15.0, mis compañeros de equipo están en Yarn 0.16.0.
    Debido a que 0.16.0 agregó espacios entre las entradas en yarn.lock cada vez que ejecuto yarn install contra yarn.lock que fue generado por mis compañeros de equipo, obtengo un archivo yarn.lock modificado que debo recordar no comprometer.
    Y viceversa.
  2. Mis otras herramientas de construcción dependen de yarn.lock como "la fuente de la verdad" del estado de node_modules. Si cambia inesperadamente, obtendré no determinismo en mis compilaciones

@gatitos

El problema es que si el archivo de bloqueo es puro de forma predeterminada, la gente se olvidará de actualizarlo, ya que sería un comando separado.

Imagine un escenario en el que alguien solo está usando npm y actualiza package.json, ¿cómo se actualizará yarn.lock?

Si asumimos que yarn install no debería actualizar yarn.lock , entonces también debería fallar si yarn.lock está sincronizado con package.json para resaltar el hecho de que un yarn install --save-lockfile es necesario para que todo vuelva a estar sincronizado.

+1 instalación de hilo no debe mutar el hilo.

  1. El depurador es una aplicación de sistema operativo. Queremos que los colaboradores puedan instalar hilo y obtener las versiones _buenas_. Hemos tenido gente que npm instaló y dijo que se está rompiendo debido a las propiedades transitivas. Con la instalación de hilo, los colaboradores instalan hilo y no saben qué hacer con los cambios de bloqueo de hilo.

No me preocupa actualizar el archivo de bloqueo. Idealmente, greenkeeper haría esto cuando los departamentos cambien y podríamos fusionar el cambio de archivo de bloqueo en ese momento.

Quiero actualizar este problema con las ideas actuales al respecto. @kittens y yo pensamos que --pure-lockfile _no_ debería ser el valor predeterminado por un par de razones.

Comienza con cómo las personas agregan / eliminan / actualizan dependencias. Si bien existen comandos para ello, es una práctica común actualizar manualmente package.json a mano o con otra herramienta como Lerna .

Una vez que haya modificado manualmente package.json la expectativa tanto en Yarn como en npm es que cuando ejecute otra instalación, se sincronice con package.json . En ese sentido, yarn install casi podría cambiarse yarn sync nombre a

Sobre el tema de la sincronización, cuando ejecuta una instalación con nuevas dependencias, espera que el directorio node_modules refleje esos cambios. Dado que yarn.lock actúa como asistente de node_modules , debe esperar que se mantenga sincronizado de la misma manera.

Su package.json es la última fuente de verdad, esa es su interfaz para el hilo, es su configuración y es lo único que debería preocuparle. En un mundo ideal, simplemente compromete sus yarn.lock y nunca más tendrá que pensar en ello.


En una nota al margen, creo que muchas personas que están expresando su apoyo a este tema están confundidas acerca de lo que realmente se está discutiendo aquí.

Usar --pure-lockfile por defecto no significa que Yarn no produzca resultados consistentes y confiables. El mismo package.json resultará en el mismo yarn.lock que resultará en el mismo node_modules 100% del tiempo.

Cuando actualiza sus package.json sus actualizaciones de archivo yarn.lock y luego sus actualizaciones de node_modules . Ese es un orden muy natural para las cosas y deberíamos mantenerlo así.


En lo que respecta a que CI pueda obtener diferentes dependencias cuando haya actualizado su package.json pero no haya ejecutado yarn install para sincronizar todo, estoy seguro de que alguien mostrará (aunque no veo como un problema) - yo y otros hemos estado hablando con varias herramientas de CI sobre la integración de Yarn, podemos presionar fácilmente para que usen --pure-lockfile de forma predeterminada si la gente lo ve como un gran problema.


Si hiciéramos este cambio, tendría un impacto negativo mucho más a menudo al cambiar las dependencias. Por las razones que he enumerado, digo que deberíamos cerrar este problema.

@thejameskyle te agradecería si pudieras aclarar algo:

  1. Un desarrollador tiene un package.json que contiene una dependencia "foo": "^1.0.0"
  2. El desarrollador ejecuta yarn install . El paquete foo es actualmente la versión 1.0.0 , por lo que crea un archivo yarn.lock que se bloquea en [email protected]
  3. El desarrollador agrega yarn.lock a Git.
  4. El desarrollador ejecuta pruebas unitarias en su copia local del repositorio, todo funciona bien.
  5. El desarrollador envía su repositorio a CI (por ejemplo, Travis).
  6. CI ejecuta yarn install , pero foo ahora se ha actualizado a la versión 1.1.0 , por lo que Yarn instala [email protected] y sobrescribe yarn.lock con la nueva versión de foo
  7. El CI se rompe porque foo tuvo un cambio importante en la versión 1.1.0

Aquí hay una situación similar:

  1. Un desarrollador tiene un package.json que contiene una dependencia "foo": "^1.0.0" , que está bloqueada como [email protected] , y yarn.lock se guarda en Git.
  2. Las pruebas unitarias funcionan bien en la copia local del repositorio del desarrollador.
  3. Un colaborador clona el repositorio con la intención de realizar una modificación + solicitud de extracción.
  4. Cuando el colaborador ejecuta yarn install obtiene la versión [email protected] que hace que yarn.lock se actualice.
  5. Ahora la compilación del colaborador está rota porque foo tuvo un cambio importante en la versión 1.1.0

Creo que ese es el tipo de situaciones que preocupan a la mayoría de la gente.

Entonces, si pudiera aclarar que el comportamiento actual de yarn install no tiene los problemas anteriores, creo que eliminaría la mayoría de nuestros temores. : +1:

Ninguna de esas situaciones se aplica. El hecho de que una dependencia se haya actualizado no significa que la obtendrá, solo si ha realizado cambios en su package.json .

Solo voy a cerrar este tema porque realmente parece que esta es la única preocupación que tiene la gente, que como dije no es un escenario real. Es probable que este problema esté causando más confusión.

Pero tiene el mal comportamiento si se instala una dependencia desde github, como informé anteriormente

@adamchainz Eso debería arreglarse por separado, podemos bloquearlo fácilmente en la confirmación

Ninguna de esas situaciones se aplica. El hecho de que una dependencia se haya actualizado no significa que la obtendrá, solo si ha realizado cambios en su package.json .

@thejameskyle : No estoy seguro de entender por qué este no es un escenario real. ¿Podrías dar más detalles?

Imagine una función de memorización donde la entrada es package.json y la salida es yarn.lock .

  1. La primera vez que pasa un package.json , crea un yarn.lock y almacena en caché el resultado.
  2. La próxima vez que ejecute _that same_ package.json el resultado será exactamente el mismo porque está almacenado en caché.
  3. Cuando cambia package.json , invalida la caché y ahora se volverá a calcular yarn.lock .

De lo que estamos hablando ahora es de deshacernos del # 3 y, en su lugar, tratar yarn.lock como si no hubiera sido invalidado por el package.json modificado. Lo cual sería realmente extraño que tuviera una función de memorización y sería un comportamiento realmente extraño para Yarn.

Lo que le sucede a un paquete en términos de confirmaciones y nuevas versiones _debería_ ser irrelevante (si tenemos un error con las confirmaciones de git, entonces deberíamos solucionarlo por separado, pero no está relacionado con este problema).

Es más complejo de lo que me imaginé (cada versión de paquete se "memoriza" de manera efectiva de forma individual, cambiar la versión de un paquete no invalida el resto), pero espero que ahora todos entiendan el punto.

@thejameskyle : En aras de la claridad (y la curiosidad), digamos que tengo un proyecto con un archivo yarn.lock y alguien abre el repositorio. Sin ejecutar yarn install o npm install , esta persona agrega una nueva dependencia al archivo package.json y luego ejecuta yarn install . ¿Se ignorará por completo el archivo yarn.lock en este caso?

Hay un montón de cosas diferentes que están sucediendo aquí que quería tratar de desentrañar (sin juego de palabras).

Primero, la gente ha planteado una serie de requisitos diferentes que creo que no son controvertidos (y que hacen que algunos de los comportamientos existentes sean fallidos, a los que llegaré pronto).

Del informe de error original.

La consistencia se pierde cuando se modifica el archivo de bloqueo según el entorno (versión de hilo instalada actualmente).
¿Cuál es el comportamiento esperado?
No escriba yarn.lock o package.json cuando realice la instalación de hilo.
Para actualizar yarn.lock use yarn upgrade

Para ser más precisos, la semántica esperada, en mi opinión, es:

  • si package.json no ha cambiado desde la última vez que yarn.lock cambió, yarn.lock es la fuente de la verdad y no debe actualizarse.
  • si package.json ha cambiado desde la última vez, yarn.lock cambió, actualice yarn.lock para que satisfaga package.json y actualice node_modules .
  • si se ejecuta yarn update , vuelva a resolver todas las dependencias y obtenga la última versión de todo lo que satisfaga los package.json .

Esto significa que cuando un repositorio se clona por primera vez en una máquina , si se registró yarn.lock , el hilo siempre debe tratarlo como la fuente de la verdad, no generar actualizaciones para yarn.lock y saltar directamente al paso de búsqueda.

En la medida en que este no sea el comportamiento actual del hilo, creo que sería un error.


@esphen escribió:

Estoy de acuerdo. Debería haber una discusión sobre por qué yarn install escribe un archivo de bloqueo por defecto en primer lugar, ya que parece estar en desacuerdo con todo el concepto de archivo de bloqueo. ¿Por qué tener un archivo de bloqueo si no bloquea las versiones de forma predeterminada?

Creo que lo que esto está tratando de decir es que el hilo no debería escribir un nuevo archivo de bloqueo si el existente todavía está actualizado. Estoy de acuerdo con eso.

Estoy de acuerdo con la opinión de @bestander de que solo las acciones mutantes deberían actualizar el archivo de bloqueo de forma predeterminada, es decir, agregar / actualizar / eliminar.

El problema principal aquí es si un cambio en package.json debería hacer que yarn.lock se actualice. En mi opinión, si el cambio al package.json no es satisfecho por el yarn.lock , debe actualizar el yarn.lock .

Un invariante importante de los sistemas de archivos de bloqueo como yarn es que, utilizando el flujo de trabajo normal, los desarrolladores pueden estar seguros de que los paquetes que realmente se utilizan cuando ejecutan su aplicación coinciden con las versiones especificadas en su package.json . Si se permite que el package.json esté sincronizado con el yarn.lock , esto no será cierto, y la única forma de saberlo será que los lectores humanos lean cuidadosamente el yarn.lock .

La mejor manera para que la mayoría de los usuarios piensen en el archivo de bloqueo es que es un artefacto del hilo en ejecución que representa las versiones precisas de todos los paquetes que se usaron para el actual package.json . Al registrarlo, otros colaboradores, CI y el código de producción tienen la seguridad de usar esas mismas versiones.


@Guuz dijo:

Entonces, para verificar si entiendo esto correctamente:
yarn instala todas las dependencias y también modifica el archivo de bloqueo. En un servidor CI debería usar yarn install --pure-lockfile?

Esta pregunta se hace eco de un sentimiento que algunas personas han expresado en este hilo.

La carga tiene una bandera --locked que dice "si el package.json no está satisfecho con el yarn.lock , es un error grave". Bundler tiene una bandera similar ( --frozen ), que se agregó cuando Heroku adoptó Bundler, para dar a las personas un error grave si realizaban cambios locales en sus Gemfile y se olvidaban de registrar los Gemfile.lock .

La idea es que durante su desarrollo normal, le gustaría poder realizar cambios en el package.json y hacer que el hilo se asegure de que el yarn.lock permanezca sincronizado (nuevamente, para asegurarse de que las versiones especificadas en package.json siempre coincide con lo que se usa en la práctica).

Pero al implementar, virtualmente siempre es un error haber divergido, porque significa que hizo un cambio a package.json , ejecutó un comando local yarn y olvidó registrar yarn.lock . Esto significa que las versiones en su package.json no coinciden con las versiones reales utilizadas cuando se ejecuta la aplicación , lo que dijimos viola un invariante fundamental de hilo.


@esphen dijo:

En mi opinión, una de las funciones que desempeña un administrador de paquetes es hacer que sea lo más fácil posible comenzar con el desarrollo de un proyecto. Una instalación simple de hilo debería obtener todos los paquetes que necesita para comenzar a desarrollar, sin ninguna confusión involucrada.

Creo que esto no es controvertido.

Con npm, he tenido muchas instancias de desarrolladores que se unieron a un proyecto, solo para descubrir que un proyecto no funciona en su máquina. Estas instancias se han producido debido a dependencias transitorias que desplazan versiones a versiones con cambios importantes o simplemente no siguen a semver. Tenía la esperanza de que yarn resolvería estos problemas, pero si la conclusión es que todos los desarrolladores de un proyecto deberían ejecutar yarn install --pure-lockfile para estar 100% seguros de que el proyecto se va a construir, entonces ese no es el caso.

Ejecutar yarn install --pure-lockfile significará que el archivo de bloqueo será respetado incluso si las versiones dentro del archivo de bloqueo entran en conflicto con las versiones especificadas en package.json . Esto solo debería surgir en primer lugar si un desarrollador se olvida de registrar su yarn.lock después de realizar cambios en el package.json .

Otra función de un administrador de paquetes es dar a los proyectos el control de sus dependencias. Si se hace puro de forma predeterminada, los desarrolladores pueden echar un vistazo al hilo desactualizado para ver las versiones desactualizadas y luego revisar las notas de cambio, evitando cambios importantes. Esto le daría a los desarrolladores un control total para solo ejecutar versiones en un período de tiempo de lanzamiento dado en lugar de prohibir a los desarrolladores hacer git commit -a para evitar confirmaciones accidentales de archivos de bloqueo.

Si package.json no ha cambiado, en mi opinión, es un error si yarn.lock se está actualizando. Al menos un caso del error parece estar en el informe original:

El archivo de bloqueo se modifica según el entorno (versión del hilo instalada actualmente).

Creo que esto es un error y debería corregirse.

Más adelante en el hilo, @thejameskyle dijo:

Imagine una función memoize donde la entrada es un package.json y la salida es yarn.lock.

Ese es exactamente el modelo mental correcto, en mi opinión (" yarn.lock puede cambiar si y solo si package.json cambió"), y si la abstracción tiene fugas, deberíamos arreglarlo.


@adamchainz dijo:

Más información sobre lo anterior: nuestra compilación tiene coffeescript de Github como subdependencia. coffeescript presionó algunas confirmaciones y obtuvimos un yarn.lock modificado en nuestro proceso de compilación al ejecutar solo yarn install

y después:

Pero tiene el mal comportamiento si se instala una dependencia desde github, como informé anteriormente

El problema aquí es que yarn no trata a git sha como parte de la versión bloqueada de las dependencias de git. Cargo y Bundler tienen el concepto de una versión "precisa" que se serializa en el archivo de bloqueo; para las fuentes de git, la versión "precisa" es el SHA. Luego, cuando crea un clon nuevo con solo package.json y yarn.lock y ejecuta yarn , toda la información necesaria para obtener precisamente el código que necesita está ahí.

Debo confesar que me perdí esta interacción al revisar el código git original; hay algún seguimiento SHA en el código, pero yarn install no asegura que el gráfico de dependencia hidratada lo respete.


TL; DR

Estoy de acuerdo con @thejameskyle y @kittens en que yarn.lock debe mantenerse sincronizado con package.json automáticamente, porque creo que los usuarios deben poder asumir que las versiones especificadas en su package.json alinearse con lo que se usa cuando se ejecuta su aplicación.

Sin embargo, parece haber algunos errores que están causando una rotación inapropiada en el yarn.lock incluso cuando el package.json no ha cambiado:

  • los cambios en la versión de hilo en las máquinas actualizan el archivo de bloqueo
  • Las dependencias de git se actualizan incluso si package.json no se ha actualizado, lo que luego actualiza el archivo de bloqueo

También deberíamos considerar algo como la bandera --locked Cargo, que puede usar en CI para fallar rápidamente en la compilación si un desarrollador actualiza package.json y se olvida de registrar el yarn.lock actualizado

@thejameskyle ¡Gracias! : corazón: Estoy de acuerdo contigo y @kittens en que yarn.lock debería actualizarse después de cambiar package.json

@wycats Una --locked (o similar). Deberíamos crear un nuevo tema sobre eso.

Hecho # 1568 para rastrear el problema de git SHA

@wycats , ¡gracias por la descripción muy reveladora y reveladora!

Esto significa que cuando un repositorio se clona por primera vez en una máquina, si se registró yarn.lock, yarn siempre debe tratarlo como la fuente de la verdad, no generar actualizaciones para yarn.lock y saltar directamente al paso de búsqueda.
En la medida en que este no sea el comportamiento actual del hilo, creo que sería un error.

Ese es exactamente el escenario por el que se ha abierto este tema.
Tenemos algunas versiones activas de Yarn en la empresa y, a nuestra escala, no creo que podamos realizar actualizaciones atómicas en todas partes.
Las construcciones sobre los hilos 0.13, 0.14 y 0.15 introdujeron ligeras variaciones en los archivos yarn.lock a pesar de que package.json estaba sincronizado.
Esto provocó algunos problemas, por ejemplo, las compilaciones de Buck se ralentizaron porque los cambios en el árbol de origen invalidan las cachés.
Esto provocó que un par de equipos y yo tuviéramos unas horas de trabajo.

@thejameskyle , gracias por compartir tu opinión.
Para ser justos, no consideré el escenario de que package.json no estuviera sincronizado con yarn.lock. Y tienes un punto válido.

Sin embargo, como señaló @wycats , el informe de error original es válido.
Arreglar esto es importante para tener compilaciones válidas y reabriré el problema con la intención de encontrar una solución que satisfaga a todas las partes interesadas.

@wycats

Para ser más precisos, la semántica esperada, en mi opinión, es:

  • si package.json no ha cambiado desde la última vez que yarn.lock cambió, yarn.lock es la fuente de la verdad y no debe actualizarse.
  • si package.json ha cambiado desde la última vez, yarn.lock cambió, actualice yarn.lock para que satisfaga package.json y actualice node_modules .
  • si se ejecuta yarn update , vuelva a resolver todas las dependencias y obtenga la última versión de todo lo que satisfaga los package.json .

Esto significa que cuando un repositorio se clona por primera vez en una máquina , si se registró yarn.lock , el hilo siempre debe tratarlo como la fuente de la verdad, no generar actualizaciones para yarn.lock y saltar directamente al paso de búsqueda.

Esta es la semántica que seguimos que agregué en el # 364.

@bestander Estuviste involucrado en las relaciones públicas (# 364) que pusieron estas heurísticas en su lugar. ¿Qué cambios adicionales propones?

Este problema es extremadamente amplio y ya hemos acordado que --pure-lockfile no será el valor predeterminado y seguiremos la heurística descrita por @wycats. Si este problema debe permanecer abierto, el título debe reflejar el problema actual con este comportamiento.

@kittens suena bien, actualizaré el problema.
O tal vez debería abrir uno nuevo relacionado con la instalación cambiando el archivo de bloqueo cuando package.json no cambió

¿Podemos pasar a una nueva edición? Estos comentarios aquí solo se pueden conservar como un archivo

Suena bien, @thejameskyle , crearé un nuevo número hoy y vincularé aquí

Creó el nuevo problema enfocado https://github.com/yarnpkg/yarn/issues/1576

Sería interesante tener una opción para hacer que yarn install falle si el paquete en package.json no está en yarn.lock, es decir. fallar si algún paquete no está bloqueado

Añadiendo una aclaración que todavía me resultaba ambigua después de leer lo anterior:

tldr; Los cambios no relacionados en package.json no actualizarán un paquete a la última versión compatible con su package.json semver sin cambios.

Según algunas de las palabras anteriores, parecía que yarn.lock se almacenó en caché con una clave en un hash de package.json y, por lo tanto, sonaba como que yarn.lock se escribiría en (actualizado / caché invalidado ) en cualquier cambio a package.json , lo cual sería problemático ya que un cambio no relacionado (es decir, una actualización a "description" u otra dependencia) podría hacer que la versión yarn.lock esa dependencia se actualice a una versión más reciente dentro del mismo package.json semver existente.

Sin embargo, verifiqué que la entrada yarn.lock un paquete solo se escribe cuando se actualiza su package.json semver correspondiente (incluso si el nuevo semver es compatible con la versión yarn.lock , y en consecuencia, no necesitaría de otra manera una actualización de la versión).

Por ejemplo,

  • Digamos que yarn add lodash@^4.17.1 instala [email protected]
  • Más tarde, [email protected] está disponible.
  • hilo seguirá instalando [email protected]
  • A menos que / Hasta que la versión de lodash se modifique en package.json (o agregar / actualizar / eliminar hilo se ejecuta específicamente contra lodash).

Pan rallado # 1576

Por cierto, si está dispuesto a contribuir a los documentos con artículos pequeños como este, sería genial para la comunidad.
El equipo central está ocupado solucionando problemas y agregando nuevas funciones, y se espera y agradece que la comunidad ayude a mantener la documentación.

@CrabDude gracias por compartir tu aclaración.

¿Quiere decir, en su ejemplo anterior, que solo lodash y sus propias dependencias tendrán sus versiones de bloqueo actualizadas en yarn.lock ? por ejemplo, incluso si otra dependencia pudiera tener una nueva versión de bloqueo, ¿no se actualizará al mismo tiempo?

O un segundo ejemplo: digamos que un yarn.lock está muy desactualizado y el usuario ejecuta yarn add para agregar una nueva dependencia a package.json. ¿Todos los demás paquetes obsoletos se actualizarán ahora en yarn.lock , o seguirán siendo los mismos?

@rarkins

¿Quiere decir, en su ejemplo anterior, que solo lodash y sus propias dependencias tendrán sus versiones de bloqueo actualizadas en yarn.lock?

Si. Esto parece confirmarse en mi ejemplo.

¿Todos los demás paquetes obsoletos se actualizarán ahora en yarn.lock o seguirán siendo los mismos?

Parecería que los árboles de dependencia / entradas de bloqueo de paquetes que no son lodash no se actualizarían; solo lo serían las subdependencias de lodash .

Desde mi perspectiva, cada uno de estos es deseable y esperado.

Prefacio : me encanta el hilo. Pero me frustra muchísimo.

En mi empresa, yarn install cambia el archivo de bloqueo constantemente en diferentes máquinas (cada una con la misma versión), a pesar de que nunca cambia package.json . Y cuando lo hacemos, lo actualizamos usando yarn add . Esto es molesto porque CI verifica que el estado de git esté limpio después de una compilación para asegurarse de que no nos olvidamos de hacer cosas como verificar un archivo de bloqueo, y cambia con frecuencia.

Mi expectativa de hilo era que aseguraría módulos de nodo idénticos en todas las máquinas _por defecto_. No con banderas adicionales. Priorizaría la corrección sobre la conveniencia. Si quisiera incertidumbre, podría usar npm directamente. Cuando un archivo cambia, es una señal para mí de que algo lo ha cambiado y debería examinarlo. No debería cambiar.

Preguntas

  • ¿Se está diciendo que a pesar de que se haya cambiado el archivo de bloqueo, el contenido de node_modules siempre será idéntico a cuando se generó? No creo que este sea el caso, pero si lo es, entonces entiendo la confusión en este hilo: significaría que el hilo hace lo correcto a pesar de la apariencia de que no lo hace.
  • Cuando package.json cambia, el archivo de bloqueo se regenera. ¿No podría eso cambiar involuntariamente muchas dependencias dependiendo del estado de los módulos de nodo de ese programador en particular? El hilo debe determinar un delta y tratar de preservar los bloqueos existentes lo mejor que pueda (si aún no lo ha hecho).
  • ¿Por qué yarn add especifica versiones en package.json con ^ ? Una vez más, entendí que la promesa de Yarn era congelar las dependencias.

Errores relacionados

  • Cuando se elimina un paquete aleatorio en node_modules , yarn install dice éxito sin reinstalarlo. Cuando muchos de ellos se han ido, los reinstala. npm es un poco más completo en este sentido.
  • El archivo de bloqueo tiende a regenerarse si elimina node_modules y realiza una instalación limpia (que es literalmente lo contrario de lo que esperaría; espero que instale exactamente lo que está en el archivo de bloqueo y no haga absolutamente nada más)
  • Si elimina el archivo de bloqueo sin tocar el paquete o node_modules después de una instalación limpia, el hilo lo regenera y suele ser muy diferente a la versión anterior. Esto es como un compilador que produce un código diferente cada vez que lo ejecuta a pesar de no cambiar nada.

En general, yarn hace que las instalaciones sean más rápidas, pero parece fallar en su (in) competencia central: congelar versiones, de manera consistente, por defecto. No necesito comodidades que me ayuden a poner en marcha mi proyecto, necesito ayuda para mantenerlo en un gran equipo durante muchos años. Los programadores son inteligentes e intencionales, cuando quieren un cambio, lo preguntan explícitamente.

El archivo de bloqueo en constante cambio no infunde confianza y es una molestia constante. Preferiría advertencias y errores de que package.json no coincide con el archivo de bloqueo, que el archivo de bloqueo no coincide con node_modules, que ya no existe una versión bloqueada, etc., por lo que detiene mis compilaciones en seco y puedo tomar decisiones intencionales sobre mis dependencias.

@jspiro , gracias por escribir esto.
Aquí se plantean algunas cuestiones.
Sería mejor abrir cada número por separado, de lo contrario se perderán en los comentarios.

¿Tiene la última versión de Yarn?
A partir de 0.18-0.19 no vemos modificaciones en los archivos yarn.lock entre máquinas.

Preguntas:

¿Se está diciendo que a pesar de que se haya cambiado el archivo de bloqueo, el contenido de node_modules siempre será idéntico a cuando se generó? No creo que este sea el caso, pero si lo es, entonces entiendo la confusión en este hilo: significaría que el hilo hace lo correcto a pesar de la apariencia de que no lo hace.

Dev y las dependencias opcionales se pueden dejar fuera para el mismo archivo de bloqueo.
Pero los que tienen bing instalado, excepto los paquetes específicos de la plataforma, node_modules deben tener paquetes idénticos en lugares idénticos.

Cuando cambia package.json, el archivo de bloqueo se regenera. ¿No podría eso cambiar involuntariamente muchas dependencias dependiendo del estado de los módulos de nodo de ese programador en particular? El hilo debe determinar un delta y tratar de preservar los bloqueos existentes lo mejor que pueda (si aún no lo ha hecho).

Esa es una buena solicitud de función, me encantaría ver un PR para eso.

¿Por qué yarn agrega versiones específicas en package.json con ^? Una vez más, entendí que la promesa de Yarn era congelar las dependencias.

Eso refleja el comportamiento de npm.
Puede hacer yarn add [email protected] o yarn add is-array --exact para la versión exacta.
Tal vez en algún momento debamos hacer que las versiones exactas sean predeterminadas, esto puede ser una discusión en un RFC.

Cuando se elimina un paquete aleatorio en node_modules, yarn install dice éxito sin reinstalarlo. Cuando muchos de ellos se han ido, los reinstala. npm es un poco más completo en este sentido.

Yarn realiza una comprobación rápida y superficial de forma predeterminada.
Hacer una verificación más profunda será más lento, pero estamos trabajando en ello, tengo una idea de cómo podríamos hacer una verificación profunda rápida.
Sin embargo, se supone que no debe tocar archivos en node_modules, verificar cada archivo para su modificación resultaría en una experiencia de instalación muy lenta.
Si desea omitir la verificación superficial, elimine el archivo node_modules/.yarn-integrity antes de la instalación. Esto no es oficial y está sujeto a cambios.
Una forma oficial es ejecutar yarn install --force , forzaría la instalación completa pero reescribiría yarn.lock como efecto secundario.

El archivo de bloqueo tiende a regenerarse si elimina node_modules y realiza una instalación limpia (que es literalmente lo contrario de lo que esperaría; espero que instale exactamente lo que está en el archivo de bloqueo y no haga absolutamente nada más)

No he visto esto por un tiempo.
Abra un problema y envíeme una copia si se puede reproducir.

Si elimina el archivo de bloqueo sin tocar package o node_modules después de una instalación limpia, yarn lo regenera y suele ser muy diferente a la versión anterior. Esto es como un compilador que produce un código diferente cada vez que lo ejecuta a pesar de no cambiar nada.

Después de algún tiempo, es posible que se hayan lanzado nuevas versiones de dependencias transitivas.
Por eso, la estructura de node_modules puede cambiar significativamente debido a la lógica de elevación.
Eso funciona según lo diseñado.
El comando import viene https://github.com/yarnpkg/yarn/pull/2580.
Eso le permitiría generar un archivo de bloqueo a partir de node_modules existentes.

@jspiro , Yarn es un proyecto joven impulsado por la comunidad, sus relaciones públicas para que funcione mejor para usted son bienvenidos.

¿Alguna posibilidad de obtener al menos una opción para establecer el comportamiento predeterminado deseado?

Actualmente estamos solucionando este problema https://github.com/yarnpkg/yarn/issues/3490 , a veces yarn install puede hacer que el archivo de bloqueo se optimice, lo que no es un comportamiento esperado y lo solucionaremos.
Esa podría ser la razón por la que solicita este cambio; de lo contrario, el archivo yarn.lock debería cambiar solo si realiza cambios en package.json manualmente.

Puede establecer --pure-lockfile / - frozen-lockfile en verdadero en .yarnrc y se agregará al comando de instalación de forma predeterminada:

--install.pure-lockfile true

Mi problema es que si no uso pure-lockfile, obtengo la versión incorrecta de las dependencias instaladas. No está relacionado con los cambios de hilo no deseados.

¿Puede enviar un problema con los pasos de reproducción?
Lo solucionaremos

Esto también me mordió cuando un package.json y yarn.lock se desincronizaron debido a que un desarrollador agregó por error una dependencia a través de npm install --save lugar de yarn add .

Sin embargo, no estoy de acuerdo en que pure-lockfile debería ser el valor predeterminado y sostengo que en lugar de frozen-lockfile debería ser el valor predeterminado para yarn install .

Como frozen-lockfile produce un mensaje de error si yarn.lock y package.json están sincronizados. El frozen-lockfile es, por lo tanto, muy útil en una máquina de compilación (es decir, jenkins) ya que marcará esas compilaciones, como era de esperar, como una falla.

Luego, depende del desarrollador decidir qué versión agregar en package.json / yarn.lock.

El desafortunado valor predeterminado de yarn install solo obtendrá la versión más actual de las dependencias aún no bloqueadas y escribirá una versión actualizada yarn.lock , que nunca será parte del proyecto. Por lo tanto, permite futuras interrupciones de la compilación debido a un cambio inesperado en la versión. Esa es la razón por la que tenemos un archivo de bloqueo para empezar.

Sin embargo, la esencia debería ser:

Solo comandos como add , remove y upgrade deben mutar el yarn.lock .

install debería hacer eso, es decir, instalar las dependencias en su versión bloqueada o fallar si detecta una discrepancia entre package.json y yarn.lock . (La única excepción es si no hay yarn.lock en primer lugar. Entonces, y solo entonces, puede crear uno, pero nunca, nunca debería volver a tocarlo).

Por lo tanto, el archivo de bloqueo congelado es muy útil en la máquina de compilación (es decir, jenkins), ya que esa compilación fallará.

Creo que podemos habilitar esto automáticamente cuando detectemos que estamos en modo CI.

@BYK No me di cuenta de que este problema estaba cerrado antes de agregarlo aquí. ¿Debería abrir uno nuevo o se puede volver a abrir?

Yo diría que abre uno nuevo ☺️

Estoy de acuerdo con @thejameskyle y @kittens en que yarn.lock debe mantenerse sincronizado con package.json automáticamente

No estoy seguro de si se ha dicho esto, pero por si acaso: no tiene que invalidar todo el yarn.lock cuando algo en package.json cambia. Puede invalidar solo las dependencias de solo los paquetes que se modificaron dentro de package.json. Fe si actualizó solo TypeScript, las dependencias de TypeScript deberían modificarse (con consideraciones respecto a otros paquetes sin cambios).

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