Yarn: Como atualizar dependências indiretas?

Criado em 23 nov. 2017  ·  45Comentários  ·  Fonte: yarnpkg/yarn

Deseja solicitar um recurso ou relatar um bug ?

Funcionalidade.

Qual é o comportamento atual?
yarn upgrade ignora dependências indiretas, então os usuários não podem atualizá-las em yarn.lock. Se eu perdi alguma coisa, por favor me diga.

Se o comportamento atual for um bug, forneça as etapas para reproduzir.

  • Suponha um novo projeto vazio, execute yarn add [email protected]

    • 2 dependências indiretas, is-alphabetical e is-decimal , serão instaladas e salvas em yarn.lock

    • a versão mais recente de is-alphabetical é 1.0.1 agora, se outra nova versão, digamos 1.0.2 foi lançada (para testar, você pode liberar 2 pacotes de teste sozinho ou modificar is-alphabetical para ser 1.0 .0 em yarn.lock , * Eu sei que modificar yarn.lock diretamente não é uma operação normal *)

  • Não importa qual das seguintes maneiras, yarn sempre diz All of your dependencies are up to date

    • a atualização do fio é alfabética

    • wire upgrade-interativo

    • yarn upgrade-interactive é alfabético

Qual é o comportamento esperado?
yarn upgrade também suporta dependências indiretas.

Mencione seu node.js, yarn e versão do sistema operacional.
Nó 8.9.0
fio 1.3.2
OSX 10.12.6

cat-feature

Comentários muito úteis

+1 para esta solicitação de recurso. Também um exemplo para qualquer pessoa burra como eu que precise atualizar manualmente uma dependência indireta específica nesse ínterim:

Dada a dependência explícita jsonwebtoken resolveu a dependência implícita jws^3.0.0 para o vulnerável jws=3.1.4 : e você precisa resolver para 3.1.5 :

Exclua a entrada jws por exemplo, abaixo de yarn.lock e execute novamente yarn . A dependência indireta e quaisquer pacotes afetados serão atualizados, sem tocar em outras coisas (pelo menos no fio v1.3)

jws@^3.0.0, jws@^3.1.4:
  version "3.1.4"
  resolved "https://registry.npmjs.org/jws/-/jws-3.1.4.tgz#f9e8b9338e8a847277d6444b1464f61880e050a2"
  dependencies:
    base64url "^2.0.0"
    jwa "^1.1.4"
    safe-buffer "^5.0.1"

Editar: pontuação

Todos 45 comentários

@chinesedfan Você já experimentou yarn upgrade-interactive ?

@milesj Sim, resulta no mesmo resultado e também atualizei as etapas de reprodução na descrição do problema.

Isso ocorre porque yarn add [email protected] configura seu package.json para _exactly_ versão 1.0.0 conforme você solicitou.

yarn upgrade respeita o intervalo semver do seu package.json e, como você especificou exatamente a versão 1.0.0, ele não oferecerá a atualização para outras versões.

Você pode resolver isso de duas maneiras:

  • yarn upgrade --latest irá ignorar o intervalo semver e ver o que está marcado como latest no registro.
  • altere package.json para aceitar um intervalo de versão como ^1.0.0 e depois yarn upgrade (talvez seja necessário yarn install primeiro para que ele atualize o arquivo de bloqueio para o intervalo alterado)
  • especifique explicitamente uma versão para upgrade , como yarn upgrade [email protected] ou yarn upgrade is-alphanumerical@^1.0.0

Editar:

Desculpe, acabei de notar que há nomes de pacotes diferentes. alphanumerical e alphabetical parecem iguais de relance :)

Certo, como não há atualização para is-alphanumerical , a árvore de dependências não é percorrida mais profundamente para lidar com suas dependências transitivas.

Você pode tentar adicionar o sinalizador --force e ver se isso o torna as subdependências. Caso contrário, acho que você está certo, não há uma maneira fácil de fazer isso além de yarn remove is-alphanumerical e yarn add is-alphanumerical

@rally25rs Obrigado pela sua resposta! Testei mais 2 casos.

  • yarn upgrade is-alphabetical --force também não funciona.
  • yarn upgrade is-alphanumerical atualizará TODAS as suas subdependências, mesmo que já seja a mais recente.

    • Mas se eu quiser apenas atualizar uma subdependência especificada, isso ainda não é muito conveniente.

