Para alinhar uma dependência entre pacotes npm em um Mac, primeiro compare os intervalos de versões no package.json de cada workspace, decida qual intervalo de versão comum atende a todos os pacotes, atualize cada workspace afetado e regenere o lockfile raiz. Os workspaces do npm podem direcionar pacotes a partir da raiz do repositório, mas não fornecem um comando integrado que analise todos os manifestos e torne as versões das dependências idênticas de forma automática.

1. Verifique se o repositório usa npm workspaces

No Terminal, acesse a raiz do repositório e inspecione sua configuração:

cd "/path/to/your/repository"
npm --version
npm pkg get workspaces

O package.json raiz deve definir os caminhos dos workspaces, e cada pacote deve ter seu próprio package.json. O recurso de workspaces do npm vincula esses pacotes locais durante a instalação e permite que comandos tenham como alvo um ou mais workspaces por nome ou caminho. Se npm pkg get workspaces não retornar nada, confirme o gerenciador de pacotes e a estrutura do repositório antes de usar os comandos de workspace do npm. npm Workspaces

2. Compare as declarações de dependências

Pesquise nos manifestos rastreados pela dependência que você deseja alinhar. Por exemplo, no Terminal do macOS você pode usar o grep sem instalar nenhuma ferramenta adicional:

grep -n '"typescript"' package.json packages/*/package.json

Substitua typescript pelo nome da dependência. Esta é uma verificação rápida de texto, portanto, revise as seções correspondentes em cada manifesto para ver se o pacote está em dependencies, devDependencies, peerDependencies ou optionalDependencies. Esses campos descrevem funções diferentes; não mova uma dependência entre eles apenas para fazer as strings de versão coincidirem. Para um inventário mais completo, inspecione o manifesto de cada workspace em seu editor ou use o comando de listagem do npm que reconhece workspaces:

npm ls typescript --workspaces --depth=0

Os intervalos do manifesto e a árvore instalada respondem a perguntas diferentes: o primeiro mostra o que cada pacote permite, enquanto o npm ls relata o estado das dependências instaladas. O lockfile do npm registra as versões resolvidas, mas não substitui os intervalos aceitáveis declarados em cada package.json. npm ls package-lock.json and npm install

3. Escolha uma política de versão compatível

Escolha uma versão que atenda aos requisitos dos consumidores e à política de suporte do repositório. Um intervalo de versão compartilhado significa que os pacotes expressam o mesmo conjunto permitido; isso não garante que todas as cópias aninhadas ou transitivas sejam resolvidas para uma única cópia instalada. Verifique os requisitos de dependências de pares (peer dependencies) e as notas de versão em busca de alterações que quebrem a compatibilidade (breaking changes) antes de migrar pacotes entre versões principais (major). Se os consumidores precisarem de um intervalo de compatibilidade mais amplo, alinhar para a mesma string exata pode ser inadequado; em vez disso, estabeleça uma política de intervalo equivalente.

Por exemplo, para definir uma ferramenta de desenvolvimento para a mesma versão exata em dois workspaces chamados web e api, execute isto a partir da raiz:

npm install --save-dev --save-exact typescript@5.8.3 --workspace=web --workspace=api

Use a versão que seu projeto selecionou; 5.8.3 aqui é apenas um exemplo. O comando de instalação do npm aceita seletores de workspace e salva o pacote no manifesto de cada pacote selecionado. --save-exact grava uma versão exata em vez do operador de intervalo habitual do npm. Para uma dependência de tempo de execução, use a categoria de salvamento apropriada, como --save-prod, em vez de --save-dev. npm install

Repita com seletores de workspace adicionais ou execute o comando para cada workspace. Não presuma que uma instalação no nível raiz atualize o manifesto de todos os pacotes: direcione explicitamente os pacotes cujas declarações devem ser alteradas. O pacote raiz também pode ser incluído deliberadamente com --include-workspace-root quando ele deve declarar a mesma dependência.

4. Reinstale, inspecione a diferença (diff) e verifique

Após atualizar as declarações, execute a instalação na raiz do repositório para que o npm reconcilie a árvore de workspaces e o lockfile:

npm install
npm ls typescript --workspaces --depth=0
git diff -- package.json package-lock.json packages/*/package.json

Verifique se cada manifesto pretendido possui a declaração combinada e se a alteração no lockfile é a esperada. Execute os scripts relevantes de build ou teste do repositório; o npm ls por si só não garante que o código funcione com a versão selecionada. Faça o commit do package-lock.json raiz quando o projeto o rastrear, para que as instalações da equipe possam reproduzir a árvore resolvida. npm package-lock documentation

Se o npm relatar uma dependência inválida ou um conflito de peer, inspecione o pacote nomeado no erro em vez de forçar a instalação. Um workspace pode exigir um intervalo compatível diferente, ou outra dependência pode impor um requisito de peer que necessite de um plano de atualização planejado.

Quando o npm dedupe ajuda

O npm dedupe pode simplificar a árvore de dependências instalada movendo dependências compatíveis para níveis mais altos, permitindo que os pacotes as compartilhem. Ele não reescreve os intervalos de dependências diretas no package.json, portanto, não pode alinhar declarações por conta própria. Use-o apenas após verificar se os intervalos são compatíveis e, em seguida, revise o diff resultante no lockfile. npm dedupe

A conclusão confiável é uma política deliberada expressa no manifesto de cada workspace relevante, um lockfile regenerado e a verificação dos pacotes afetados. Isso oferece aos mantenedores um registro claro do que foi alinhado e deixa restrições incompatíveis visíveis para uma decisão separada.

Fontes