Anúncios incomodam? Ir Sem anúncios Hoje

Versão Semântica O Sistema de Numeração que seu npm install depende

Atualizado em

Os três números do Semver são um contrato. MAJOR quebra, MINOR adiciona e PATCH corrige — e quando sua build quebra após npm install, em dez de cada dez casos alguém ignorou esse contrato. Aqui está como o sistema de numeração funciona, o que ^ e ~ realmente fazem no package.json e por que commitar seu lockfile é indispensável.

Versão Semântica: O Sistema de Numeração que seu npm install depende 1
ANUNCIADO Remover?

Seu build quebrou. Funcionava na sexta-feira. npm install em segunda-feira foi incluído react-query@5 e agora metade dos seus hooks desapareceu. Você está diante de uma pilha de erros que não existia antes, e em algum lugar um changelog está acumulando poeira.

Esta é uma história de semver. Especificamente, é sua culpa.

O que os três números realmente significam

MAJOR.MINOR.PATCH — é isso. Três slots, três regras:

  • PATCH (1.2.3 → 1.2.4): Correção de bug. Nada no seu código precisa mudar. Você apenas recebe um comportamento menos quebrado.
  • MINOR (1.2.3 → 1.3.0): Nova funcionalidade adicionada, compatível para versões anteriores. Você não precisa usá-la, mas ela está lá.
  • MAJOR (1.2.3 → 2.0.0): Algo quebrou. Uma função foi renomeada, removida ou alterada no contrato. A API antiga desapareceu ou funciona de forma diferente.

A palavra-chave em todos os três é compatível para versões anteriores. MINOR e PATCH são promessas: “não quebramos nada que você já estava usando”. MAJOR é uma advertência: “sim, quebrou algo”.

Quando um mantenedor aumenta a versão MAJOR e você não percebe porque você fixou ^1.0.0 no package.json e o arquivo de bloqueio estava obsoleto — isso é de você. O padrão funcionou exatamente como foi projetado.

O contrato social do semver

O semver é uma convenção, não uma lei. Pacotes podem afirmar que seguem esse padrão e depois lançar uma versão MINOR com mudanças quebrantes. Quando isso acontece, é uma falta de integridade do mantenedor. Mas quando um pacote aumenta corretamente a versão MAJOR para indicar uma quebra e você o inclui sem olhar — você é quem quebrou seu próprio build.

É por isso que existem changelogs. Uma CHANGELOG.md entrada que diz “Removido o depreciado v1Api — use v2Api em vez” é o mantenedor cumprindo seu lado. Não ler isso é você ignorando o seu. O changelog é uma leitura de dois minutos. A sessão de depuração que ele evita não é.

^ vs ~ — as mecânicas reais

Em package.json, ^ (caret) e ~ (tilde) definem faixas de versão. Elas parecem semelhantes e comportam-se de forma muito diferente.

Caret (^): Permite qualquer coisa que não aumente a versão MAJOR. Isso é o padrão do npm quando você executa npm install some-package.

  • ^1.2.3 resolve para >=1.2.3 <2.0.0
  • ^0.2.3 resolve para >=0.2.3 <0.3.0 — caso especial: 0.x trata a versão MINOR como quebrante
  • ^0.0.3 resolve para >=0.0.3 <0.0.40.0.x fixa exatamente, sem margem de erro

Tilde (~): Permite apenas atualizações de PATCH, dentro da versão especificada MINOR.

  • ~1.2.3 resolve para >=1.2.3 <1.3.0
  • ~1.2 resolve para >=1.2.0 <1.3.0 — igual a ~1.2.0
  • ~1 resolve para >=1.0.0 <2.0.0 — equivalente a ^1.0.0 no momento atual

Exemplos de faixa de versão

FaixaO que permiteCorrespondência concreta
1.2.3Exatamente esta versãoApenas 1.2.3
^1.2.3Qualquer MINOR/PATCH ≥ 1.2.31.2.4, 1.3.0, 1.99.0 — NÃO 2.0.0
^0.2.3PATCH dentro de 0.2.x apenas0.2.4, 0.2.99 — NÃO 0.3.0
~1.2.3PATCH dentro de 1.2.x apenas1.2.4, 1.2.99 — NÃO 1.3.0
~1.2Qualquer PATCH de 1.2.x1.2.0, 1.2.1, 1.2.99
>=1.2.3 <2.0.0Faixa explícitaResultado igual a ^1.2.3
1.2.xQualquer PATCH de 1.21.2.0, 1.2.1, 1.2.99
*Qualquer coisaO que o npm achar que instalar hoje

