Atualize dependências transitivas com PNPM: Corrija as vulnerabilidades de segurança sem quebrar nada
Corrigir vulnerabilidades de segurança pode ser uma tarefa frustrante, especialmente quando envolve dependências transitivas. Aprenda como atualizá-las sem afetar suas dependências diretas.
Atualmente, vulnerabilidades de segurança são um problema comum no desenvolvimento de software. Felizmente, temos ferramentas como GitHub Dependabot para nos ajudar a manter nossas dependências atualizadas com detecção automática e pull requests.

No entanto, nem sempre funciona como esperado. Como algumas dependências são transitivas, atualizá-las pode ser uma tarefa difícil para essas ferramentas, pois elas não sabem o impacto das mudanças e o que decidir fazer em caso de conflitos. Precisamos lidar com esses casos manualmente.
Métodos que não funcionam
- Comandos oficiais como
pnpm upirão bagunçar seu arquivopnpm-lock.yaml. Há um problema sobre isso que ainda está aberto no momento em que este artigo foi escrito. - Instalar a versão mais recente da dependência direta que possui a dependência transitiva desejada pode não funcionar. Se a dependência direta não atualizou as definições de versão, a dependência transitiva não será atualizada, pois já foi resolvida e travada no arquivo
pnpm-lock.yaml.
A solução
O campo overrides é um recurso poderoso no PNPM que permite substituir algumas resoluções de versão. Vamos usar esse recurso para atualizar dependências transitivas e fazer a mudança da forma mais mínima possível.
Vamos usar o alerta do Dependabot mencionado acima como exemplo. Ele nos informa que o pacote follow-redirects tem uma vulnerabilidade de segurança, e a versão corrigida é 1.15.6. No entanto, a dependência direta gatsby usa axios, que depende de [email protected].
Passo 1: Encontrar a dependência transitiva
Existem muitas maneiras de localizar a dependência transitiva, mas eu recomendaria a maneira mais direta: pesquisar no arquivo pnpm-lock.yaml.
E quanto ao "pnpm why"?
O comando pnpm why <package> é realmente útil. No entanto, ele pode confundir você nesse caso. Por exemplo, quando eu executo pnpm why follow-redirects, aqui está uma parte da saída:
Na verdade, há apenas uma resolução para follow-redirects no arquivo pnpm-lock.yaml. O comando pnpm why pode mostrar vários caminhos que dependem da mesma versão do pacote.
Passo 2: Adicione os overrides
O caso mais fácil é quando existe apenas uma resolução no arquivo pnpm-lock.yaml. Você pode adicionar a substituição diretamente ao arquivo package.json:
Se você estiver em um workspace, deve adicionar o override ao arquivo package.json da raiz do workspace.
Passo 3: Aplique as mudanças
Execute pnpm install para aplicar as mudanças. Podemos ver que o pacote follow-redirects foi atualizado para 1.15.6 no arquivo pnpm-lock.yaml com mudanças mínimas.
Agora você pode remover o campo overrides do arquivo package.json para mantê-lo limpo. Em seguida, execute pnpm install novamente para validar se as mudanças podem ser aplicadas sem o campo overrides.
Solução de problemas
Os passos acima são o caso ideal. As coisas nem sempre acontecem como o esperado. Aqui estão algumas dicas para a solução de problemas:
A versão é revertida após remover o campo "overrides"
Isso pode acontecer quando o pacote dependente tem uma versão fixa ou um intervalo que não inclui a versão desejada. Verifique o arquivo package.json do pacote dependente, neste caso, axios, para ver se isso se aplica.
Se for o caso, você precisará manter o campo overrides no arquivo package.json até que o pacote dependente atualize as definições de versão.
Existem múltiplas resoluções para a dependência transitiva
À medida que o projeto cresce, o arquivo pnpm-lock.yaml pode inflar com várias resoluções para o mesmo pacote. Por exemplo, pode haver duas versões principais do mesmo pacote foo:
O relatório de vulnerabilidade mostra que [email protected] tem um problema de segurança que é corrigido na 1.0.1, e [email protected] não é afetado. Não podemos simplesmente adicionar um override ao foo:
- Se adicionarmos um override
"foo": "^1.0.1", o[email protected]será rebaixado para1.0.1. Isso pode quebrar o projeto, pois o[email protected]pode ter alguns novos recursos que são usados nos pacotes dependentes. - Se adicionarmos um override
"foo": "^2.0.0", o[email protected]será atualizado para2.0.0. Isso pode quebrar o projeto, pois o[email protected]pode ter algumas mudanças que causam quebra de compatibilidade.
Assumindo que foo segue a Versionamento Semântico, podemos adicionar um override assim:
Isso apenas atualizará o [email protected] para 1.0.1 e manterá o [email protected] inalterado.
Conclusão
Até que o PNPM suporte a atualização direta de dependências transitivas, o campo overrides é uma boa solução alternativa para corrigir vulnerabilidades de segurança sem quebrar nada. Espero que este artigo ajude você a lidar com esses casos de maneira mais eficiente. No Logto, usamos esse método para manter nossas dependências atualizadas e seguras.