sim, este é um grande problema com fios no momento. e já está em discussão em #2394

duplicata #2394

Por favor, reabra: não é duplicado.

2394 descreve a duplicação do pacote meck-test-bb (dependência indireta):

Eu tenho duas cópias do meck-test-bb

Este problema descreve apenas a capacidade de atualizar a dependência indireta (de alguma forma).

@rally25rs Perdoe-me pelo ping.

@rally25rs , por favor, você fechou os dois problemas não duplicados, está errado. Dê-nos a capacidade de atualizar dependências indiretas, por favor!

Desculpe, houve alguma confusão sobre a outra questão. Eu originalmente pensei que 2394 estava pedindo uma maneira de atualizar um dep transitivo usando um sinalizador --deep , ou algo assim, então marquei esse problema como uma duplicata disso. Mais tarde, depois de reler 2394, acho que era sobre algo diferente, que não é uma duplicata disso como eu pensava originalmente.

+1 para esta solicitação de recurso. Também um exemplo para qualquer pessoa burra como eu que precise atualizar manualmente uma dependência indireta específica nesse ínterim:

Dada a dependência explícita jsonwebtoken resolveu a dependência implícita jws^3.0.0 para o vulnerável jws=3.1.4 : e você precisa resolver para 3.1.5 :

Exclua a entrada jws por exemplo, abaixo de yarn.lock e execute novamente yarn . A dependência indireta e quaisquer pacotes afetados serão atualizados, sem tocar em outras coisas (pelo menos no fio v1.3)

jws@^3.0.0, jws@^3.1.4:
  version "3.1.4"
  resolved "https://registry.npmjs.org/jws/-/jws-3.1.4.tgz#f9e8b9338e8a847277d6444b1464f61880e050a2"
  dependencies:
    base64url "^2.0.0"
    jwa "^1.1.4"
    safe-buffer "^5.0.1"

Editar: pontuação

@alex-thewsey-ibm, obrigado pela solução alternativa!

Trabalhou no fio v1.7.

ty, fio trabalhado 1.9.2

Pode ajudar a estimular o fio com dependência seletiva resolutions , mesmo que seja para uma única dependência. Obrigado a @remoleoend pela dica!
https://yarnpkg.com/lang/en/docs/selective-version-resolutions/

Dos documentos:

{
  "name": "project",
  "version": "1.0.0",
  "dependencies": {
    "left-pad": "1.0.0",
    "c": "file:../c-1",
    "d2": "file:../d2-1"
  },
  "resolutions": {
    "d2/left-pad": "1.1.1",
    "c/**/left-pad": "1.1.2"
  }
}

Precisamos desse recurso no Autoprefixer para sugerir aos usuários como atualizar caniuse-lite em seu yarn.lock https://github.com/postcss/autoprefixer/issues/1184

Mesmo problema aqui. Eu esperava yarn upgrade caniuse-lite browserslist para atualizar a subdependência. Ele não fez isso, nem me deu uma mensagem de erro dizendo que não pode atualizá-lo porque não é uma dependência.

Excluir as entradas relevantes do arquivo de bloqueio e, em seguida, executar novamente yarn como @alex-thewsey-ibm sugeriu corrigiu o problema imediato para mim.

É estranho para mim que o fio está faltando o recurso tnis. Eu sou novo no fio (e no npm), então assumi que deve haver uma maneira de fazer isso. Ainda não tenho certeza se existe uma maneira não óbvia de fazer isso que ninguém neste tópico conhece, ou se realmente não há como fazer isso.

Se realmente não há como atualizar uma dependência transitiva/indireta no arquivo de bloqueio sem adicioná-lo ao package.json... Não entendo como os usuários do yarn fazem sem ele.

Este é um comportamento inesperado IMO - tentei atualizar o lodash recentemente com yarn upgrade [email protected] e ainda não foi atualizado para nenhuma dependência transitória.

Eu ainda fiquei com todas as versões major (^4.XX) e patch (~4.17.X) apontando para a versão antiga.