O * Faixa é uma estratégia de versão "confie em mim, amigo". Você não está fixando nada. Se um pacote lançar uma API totalmente reescrita, você receberá isso na próxima v9.0.0 com cache limpo. Use apenas em aplicações de nível superior que nunca são dependências de outros pacotes — e mesmo então, apenas se a reprodutibilidade realmente não importar para você (importa). npm install com um cache limpo. Use-o apenas em aplicações de nível superior que não são dependências de outros pacotes — e mesmo assim, apenas se a reprodutibilidade realmente não importar para você (ela importa).

Identificadores de versão pré-lançamento

Antes do lançamento estável, os mantenedores rotulam versões com uma etiqueta de pré-lançamento:

  • 1.0.0-alpha.1 — early, instável, a API provavelmente ainda está mudando
  • 1.0.0-beta.2 — completa em funcionalidade, ainda sendo testada, espere alguns defeitos
  • 1.0.0-rc.1 — candidato ao lançamento, deve ser usada em produção a menos que algo surja nos testes finais

Pré-lançamentos são ordenados abaixo do lançamento estável: 1.0.0-alpha.1 < 1.0.0. E criticamente, ^1.0.0 instalará não — pré-lançamentos só correspondem se você especificar explicitamente na sua faixa. É esse comportamento que evita que você opte acidentalmente por uma versão alpha quando queria acompanhar versões estáveis. 2.0.0-beta.1 Se você estiver consumindo um pacote que só tem pré-lançamentos, fixe a string completa da versão:

. Não use "some-package": "1.0.0-beta.2"com pré-lançamentos a menos que você saiba que o mantenedor os trata com cuidado — a maioria não faz isso. ^ ou ~ com versões pré-lançamento, a menos que você saiba que o mantenedor as trata com cuidado — a maioria não faz isso.

Verificando uma faixa antes de cometer

Antes de fixar uma faixa de versão em package.json, vale a pena confirmar o que você realmente está concordando em instalar. O Calculador de Versão Semver recebe uma faixa de versão e uma lista de versões candidatas e mostra quais delas correspondem — útil quando você está incerto se ~2.3 cobre uma versão específica que você precisa, ou quando você está revisando um PR e a faixa parece errada.

Os três modos de falha

A maioria dos falhas relacionadas ao semver no build segue um dos três padrões:

  1. ^ + aumento MAJOR + arquivo de bloqueio excluído: Você fixou ^1.0.0, o mantenedor lançou 2.0.0, o arquivo de bloqueio foi excluído ou nunca foi commitado, o CI instala 2.0.0. Solução: commit seu arquivo de bloqueio. Em todos os projetos. Sem exceções.
  2. * em uma biblioteca que você publica: Você é um autor de biblioteca que usou * para uma dependência. Cada usuário downstream da sua biblioteca herda seu wildcard. Você tornou o grafo de dependência do outro seu problema. Solução: use faixas explícitas em qualquer coisa que você publique no npm.
  3. Pré-lançamento sem arquivo de bloqueio: Uma faixa solta puxou 1.0.0-alpha.3, a API mudou de alpha.1, nada funciona. Solução: fixe pré-lançamentos explicitamente e — diga comigo — commit o arquivo de bloqueio.

Leia o changelog

Quando uma versão MAJOR é lançada para qualquer coisa na sua árvore de dependências, dedique dois minutos ao changelog. Os mantenedores o escreveram para que você não tivesse que reverse-engineer a quebra a partir de uma pilha de erros às 3h da madrugada.

Se um pacote lança mudanças quebrantes sob um aumento MINOR sem changelog — isso é falta de integridade. Crie um issue. Aponte publicamente. Mas se a versão MAJOR estiver claramente presente, o guia de migração for detalhado e você o inclui sem olhar: a ferramenta fez exatamente o que você lhe pediu. O contrato foi escrito em três números. Você simplesmente não o leu.

Quer eliminar anúncios? Fique sem anúncios hoje mesmo

Instale nossas extensões

Adicione ferramentas de IO ao seu navegador favorito para acesso instantâneo e pesquisa mais rápida

Ao Extensão do Chrome Ao Extensão de Borda Ao Extensão Firefox Ao Extensão Opera

O placar chegou!

Placar é uma forma divertida de acompanhar seus jogos, todos os dados são armazenados em seu navegador. Mais recursos serão lançados em breve!

ANUNCIADO Remover?
ANUNCIADO Remover?
ANUNCIADO Remover?

Notícias com destaques técnicos

Envolver-se

Ajude-nos a continuar fornecendo ferramentas gratuitas valiosas

Compre-me um café
ANUNCIADO Remover?