Você deseja solicitar um _feature_ ou denunciar um _bug_?
_recurso_
Qual é o comportamento atual?
Não passar --pure-lockfile
para install
comando me confunde porque ele modifica o arquivo de bloqueio ao instalar node_modules.
Nós concordamos na semântica de que add/upgrade/remove
deve alterar dependências e install
deve reconstruir consistentemente node_modules a partir de lockfile.
A consistência é perdida quando o arquivo de bloqueio é modificado, dependendo do ambiente (versão do yarn atualmente instalada).
Qual é o comportamento esperado?
Não escreva yarn.lock ou package.json ao fazer yarn install
.
Para atualizar yarn.lock use yarn upgrade
Mencione seu node.js, yarn e versão do sistema operacional.
fio 0,14
Eu concordo. Deve haver uma discussão sobre por que yarn install
grava um arquivo de bloqueio por padrão em primeiro lugar, já que parece estar em desacordo com o conceito inteiro de arquivo de bloqueio. Por que ter um arquivo de bloqueio se ele não está bloqueando as versões por padrão?
Existe um caso para yarn install
criar um arquivo de bloqueio se nenhum estiver presente, ou seja, quando alguém está convertendo um projeto para usar yarn
, mas a razão para sempre escrevê-lo não é clara. Eu concordo com a opinião de @bestander de que apenas ações mutantes devem atualizar o arquivo de bloqueio por padrão, ou seja, add/upgrade/remove
.
Deve haver uma maneira de modificar o arquivo de bloqueio sem add/remove/upgrade
ex: no cenário quando você atualiza o Yarn e ele usa uma nova versão do arquivo de bloqueio?
Suponho que a opção poderia ser invertida
yarn install --save-lockfile
Em 17 de outubro de 2016 às 18:53, James Ide [email protected] escreveu:
Deve haver uma maneira de modificar o arquivo de bloqueio sem adicionar / remover / atualizar
ex: no cenário quando você atualiza o Yarn e usa um novo arquivo de bloqueio
versão?-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/yarnpkg/yarn/issues/570#issuecomment -254282256 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/ACBdWJLpdvqiwcBwqE4KB3x3f4oCn_nVks5q07YYgaJpZM4KSlSw
.
Eu também estou confuso com isso. Qual é o motivo do comportamento padrão atual?
Afaik, não havia razões fortes para o comportamento padrão.
A ideia, suponho, é manter os arquivos de bloqueio das pessoas "perenes".
BTW PR é bem-vindo
Acho que a razão para isso foi que o fio foi originalmente projetado com um único comando install
que foi dividido em install/add/upgrade
Então, para verificar se entendi corretamente:
yarn
instala todas as dependências e também modifica o arquivo de bloqueio. Em um servidor de CI, você deve usar yarn install --pure-lockfile
?
Por que o lockfile é modificado durante uma instalação? Já que você não está atualizando nada ... Yarn deve apenas instalar os pacotes conforme descrito no lockfile, certo?
Obrigada pelo esclarecimento!
O problema é que se o arquivo de bloqueio for puro por padrão, as pessoas vão se esquecer de atualizá-lo, pois seria um comando separado.
@kittens O arquivo de bloqueio não deve ser atualizado apenas ao adicionar / remover / atualizar qualquer pacote? Esses devem sempre atualizar o arquivo de bloqueio, bem como uma instalação inicial.
O problema é que se o arquivo de bloqueio for puro por padrão, as pessoas vão se esquecer de atualizá-lo, pois seria um comando separado
Ser um problema depende do que você considera ser o objetivo principal de um gerenciador de pacotes.
Na minha opinião, uma das funções que um gerenciador de pacotes desempenha é facilitar ao máximo o início do desenvolvimento de um projeto. Um simples yarn install
deve receber todos os pacotes que você precisa para começar a desenvolver, sem nenhuma confusão envolvida.
Com npm
, tive muitas instâncias de desenvolvedores ingressando em um projeto, apenas para descobrir que um projeto não funciona em sua máquina. Essas instâncias ocorreram devido a dependências temporárias que impulsionaram as versões para versões com alterações significativas ou simplesmente não seguindo o semver. Eu esperava que yarn
resolvesse esses problemas, mas se a conclusão é que todos os desenvolvedores em um projeto devem executar yarn install --pure-lockfile
para ter 100% de certeza de que o projeto vai ser construído, então isso não é O caso.
Outra função de um gerenciador de pacotes é fornecer aos projetos o controle de suas dependências. Se for feito puro por padrão, os desenvolvedores podem dar uma olhada em yarn outdated
para ver as versões desatualizadas e, em seguida, revisar as notas de alteração, evitando alterações interruptivas. Isso daria aos desenvolvedores controle total para apenas alterar as versões em um determinado período de lançamento, em vez de proibir os desenvolvedores de fazer git commit -a
para evitar commits de arquivos de bloqueio acidentais.
Eu concordo com tudo o que @esphen diz. Estou surpreso de que o comportamento puro não seja o padrão no Yarn - pensei que esse tipo de consistência fosse o principal benefício que o Yarn tinha sobre o NPM. Esse deve ser o motivo mais convincente para mudar do NPM da forma como eu o vejo.
Nos surpreendeu totalmente quebrando a compilação depois que começamos a usar yarn
por alguns dias. Sinceramente, pensei que --pure-lockfile
era o comportamento padrão depois de ler grande parte da documentação e sobre como ele é melhor do que o npm com embalagem plástica. Por favor, torne o padrão :)
@ide Imagine um cenário em que alguém está apenas usando npm e atualiza package.json
, como yarn.lock
será atualizado?
Alguém pode escrever os cenários que levam ao lockfile sendo modificado inesperadamente? Esta mudança é grave e faz o lockfile um cidadão de segunda classe, exigindo atualizações para que ele seja explícito o que significa um monte de sobrecarga em lembrar que operações resultar em que está sendo atualizado etc.
Mais informações sobre o acima: nosso build tem coffeescript do Github como uma subdependência. coffeescript empurrou alguns commits e obtivemos um yarn.lock
modificado em nosso processo de compilação executando apenas 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"
Alguém pode escrever os cenários que levam ao lockfile sendo modificado inesperadamente? Esta mudança é séria e torna o arquivo de bloqueio um cidadão de segunda classe, exigindo que as atualizações sejam explícitas, o que significa uma grande sobrecarga ao lembrar quais operações resultam em sua atualização etc.
Percebo yarn install
como um comando que cria node_modules para mim.
É o oposto de yarn add
e yarn remove
que modificam package.json, yarn.lock e cleanup node_modules.
Ao contrário de add
e remove
, corro install
100 vezes mais frequentemente, especialmente em CI, onde nunca espero ter efeitos colaterais.
Exemplos de quando não espero que as coisas mudem:
yarn install
em yarn.lock gerado por meus companheiros de equipe, recebo um arquivo yarn.lock modificado que preciso lembrar de não enviar.@kittens
O problema é que se o arquivo de bloqueio for puro por padrão, as pessoas vão se esquecer de atualizá-lo, pois seria um comando separado.
Imagine um cenário em que alguém está apenas usando o npm e atualiza o package.json, como o yarn.lock será atualizado?
Se assumirmos que yarn install
não deve atualizar yarn.lock
, então também deve falhar se yarn.lock
estiver fora de sincronia com package.json
para destacar o fato de que yarn install --save-lockfile
é necessário para trazer tudo de volta em sincronia.
A instalação do fio +1 não deve alterar o yarn.lock
Não estou preocupado em atualizar o arquivo de bloqueio. Idealmente, o greenkeeper faria isso quando as dependências mudassem e pudéssemos mesclar a mudança do arquivo de bloqueio então.
Quero atualizar este problema com os pensamentos atuais sobre ele. @kittens e eu achamos que --pure-lockfile
_não_ deveria ser o padrão por alguns motivos.
Começa com como as pessoas adicionam / removem / atualizam dependências. Embora existam comandos para ele, é prática comum atualizar manualmente o package.json
manualmente ou por outra ferramenta como o Lerna .
Depois de modificar manualmente o package.json
a expectativa tanto no Yarn quanto no npm é que, ao executar outra instalação, ele _sincronize_ com package.json
. Nesse sentido, yarn install
quase poderia ser renomeado para yarn sync
.
No tópico de sincronização, ao executar uma instalação com novas dependências, você espera que o diretório node_modules
reflita essas alterações. Como yarn.lock
atua como um assistente de node_modules
você deve esperar que ele permaneça em sincronia da mesma maneira.
Seu package.json
é a fonte suprema da verdade, essa é sua interface para o yarn, é sua configuração e é a única coisa com a qual você deve se preocupar. Em um mundo ideal, você simplesmente compromete seus yarn.lock
e nunca mais terá que pensar sobre isso novamente.
Por outro lado, acredito que muitas pessoas que estão expressando seu apoio a este problema estão confusas sobre o que realmente está sendo discutido aqui.
Usar --pure-lockfile
por padrão não significa que o Yarn não produz resultados consistentes e confiáveis. O mesmo package.json
resultará nos mesmos yarn.lock
que resultará nos mesmos node_modules
100% das vezes.
Quando você atualiza suas package.json
suas yarn.lock
atualizações de arquivo e, em seguida, suas node_modules
atualizações. Essa é uma ordem muito natural para as coisas e devemos mantê-la assim
Em relação ao CI ser capaz de obter dependências diferentes quando você atualizou seu package.json
mas não executou yarn install
para sincronizar tudo o que tenho certeza que alguém abrirá (embora eu não veja como um problema) - eu e outros temos conversado com várias ferramentas de CI sobre a integração do Yarn, podemos facilmente fazer com que eles usem --pure-lockfile
por padrão, se as pessoas virem isso como um grande problema.
Se tivéssemos que fazer essa alteração, ela teria um impacto negativo com muito mais frequência ao alterar as dependências. Pelas razões que listei, acho que devemos encerrar este problema.
@thejameskyle Eu agradeceria se você pudesse esclarecer algo:
package.json
que contém uma dependência "foo": "^1.0.0"
yarn install
. O pacote foo
está atualmente na versão 1.0.0
, então ele cria um arquivo yarn.lock
que bloqueia em [email protected]
yarn.lock
ao Git.yarn install
, mas foo
agora foi atualizado para a versão 1.1.0
, então Yarn instala [email protected]
e sobrescreve yarn.lock
com a nova versão de foo
foo
teve uma alteração significativa na versão 1.1.0
Aqui está uma situação semelhante:
package.json
que contém uma dependência "foo": "^1.0.0"
, que está bloqueado como [email protected]
, e yarn.lock
é salvo no Git.yarn install
ele obtém a versão [email protected]
que faz com que yarn.lock
seja atualizado.foo
teve uma alteração significativa na versão 1.1.0
Acho que esse é o tipo de situação com que a maioria das pessoas se preocupa.
Portanto, se você pudesse esclarecer que o comportamento atual de yarn install
não tem os problemas acima, acho que isso eliminaria muitos de nossos medos. : +1:
Nenhuma dessas situações se aplica. Só porque uma dependência foi atualizada, não significa que você a receberá, apenas se tiver feito alterações em package.json
.
Vou apenas encerrar este assunto porque realmente parece que essa é a única preocupação que as pessoas têm, o que, como eu disse, não é um cenário real. Esse problema provavelmente está causando mais confusão.
Mas tem o mau comportamento se uma dependência está sendo instalada a partir do github, como eu relatei acima
@adamchainz Isso deve ser corrigido separadamente, podemos facilmente bloqueá-lo no commit
Nenhuma dessas situações se aplica. Só porque uma dependência foi atualizada, não significa que você a receberá, apenas se tiver feito alterações em
package.json
.
@thejameskyle : Não tenho certeza se entendi por que esse não é um cenário real. Você poderia, por favor, explicar?
Imagine uma função memoize onde a entrada é package.json
e a saída é yarn.lock
.
package.json
ele cria um yarn.lock
e armazena o resultado em cache.package.json
o resultado será exatamente o mesmo porque está armazenado em cache.package.json
você invalidou o cache e agora o yarn.lock
será recalculado.O que estamos falando agora é nos livrarmos de # 3 e, em vez disso, tratar yarn.lock
como se não tivesse sido invalidado pelo package.json
alterado. O que seria muito estranho para uma função memoize ter e seria um comportamento muito estranho para Yarn ter.
O que acontece com um pacote em termos de commits e novas versões _deve_ ser irrelevante (se tivermos um bug com git commits, devemos consertar isso separadamente, mas não está relacionado a esse problema).
É mais complexo do que eu imaginei (cada versão de pacote é efetivamente "memoizada" individualmente, mudar a versão de um pacote não invalida o resto), mas espero que agora todos entendam.
@thejameskyle : Por uma questão de clareza (e curiosidade), digamos que eu tenho um projeto com um arquivo yarn.lock
e alguém puxa o repositório. Sem executar yarn install
ou npm install
, essa pessoa adiciona uma nova dependência ao arquivo package.json
e executa yarn install
. O arquivo yarn.lock
será completamente desconsiderado neste caso?
Há um monte de coisas diferentes acontecendo aqui que eu queria tentar desvendar (sem trocadilhos).
Primeiro, as pessoas levantaram uma série de requisitos diferentes que considero incontroversos (e que tornam alguns dos comportamentos existentes bugs, dos quais falarei em breve).
Do relatório de bug original.
A consistência é perdida quando o arquivo de bloqueio é modificado, dependendo do ambiente (versão do yarn atualmente instalada).
Qual é o comportamento esperado?
Não escreva yarn.lock ou package.json ao fazer a instalação do yarn.
Para atualizar o yarn.lock, use a atualização do yarn
Para ser mais preciso, a semântica esperada, na minha opinião, é:
package.json
não mudou desde a última vez que yarn.lock
mudou, yarn.lock
é a fonte da verdade e não deve ser atualizado.package.json
mudou desde a última vez, yarn.lock
mudou, atualize yarn.lock
para que satisfaça package.json
e atualize node_modules
.yarn update
for executado, resolva novamente todas as dependências e obtenha a versão mais recente de tudo que satisfaça o package.json
.Isso significa que quando um repositório é clonado pela primeira vez em uma máquina , se o yarn.lock
foi verificado, o yarn deve sempre tratá-lo como a fonte da verdade, não gerar atualizações para yarn.lock
e pular diretamente para a etapa de busca.
Na medida em que esse não é o comportamento atual do fio, acredito que seria um bug.
@esphen escreveu:
Eu concordo. Deve haver uma discussão sobre por que yarn install grava um lockfile por padrão em primeiro lugar, já que parece estar em desacordo com todo o conceito de lockfile. Por que ter um arquivo de bloqueio se ele não está bloqueando as versões por padrão?
Acho que o que isso quer dizer é que o yarn não deve escrever um novo arquivo de bloqueio se o existente ainda estiver atualizado. Eu concordo com isso.
Concordo com a opinião de @bestander de que apenas ações mutantes devem atualizar o arquivo de bloqueio por padrão, ou seja, adicionar / atualizar / remover.
O principal problema aqui é se uma mudança em package.json
deve fazer com que yarn.lock
seja atualizado. Na minha opinião, se a mudança para package.json
não for satisfeita pelo yarn.lock
, ele deve atualizar o yarn.lock
.
Uma invariante importante dos sistemas lockfile como o yarn é que, usando o fluxo de trabalho normal, os desenvolvedores podem ter certeza de que os pacotes que realmente são usados quando executam seus aplicativos correspondem às versões especificadas em seus package.json
. Se package.json
ficar fora de sincronia com yarn.lock
, isso não será verdade, e a única maneira de saber isso será para leitores humanos lerem cuidadosamente yarn.lock
.
A melhor maneira para a maioria dos usuários pensar sobre o arquivo de bloqueio é que ele é um artefato do fio em execução que representa as versões precisas de todos os pacotes que foram usados para os package.json
atuais. Ao fazer o check-in, outros colaboradores, CI e código de produção têm a garantia de usar essas mesmas versões.
@Guuz disse:
Então, para verificar se entendi corretamente:
yarn instala todas as dependências e também modifica o lockfile. Em um servidor CI, você deve usar yarn install --pure-lockfile?
Esta pergunta ecoa um sentimento que algumas pessoas fizeram neste tópico.
A carga tem uma bandeira --locked
que diz "se package.json
não for satisfeito com yarn.lock
, é um erro grave". Bundler tem um sinalizador semelhante ( --frozen
), que foi adicionado quando o Heroku adotou o Bundler, para dar às pessoas um erro grave caso fizessem alterações locais em seus Gemfile
e se esquecessem de fazer o check-in de Gemfile.lock
.
A ideia é que durante o seu desenvolvimento normal, você gostaria de ser capaz de fazer alterações em package.json
e fazer com que o yarn.lock
ficasse em sincronia (novamente, para garantir que as versões especificadas em package.json
sempre coincidir com o que é usado na prática).
Mas, durante a implantação, é quase sempre um erro ter divergido, porque significa que você fez uma alteração em package.json
, executou um comando yarn
e se esqueceu de fazer o check-in yarn.lock
. Isso significa que as versões em seu package.json
não correspondem às versões reais usadas quando o aplicativo é executado , o que dizemos que viola uma invariante fundamental do yarn.
@esphen disse:
Na minha opinião, uma das funções que um gerenciador de pacotes desempenha é facilitar ao máximo o início do desenvolvimento de um projeto. Uma simples instalação do yarn deve obter todos os pacotes de que você precisa para começar a desenvolver, sem nenhuma confusão envolvida.
Acho isso incontroverso.
Com o npm, tive muitas instâncias de desenvolvedores que ingressaram em um projeto, apenas para descobrir que um projeto não funciona em sua máquina. Essas instâncias ocorreram devido a dependências temporárias que impulsionaram as versões para versões com alterações significativas ou simplesmente não seguindo o semver. Eu esperava que o yarn resolvesse esses problemas, mas se a conclusão é que todos os desenvolvedores em um projeto devem executar yarn install --pure-lockfile para ter 100% de certeza de que o projeto será construído, então esse não é o caso.
Executar yarn install --pure-lockfile
significará que o arquivo de bloqueio será respeitado mesmo se as versões dentro do arquivo de bloqueio entrarem em conflito com as versões especificadas em package.json
. Isso só deve ocorrer se um desenvolvedor esquecer de fazer o check-in de seu yarn.lock
após fazer alterações em package.json
.
Outra função de um gerenciador de pacotes é fornecer aos projetos o controle de suas dependências. Se for feito puro por padrão, os desenvolvedores podem dar uma olhada no fio desatualizado para ver as versões desatualizadas e, em seguida, revisar as notas de alteração, evitando quaisquer alterações interrompidas. Isso daria aos desenvolvedores controle total para apenas alterar as versões em um determinado período de lançamento, em vez de proibir os desenvolvedores de fazer git commit -a para evitar commits de arquivo de bloqueio acidentais.
Se package.json
não mudou, na minha opinião é um bug se yarn.lock
está sendo atualizado. Pelo menos um caso de bug parece estar no relatório original:
lockfile é modificado dependendo do ambiente (versão do yarn atualmente instalada).
Acho que isso é um erro e deve ser corrigido.
Mais tarde no tópico, @thejameskyle disse:
Imagine uma função memoize em que a entrada é um package.json e a saída é yarn.lock.
Esse é exatamente o modelo mental correto, na minha opinião (" yarn.lock
pode mudar se e somente se package.json
mudar"), e se a abstração vazar, devemos consertar.
@adamchainz disse:
Mais informações sobre o acima: nosso build tem coffeescript do Github como uma subdependência. coffeescript empurrou alguns commits e obtivemos um yarn.lock modificado em nosso processo de compilação executando apenas yarn install
e depois:
Mas tem o mau comportamento se uma dependência está sendo instalada a partir do github, como eu relatei acima
O problema aqui é que o yarn não trata o git sha como parte da versão bloqueada das dependências do git. Cargo e Bundler têm o conceito de uma versão "precisa" que é serializada no arquivo de bloqueio; para fontes git, a versão "precisa" é o SHA. Então, quando você faz um novo clone com apenas package.json
e yarn.lock
e executa yarn
, todas as informações necessárias para obter precisamente o código de que você precisa estão lá.
Devo confessar que perdi essa interação ao revisar o código git original; há algum rastreamento SHA no código, mas yarn install
não garante que o gráfico de dependência hidratada o respeite.
TL; DR
Concordo com @thejameskyle e @kittens que yarn.lock
deve ser mantido em sincronia com package.json
automaticamente, porque acredito que os usuários devem ser capazes de assumir que as versões especificadas em seus package.json
alinhar com o que é usado quando seu aplicativo é executado.
No entanto, parece haver alguns bugs que estão causando rotatividade inadequada no yarn.lock
mesmo quando o package.json
não mudou:
package.json
não tenha sido atualizado, o que então atualiza o arquivo de bloqueioDevemos também considerar algo como a bandeira --locked
da Cargo, que você pode usar em CI para falhar rapidamente a compilação se um desenvolvedor atualizar o package.json
e esquecer de verificar o yarn.lock
atualizado
@thejameskyle Obrigado! : heart: Eu concordo com você e @kittens que yarn.lock
deve ser atualizado após alterar package.json
@wycats Uma --locked
(ou semelhante). Devemos criar uma nova questão sobre isso.
Feito # 1568 para rastrear o problema do git SHA
@wycats , obrigado pela visão geral reveladora e muito perspicaz!
Isso significa que quando um repositório é clonado pela primeira vez em uma máquina, se o yarn.lock foi verificado, o yarn deve sempre tratá-lo como a fonte da verdade, não gerar atualizações para o yarn.lock e pular diretamente para a etapa de busca.
Na medida em que esse não é o comportamento atual do fio, acredito que seria um bug.
Este é exatamente o cenário pelo qual esta edição foi aberta.
Temos algumas versões ativas do Yarn na empresa e, em nossa escala, não acho que seremos capazes de fazer atualizações atômicas em todos os lugares.
As compilações no yarn 0.13, 0.14 e 0.15 introduziram pequenas variações nos arquivos yarn.lock, embora o package.json estivesse em sincronia.
Isso causou alguns problemas, por exemplo, as compilações de Buck foram retardadas porque as mudanças na árvore de origem invalidam os caches.
Isso fez com que eu e algumas equipes trabalhassem algumas horas.
@thejameskyle , obrigado por compartilhar sua opinião.
Não considerei justo o cenário de package.json fora de sincronia com yarn.lock. E você tem um ponto válido.
No entanto, como @wycats apontou, o relatório de bug original é válido.
Corrigir isso é importante para ter compilações válidas e reabrirei o problema com a intenção de apresentar uma solução que satisfaça todas as partes interessadas.
@wycats
Para ser mais preciso, a semântica esperada, na minha opinião, é:
- se
package.json
não mudou desde a última vez queyarn.lock
mudou,yarn.lock
é a fonte da verdade e não deve ser atualizado.- se
package.json
mudou desde a última vez,yarn.lock
mudou, atualizeyarn.lock
para que satisfaçapackage.json
e atualizenode_modules
.- se
yarn update
for executado, resolva novamente todas as dependências e obtenha a versão mais recente de tudo que satisfaça opackage.json
.Isso significa que quando um repositório é clonado pela primeira vez em uma máquina , se o
yarn.lock
foi verificado, o yarn deve sempre tratá-lo como a fonte da verdade, não gerar atualizações parayarn.lock
e pular diretamente para a etapa de busca.
Estas são as semânticas que seguimos e adicionei em # 364.
@bestander Você esteve envolvido no PR (# 364) que implementou essas heurísticas. Que mudanças adicionais você está propondo?
Este problema é extremamente amplo e já concordamos que --pure-lockfile
não será o padrão e seguiremos as heurísticas descritas por @wycats. Se esse problema for mantido em aberto, o título precisa refletir o problema atual com esse comportamento.
@kittens parece bom, atualizarei o problema.
Ou talvez eu deva abrir um novo relacionado à instalação, alterando o arquivo de bloqueio quando o package.json não mudou
Podemos passar para um novo problema? Esses comentários aqui podem apenas ser preservados como um arquivo
Parece bom, @thejameskyle , vou criar um novo problema hoje e criar um link aqui
Criado o novo problema em foco https://github.com/yarnpkg/yarn/issues/1576
seria interessante ter a opção de fazer yarn install
falhar se o pacote em package.json não estiver em yarn.lock, ou seja. falha se algum pacote não estiver bloqueado
Adicionando esclarecimentos que ainda eram ambíguos para mim depois de ler o acima:
tldr; Mudanças não relacionadas em package.json
não irão atualizar um pacote para a versão mais recente compatível com seu package.json
semver inalterado.
Com base em algumas das palavras acima, parecia que yarn.lock
foi armazenado em cache com chave em um hash package.json
e, portanto, parecia que yarn.lock
seria gravado em (atualizado / cache invalidado ) em qualquer alteração em package.json
, o que seria problemático, pois uma alteração não relacionada (ou seja, atualizar para "description"
ou outra dependência) pode fazer com que a versão yarn.lock
dessa dependência seja atualizada para uma versão mais recente dentro do mesmo package.json
existente.
No entanto, verifiquei que a entrada yarn.lock
um pacote só é gravada quando o package.json
semver correspondente é atualizado (mesmo se o novo semver for compatível com a versão yarn.lock
, e consequentemente, não precisaria de uma atualização de versão).
Por exemplo,
yarn add lodash@^4.17.1
instala [email protected]
[email protected]
estará disponível.[email protected]
package.json
(ou adicionar / atualizar / remover yarn é executado especificamente no lodash).Breadcrumb # 1576
A propósito, se você estiver disposto a contribuir com os documentos com pequenos artigos como este, que seriam ótimos para a comunidade.
A equipe principal está ocupada corrigindo problemas e adicionando novos recursos, o que é esperado e apreciado se a comunidade ajudar a manter a documentação
@CrabDude obrigado por compartilhar seus esclarecimentos.
Você quer dizer - em seu exemplo acima - que apenas lodash
e suas próprias dependências terão suas versões de bloqueio atualizadas em yarn.lock
? por exemplo, mesmo se outra dependência puder ter uma nova versão de bloqueio, ela não será atualizada ao mesmo tempo?
Ou um segundo exemplo: Digamos que yarn.lock
esteja severamente desatualizado e o usuário execute yarn add
para adicionar uma nova dependência ao package.json. Todos os outros pacotes desatualizados serão atualizados em yarn.lock
ou permanecerão os mesmos?
@rarkins
Você quer dizer - em seu exemplo acima - que apenas lodash e suas próprias dependências terão suas versões de bloqueio atualizadas em yarn.lock?
sim. Isso parece ser confirmado em meu exemplo.
Todos os outros pacotes desatualizados serão atualizados em yarn.lock ou permanecerão os mesmos?
Parece que as não lodash
árvores de dependência / entradas de bloqueio de pacotes não seriam atualizadas; apenas as subdependências de lodash
seriam.
Do meu ponto de vista, cada um deles é desejável e esperado.
Prefácio : Eu amo fios. Mas isso me frustra infinitamente.
Na minha empresa, yarn install
muda o arquivo de bloqueio constantemente em máquinas diferentes (cada uma executando a mesma versão), apesar de nunca mudar package.json
. E quando o fazemos, atualizamos usando yarn add
. Isso é irritante porque o CI verifica se o status do git está limpo após uma compilação para ter certeza de que não esquecemos de fazer coisas como verificar um arquivo de bloqueio, e ele muda frequentemente.
Minha expectativa do yarn era que ele garantiria node_modules idênticos em todas as máquinas _por padrão_. Não com sinalizadores extras. Isso priorizaria a correção sobre a conveniência. Se eu quisesse incerteza, poderia usar o npm diretamente. Quando um arquivo é alterado, é um sinal de que algo o mudou e devo examiná-lo. Não deve mudar.
Perguntas
package.json
muda, o lockfile é regenerado. Isso não poderia alterar acidentalmente muitas dependências, dependendo do estado dos node_modules desse programador em particular? O fio deve determinar um delta e tentar preservar os bloqueios existentes da melhor maneira possível (se ainda não o fizer).yarn add
especifica versões em package.json
com ^
? Mais uma vez, entendi que a promessa do yarn era congelar as dependências.Bugs Relacionados
node_modules
, yarn install
indica sucesso sem reinstalá-lo. Quando muitos deles acabam, ele os reinstala. npm
é um pouco mais completo a esse respeito.node_modules
após uma instalação limpa, o yarn o regenera e é geralmente muito diferente da versão anterior. É como um compilador que produz um código diferente a cada vez que você o executa, apesar de não mudar nada.No geral, o yarn torna as instalações mais rápidas, mas parece falhar em sua (in) competência principal: Congelar versões, de forma consistente, por padrão. Não preciso de conveniências que me ajudem a iniciar meu projeto, preciso de ajuda para mantê-lo em uma equipe enorme por muitos anos. Os programadores são inteligentes e intencionais, quando querem uma mudança, eles pedem explicitamente.
O arquivo de bloqueio em constante mudança não inspira confiança e é um incômodo constante. Eu prefiro avisos e erros de que package.json não corresponde ao lockfile, que o lockfile não corresponde a node_modules, que uma versão bloqueada não existe mais, etc., para que minhas compilações parem imediatamente e eu posso tomar decisões intencionais sobre minhas dependências.
@jspiro , obrigado por escrever isso.
Existem algumas questões levantadas aqui.
Seria melhor abrir cada problema separadamente, caso contrário, eles se perderão nos comentários.
Você está usando a versão mais recente do Yarn?
A partir de 0,18-0,19, não vemos modificações nos arquivos yarn.lock entre as máquinas.
Perguntas:
Está sendo dito que, apesar do lockfile ser alterado, o conteúdo de node_modules será sempre idêntico ao de quando foi gerado? Não acredito que seja esse o caso, mas se for, então eu entendo a confusão neste tópico - isso significaria que o fio faz a coisa certa, apesar de parecer que não.
Dev e dependências opcionais podem ser deixadas de fora para o mesmo arquivo de bloqueio.
Mas aqueles que estão bing instalados, exceto para pacotes específicos da plataforma, node_modules deve ter pacotes idênticos em locais idênticos.
Quando o package.json muda, o lockfile é regenerado. Isso não poderia alterar acidentalmente muitas dependências, dependendo do estado dos node_modules desse programador em particular? O fio deve determinar um delta e tentar preservar os bloqueios existentes da melhor maneira possível (se ainda não o fizer).
Esse é um bom pedido de recurso, adoraria ver um PR para isso.
Por que yarn add especifica versões em package.json com um ^? Mais uma vez, entendi que a promessa do yarn era congelar as dependências.
Isso reflete o comportamento do npm.
Você pode fazer yarn add [email protected]
ou yarn add is-array --exact
para a versão exata.
Talvez em algum momento devamos tornar padrão as versões exatas, isso pode ser uma discussão em um RFC.
Quando um pacote aleatório é excluído em node_modules, yarn install diz sucesso sem reinstalá-lo. Quando muitos deles acabam, ele os reinstala. O npm é um pouco mais completo a esse respeito.
O Yarn executa uma verificação superficial rápida por padrão.
Fazer uma verificação mais profunda será mais lento, mas estamos trabalhando nisso. Tenho uma ideia de como poderíamos fazer uma verificação profunda rápida.
Você não deve tocar nos arquivos em node_modules, porém, verificar cada arquivo para modificação resultaria em uma experiência de instalação muito lenta.
Se você quiser pular a verificação superficial, remova o arquivo node_modules/.yarn-integrity
antes da instalação. Isso não é oficial e está sujeito a alterações.
Uma forma oficial é executar yarn install --force
, isso forçaria a instalação completa, mas reescreveria yarn.lock como um efeito colateral.
O lockfile tende a ser regenerado se você deletar node_modules e fazer uma instalação limpa (que é literalmente o oposto do que você esperaria - eu espero que ele instale exatamente o que está no lockfile e não faça absolutamente nada mais)
Faz um tempo que não vejo isso.
Abra um problema e me envie uma cópia se ele puder ser reproduzido.
Se você deletar o lockfile sem tocar em package ou node_modules após uma instalação limpa, o yarn o regenera e é geralmente muito diferente da versão anterior. É como um compilador que produz um código diferente a cada vez que você o executa, apesar de não mudar nada.
Depois de algum tempo, novas versões de dependências transitivas podem ter sido lançadas.
Por causa disso, a estrutura de node_modules pode mudar significativamente por causa da lógica de içamento.
Isso funciona como planejado.
Há um comando import
chegando em https://github.com/yarnpkg/yarn/pull/2580.
Isso permitiria a geração de um arquivo de bloqueio a partir de node_modules existentes.
@jspiro , Yarn é um projeto jovem voltado para a comunidade. Seus RPs para torná-lo um trabalho melhor para você são bem-vindos.
Alguma chance de obter pelo menos uma opção para definir o comportamento padrão desejado?
No momento, estamos corrigindo esse problema https://github.com/yarnpkg/yarn/issues/3490 , às vezes yarn install
pode fazer com que o arquivo de bloqueio seja otimizado, o que não é um comportamento esperado e nós o consertaremos.
Essa pode ser a razão pela qual você está solicitando essa alteração, caso contrário, o arquivo yarn.lock deve ser alterado apenas se você fizer alterações no package.json manualmente.
Você pode definir --pure-lockfile / - frozen-lockfile como true em .yarnrc e será anexado ao comando de instalação por padrão:
--install.pure-lockfile true
Meu problema é que se eu não usar o pure-lockfile, obtenho a versão errada das dependências instaladas. Não está relacionado às alterações indesejadas do yarn.lock
Você pode enviar um problema com as etapas de reprodução?
Vamos resolver isso
Também fui mordido por isso quando package.json
e yarn.lock
saíram de sincronia devido a um desenvolvedor adicionar por engano uma dependência por meio de npm install --save
vez de yarn add
.
Eu discordo que pure-lockfile
deve ser o padrão e argumento que frozen-lockfile
deve ser o padrão para yarn install
.
Como frozen-lockfile
gerará uma mensagem de erro se yarn.lock
e package.json
estiverem fora de sincronia. O frozen-lockfile
é, portanto, muito útil em uma máquina de construção (por exemplo, jenkins), pois marcará essas construções, como seria de se esperar, como uma falha.
Cabe então ao desenvolvedor decidir qual versão adicionar no package.json / yarn.lock.
O infeliz padrão de yarn install
irá apenas buscar a versão mais atual das dependências ainda não bloqueadas e escrever uma versão atualizada yarn.lock
, que nunca fará parte do projeto. Portanto, permitindo quebras futuras da construção devido a um aumento inesperado da versão. Essa é a razão pela qual temos um arquivo de bloqueio para começar.
A essência deve ser:
Apenas comandos como add
, remove
e upgrade
devem transformar yarn.lock
.
install
deve apenas fazer isso, ou seja, instalar as dependências em sua versão bloqueada ou falhar se detectar uma incompatibilidade entre package.json
e yarn.lock
. (A única exceção é se não houver yarn.lock
em primeiro lugar. Então, e somente então, ele pode criar um, mas nunca, nunca deve tocá-lo novamente.)
O arquivo frozen-lock é, portanto, muito útil na máquina de construção (ou seja, jenkins), pois essas construções irão falhar.
Acho que podemos habilitar isso automaticamente quando detectarmos que estamos no modo CI?
@BYK Não sabia que este problema estava
Eu diria para abrir um novo ☺️
Eu concordo com @thejameskyle e @kittens que yarn.lock deve ser mantido em sincronia com o package.json automaticamente
Não tenho certeza se isso foi dito, mas apenas no caso: você não precisa invalidar todo o yarn.lock quando algo em package.json mudar. Você pode invalidar apenas as dependências de pacotes que foram modificados dentro de package.json. Por exemplo, se você atualizou apenas o TypeScript, as dependências do TypeScript precisariam ser modificadas (com considerações a respeito de outros pacotes inalterados).
Comentários muito úteis
Há um monte de coisas diferentes acontecendo aqui que eu queria tentar desvendar (sem trocadilhos).
Primeiro, as pessoas levantaram uma série de requisitos diferentes que considero incontroversos (e que tornam alguns dos comportamentos existentes bugs, dos quais falarei em breve).
Do relatório de bug original.
Para ser mais preciso, a semântica esperada, na minha opinião, é:
package.json
não mudou desde a última vez queyarn.lock
mudou,yarn.lock
é a fonte da verdade e não deve ser atualizado.package.json
mudou desde a última vez,yarn.lock
mudou, atualizeyarn.lock
para que satisfaçapackage.json
e atualizenode_modules
.yarn update
for executado, resolva novamente todas as dependências e obtenha a versão mais recente de tudo que satisfaça opackage.json
.Isso significa que quando um repositório é clonado pela primeira vez em uma máquina , se o
yarn.lock
foi verificado, o yarn deve sempre tratá-lo como a fonte da verdade, não gerar atualizações parayarn.lock
e pular diretamente para a etapa de busca.Na medida em que esse não é o comportamento atual do fio, acredito que seria um bug.
@esphen escreveu:
Acho que o que isso quer dizer é que o yarn não deve escrever um novo arquivo de bloqueio se o existente ainda estiver atualizado. Eu concordo com isso.
O principal problema aqui é se uma mudança em
package.json
deve fazer com queyarn.lock
seja atualizado. Na minha opinião, se a mudança parapackage.json
não for satisfeita peloyarn.lock
, ele deve atualizar oyarn.lock
.Uma invariante importante dos sistemas lockfile como o yarn é que, usando o fluxo de trabalho normal, os desenvolvedores podem ter certeza de que os pacotes que realmente são usados quando executam seus aplicativos correspondem às versões especificadas em seus
package.json
. Sepackage.json
ficar fora de sincronia comyarn.lock
, isso não será verdade, e a única maneira de saber isso será para leitores humanos lerem cuidadosamenteyarn.lock
.A melhor maneira para a maioria dos usuários pensar sobre o arquivo de bloqueio é que ele é um artefato do fio em execução que representa as versões precisas de todos os pacotes que foram usados para os
package.json
atuais. Ao fazer o check-in, outros colaboradores, CI e código de produção têm a garantia de usar essas mesmas versões.@Guuz disse:
Esta pergunta ecoa um sentimento que algumas pessoas fizeram neste tópico.
A carga tem uma bandeira
--locked
que diz "sepackage.json
não for satisfeito comyarn.lock
, é um erro grave". Bundler tem um sinalizador semelhante (--frozen
), que foi adicionado quando o Heroku adotou o Bundler, para dar às pessoas um erro grave caso fizessem alterações locais em seusGemfile
e se esquecessem de fazer o check-in deGemfile.lock
.A ideia é que durante o seu desenvolvimento normal, você gostaria de ser capaz de fazer alterações em
package.json
e fazer com que oyarn.lock
ficasse em sincronia (novamente, para garantir que as versões especificadas empackage.json
sempre coincidir com o que é usado na prática).Mas, durante a implantação, é quase sempre um erro ter divergido, porque significa que você fez uma alteração em
package.json
, executou um comandoyarn
e se esqueceu de fazer o check-inyarn.lock
. Isso significa que as versões em seupackage.json
não correspondem às versões reais usadas quando o aplicativo é executado , o que dizemos que viola uma invariante fundamental do yarn.@esphen disse:
Acho isso incontroverso.
Executar
yarn install --pure-lockfile
significará que o arquivo de bloqueio será respeitado mesmo se as versões dentro do arquivo de bloqueio entrarem em conflito com as versões especificadas empackage.json
. Isso só deve ocorrer se um desenvolvedor esquecer de fazer o check-in de seuyarn.lock
após fazer alterações empackage.json
.Se
package.json
não mudou, na minha opinião é um bug seyarn.lock
está sendo atualizado. Pelo menos um caso de bug parece estar no relatório original:Acho que isso é um erro e deve ser corrigido.
Mais tarde no tópico, @thejameskyle disse:
Esse é exatamente o modelo mental correto, na minha opinião ("
yarn.lock
pode mudar se e somente sepackage.json
mudar"), e se a abstração vazar, devemos consertar.@adamchainz disse:
e depois:
O problema aqui é que o yarn não trata o git sha como parte da versão bloqueada das dependências do git. Cargo e Bundler têm o conceito de uma versão "precisa" que é serializada no arquivo de bloqueio; para fontes git, a versão "precisa" é o SHA. Então, quando você faz um novo clone com apenas
package.json
eyarn.lock
e executayarn
, todas as informações necessárias para obter precisamente o código de que você precisa estão lá.Devo confessar que perdi essa interação ao revisar o código git original; há algum rastreamento SHA no código, mas
yarn install
não garante que o gráfico de dependência hidratada o respeite.TL; DR
Concordo com @thejameskyle e @kittens que
yarn.lock
deve ser mantido em sincronia compackage.json
automaticamente, porque acredito que os usuários devem ser capazes de assumir que as versões especificadas em seuspackage.json
alinhar com o que é usado quando seu aplicativo é executado.No entanto, parece haver alguns bugs que estão causando rotatividade inadequada no
yarn.lock
mesmo quando opackage.json
não mudou:package.json
não tenha sido atualizado, o que então atualiza o arquivo de bloqueioDevemos também considerar algo como a bandeira
--locked
da Cargo, que você pode usar em CI para falhar rapidamente a compilação se um desenvolvedor atualizar opackage.json
e esquecer de verificar oyarn.lock
atualizado