A única maneira de corrigi-lo é através da edição manual de yarn.lock e, em seguida, talvez executando yarn upgrade para consolidar as alterações. Eu esperaria um pouco melhor de uma ferramenta tão amplamente utilizada.

Este bug ou fio reconhecido é conservador por padrão e espera-se que eu edite manualmente yarn.lock ou use algum sinalizador?

Suspeito que tenho o mesmo alerta de segurança para resolver que @Machiaweliczny ;) Seria muito útil substituir a dependência indireta enquanto esperamos que os projetos corrijam seus próprios. Mesmo com projetos altamente responsivos, há um atraso à espera de correções e lançamentos.

De fato, isso é problemático para problemas de segurança em dependências indiretas, e a solução alternativa de editar yarn.lock , embora eficaz, é decepcionante e difícil de automatizar. Se esse não for o comportamento padrão por algum motivo, seria ótimo adicionar uma opção como --include-indirect que forçará o Yarn a seguir as dependências indiretas.

Eu não acho que deva precisar de uma opção, não vejo por que yarn upgrade [an indirect dependency] não apenas atualiza o yarn.lock para a versão mais recente da dependência indireta que é permitida pela árvore de dependências, sem qualquer necessidade de opções adicionais. Eu acho que agora é apenas um no-op?

No entanto, outra solução com a qual estou feliz é adicionar resolutions ao meu package.json. Se lodash for uma dependência indireta e eu sei que preciso que seja >= 4.7.13 para evitar uma vulnerabilidade de segurança, posso adicionar ao meu package.json:

  "resolutions": {
    "lodash": ">= 4.17.13"
  }

Em seguida, basta executar yarn install , ele atualizará o yarn.lock para atender a esse requisito, ou reclamará se não puder porque está em conflito com uma dependência indireta.

Isso realmente parece ter funcionado muito bem no meu caso; Gostaria de saber se não é uma "solução alternativa", mas a solução pretendida? Mas demorei um pouco para descobrir. E eu não entendo as coisas bem o suficiente para ter certeza de que esta é uma solução universal/correta ou se pode haver algum problema em alguns casos com ela. Se for a solução 'certa' para atualizar dependências indiretas, foi um pouco difícil de encontrar.

Por que não o yarn instala o dep transitivo que você deseja atualizar, mas não confirma as alterações do package.json, apenas o yarn.lock?

Por que não o yarn instala o dep transitivo que você deseja atualizar, mas não confirma as alterações do package.json, apenas o yarn.lock?

Eu não acho que isso (sempre?) funcionará, porque o fio instalará alegremente várias versões do mesmo pacote, mesmo que uma única versão satisfaça todos os intervalos de semver relevantes. Portanto, isso instalaria a versão desejada, mas não removeria a versão que você não deseja.

@djmitche Certo. Você precisaria instalar a versão dentro do intervalo esperado. Não é o ideal e um pouco tedioso, mas um paliativo disponível por enquanto.

@djmitche De fato, isso é problemático para problemas de segurança em dependências indiretas, e a solução alternativa de editar yarn.lock , embora eficaz, é decepcionante e difícil de automatizar.

Esta é outra solução que é um pouco mais automatizável:

yarn remove is-alphanumerical
yarn add is-alphanumerical

Usando o exemplo na descrição do PR, isso removeria o dep de nível superior e o adicionaria novamente, o que obterá todos os seus subdeps mais recentes, de acordo com os intervalos especificados por is-alphanumerical (intervalos de acento circunflexo, por exemplo) . Em seguida, ele produzirá um novo arquivo de bloqueio.

O efeito colateral é que ele atualizará todos os subdeps, o que não é o ideal. Para um problema de segurança no subdep A, gostaria de atualizar apenas o subdep A.

A solução alternativa de adicionar o subdep A como um dep direto apenas para corrigir um problema de segurança é pior porque cria confusão (o pacote não é usado diretamente), bem como uma carga de manutenção.

remoção de fios é alfanumérico
fio adicionar é alfanumérico

Esta parece ser a única maneira confiável de realmente atualizar uma dependência. Percebi hoje que estávamos presos em uma versão 1.0.0 de um pacote que havia sido atualizado para 1.1.0 um ano atrás. O pacote que estávamos usando usava ^1.0.0 e todas as vezes que "atualizamos" esse pacote ele nunca pegou a nova versão 1.1.0 de sua dependência.
Acontece que havia um bug muito ruim que estava falhando silenciosamente em nosso produto que deveria ter sido corrigido há um ano sem que eu perdesse um dia investigando por que estávamos tendo esse problema.

Eu não posso acreditar que editar o yarn.lock manualmente, remover e re-adicionar o pacote ou usar a resolução seletiva são as "maneiras" de atualizar uma dependência indireta.

IMO, yarn upgrade deve atualizar as dependências indiretas para a versão semver mais recente aceita, é por isso que atualizamos um pacote. Quer dizer, se houver uma quebra no intervalo semver, ele atualizará as dependências indiretas, então deve fazê-lo sempre.

Ajudaria escrever algum tipo de script externo para fazer isso? Suponho que apenas removeria todas as entradas yarn.lock para o pacote fornecido e, em seguida, executaria novamente o yarn?

Existe um script simples para fazer isso: https://gist.github.com/pftg/fa8fe4ca2bb4638fbd19324376487f42

Um dos mantenedores pode alterar o rótulo de cat-feature para cat-bug ?

Um dos mantenedores pode mudar o rótulo de cat-feature para cat-bug?

porque? isso não é um bug. É como projetado. yarn upgrade nunca foi planejado para ser usado para atualizar uma dependência transitiva. O "problema" originalmente aberto é ainda rotulado como uma solicitação de recurso.

Internamente upgrade usa yarn outdated para determinar o que está desatualizado e para quais versões atualizar. outdated verifica apenas dependências diretas.

Posso estar errado, ou talvez tenha mudado, mas tenho certeza de que npm upgrade pelo menos 3 anos atrás, quando yarn upgrade foi retrabalhado pela última vez, também não fornece uma maneira de atualizar um dep transitivo. (novamente, isso pode ter mudado, pois ao longo dos anos, não estou muito atualizado sobre as alterações do npm).


Qualquer pessoa é livre para enviar um PR para adicionar essa funcionalidade. Este é um projeto de código aberto e cabe à comunidade em geral contribuir. Essa solicitação de recurso está aberta há anos, mas ninguém se esforçou para implementá-la e é por isso que ela não foi "consertada".

@nnmrts você poderia verificar meu script https://github.com/yarnpkg/yarn/issues/4986#issuecomment -562719589 isso ajudará você por enquanto?

@rally25rs Desculpe, eu estava cansado e mal-humorado, considere meu comentário como resolvido. 😬

@nnmrts você poderia verificar meu script # 4986 (comentário) isso ajudará você por enquanto?

Esse script infelizmente não funcionou para mim, tentei ontem. Talvez eu tenha feito algo errado, mas todo o meu arquivo yarn.lock foi "esvaziado" pelo script.

Não tenho certeza de quão boa é uma solução alternativa, mas executei este script que escrevi:

const fs = require('fs')
const lockfile = require('@yarnpkg/lockfile')
const package = require('./package.json')

const lock = lockfile.parse(fs.readFileSync('yarn.lock', 'utf-8')).object

const allDeps = new Set()

const parseDep = ([name, version]) => {
  allDeps.add(`${name}@${version}`)
}

Object.entries(package.dependencies).forEach(parseDep)
Object.entries(package.devDependencies).forEach(parseDep)

const newLock = Object.fromEntries(Object.entries(lock).filter(([dep]) => allDeps.has(dep)))
const newLockString = lockfile.stringify(newLock)

fs.writeFileSync('yarn.lock', newLockString)

Em seguida, executei yarn install e parece instalar as versões mais recentes de dependências indiretas.

Consegui resolver dependências profundas/indiretas com sucesso. Eu me pergunto quando teremos um apoio oficial.

https://medium.com/@ayushya/upgrading -javascript-packages-deep-dependencies-using-yarn-8b5983d5fb6b

Tentei resolver e expliquei os riscos de gerar novamente o yarn.lock e sugeri o que deveria ser feito.

Deixe-me saber se isso funciona para vocês também. Ou qualquer sugestão para melhorar o processo de atualização.

@ayushya Hm, isso parece funcionar, gênio.

Gostaria de saber se yarn aceitaria um patch em que yarn upgrade para uma dependência indireta (ou algum outro comando?) apenas... fez isso?

@jrochkind Eu esperaria um yarn upgrade de uma dependência indireta para atualizá-lo, mesmo que não seja minha dependência direta. Sem esse recurso, você pode estar anos atrasado nas atualizações de dependências indiretas.

No meu caso, eu estava tentando atualizar fsevents , para que não vomitasse erros quando eu fizesse um yarn install (https://github.com/fsevents/fsevents/issues/278 ). fsevents não é um pacote que eu uso diretamente -- é algo que webpack-dev-server usa. Mas, surpreendentemente, eu estava preso a qualquer versão que existisse quando webpack-dev-server foi instalado pela primeira vez neste aplicativo.

Eu tive que usar esse truque para atualizá-lo, o que parecia um hack total. https://github.com/yarnpkg/yarn/issues/4986#issuecomment -395036563

a solução alternativa não está funcionando para mim, infelizmente, as antigas dependências profundas foram adicionadas novamente ao arquivo yarn.lock após excluí-las. Eu posso vê-los de volta na pasta node_modules e no arquivo yarn.lock depois de executar o yarn install.

talvez a solução alternativa não seja compatível com os espaços de trabalho do yarn?

@FelipeLujan quando a solução alternativa funciona, as dependências profundas ainda são adicionadas novamente ao arquivo yarn.lock - o que é esperado - mas com novas versões posteriores. Mas apenas com novas versões se houver novas versões lançadas e se elas forem permitidas pela árvore de dependências. Se alguma dependência intermediária expressar uma restrição que não permite uma atualização, ela ainda não poderá ser atualizada. Eles são apenas atualizados para o último permitido pelas restrições na árvore.

eu não uso espaços de trabalho de fios, portanto, não posso dizer se isso é relevante.

@FelipeLujan Os espaços de trabalho de fios AFAIK funcionam de maneira semelhante.

A solução alternativa para excluir a seção do pacote atualizará apenas o pacote para a versão MINOR/PATCH mais recente.
Se você deseja atualizar o pacote para uma versão MAJOR mais recente, você precisa encontrar a cadeia de dependências do pacote executando yarn why package-name-here e atualizar o pacote no topo de sua cadeia.

CUIDADO: Teste seu código, pois atualizar os pacotes para uma versão MAJOR mais recente pode trazer algumas mudanças importantes.

https://github.com/djmitche/yarn-minify pode ajudar com isso ..

A solução alternativa do @ayushya está funcionando muito bem para mim, editando manualmente o yarn.lock para remover uma dependência indireta e, em seguida, executando o yarn install para adicioná-lo novamente em uma versão posterior.

Para mim, isso parece um recurso que deve ser incorporado ao yarn, em vez de exigir que você edite o yarn.lock manualmente. Parece que deve ser bastante simples criar um recurso que é como se você tivesse editado manualmente para excluir a dependência e executar o yarn install. Eu sinto que esse recurso realmente deveria ser incorporado ao fio e estou meio confuso sobre o motivo pelo qual não é.

Consegui resolver dependências profundas/indiretas com sucesso. Eu me pergunto quando teremos um apoio oficial.

https://medium.com/@ayushya/upgrading -javascript-packages-deep-dependencies-using-yarn-8b5983d5fb6b

Tentei resolver e expliquei os riscos de gerar novamente o yarn.lock e sugeri o que deveria ser feito.

Deixe-me saber se isso funciona para vocês também. Ou qualquer sugestão para melhorar o processo de atualização.

Acho que é a mesma resolução dada por @alex-thewsey-ibm. A exclusão dessa dependência específica do yarn.lock me ajudou.
De qualquer forma, obrigado por este hack☺️

Usar resolutions em package.json funcionou para mim https://github.com/webpack/webpack-dev-server/issues/2739#issuecomment -695164486

Isso deve pelo menos retornar algum aviso:

yarn add [email protected]
yarn upgrade is-alphabetical

Isto é o que eu recebo em vez disso:

success Saved lockfile.
success Saved 0 new dependencies.

Não há alterações em package.json e yarn.lock , embora haja uma nova versão do pacote is-alphabetical disponível.

Esta página foi útil?
0 / 5 - 0 avaliações