Qual é a sintaxe da versão do bower (e npm)?

274

O Bower permite especificar requisitos de versão para pacotes usando a seguinte sintaxe:

"dependencies": {
  "<name>": "<version>",
},

Mas não consegui encontrar qual é a sintaxe a ser usada para o <version>. Eu sei que posso especificar versões para serem:

  • maior que uma determinada versão com ">1.0.0"
  • maior ou igual a uma versão: ">=1.0.0"
  • ou em algum intervalo: "1.0.0 - 2.0.0".

Sei também que há uma sintaxe versão comum contendo o til: "~1.0.0". Mas não tenho certeza do que isso significa e se é o mesmo que "=1.0.0".

Também estou interessado em saber se sou capaz de especificar várias versões não consecutivas, como exatamente 1.0.3mais versões maiores que 1.5.0, etc ...

Samuel Hapak
fonte
3
Esta poderia ser uma duplicata de stackoverflow.com/a/19040351/537738
David

Respostas:

341

Em resumo, a sintaxe dos números de versão do Bower (e NPMs) é chamada SemVer, abreviação de 'Semantic Versioning'. Você pode encontrar documentação para a sintaxe detalhada do SemVer, conforme usado no Bower e no NPM, na API do analisador de semver em Nó / npm . Você pode aprender mais sobre a especificação subjacente (que não menciona ~ou outros detalhes da sintaxe) em semver.org .

Há uma calculadora semver visuais super-acessível você pode jogar com, fazendo tudo isso muito mais fácil de grok e teste.

O SemVer não é apenas uma sintaxe! Tem algumas coisas bastante interessantes a dizer sobre as maneiras corretas de publicar APIs, o que ajudará a entender o significado da sintaxe. Crucialmente:

Depois de identificar sua API pública, você comunica alterações nela com incrementos específicos ao número da sua versão. Considere um formato de versão de XYZ (Major.Minor.Patch) . As correções de erros que não afetam a API incrementam a versão do patch, as adições / mudanças de API compatíveis com versões anteriores aumentam a versão secundária e as alterações incompatíveis com a API aumentam a versão principal.

Portanto, sua pergunta específica está ~relacionada ao esquema Major.Minor.Patch. (Assim como o operador de interpolação relacionado ^.) Você pode usar ~para restringir o intervalo de versões que deseja aceitar:

  • alterações subsequentes no nível do patch na mesma versão secundária ( "correções de bugs que não afetam a API" ) ou:
  • alterações subsequentes em nível secundário na mesma versão principal ( "adições / alterações de API compatíveis com versões anteriores" )

Por exemplo: para indicar que você fará alterações subseqüentes no nível de patch na árvore 1.2.x, começando com 1.2.0, mas menor que 1.3.0, você pode usar:

"angular": "~1.2"
  or:
"angular": "~1.2.0"

Isso também fornece os mesmos resultados que o uso da .xsintaxe:

"angular": "1.2.x"

Mas você pode usar o til / ~sintaxe para ser ainda mais específico: se você estiver disposto a aceitar apenas alterações no nível de patch começando com 1.2.4 , mas ainda menos que 1.3.0, você usaria:

"angular": "~1.2.4"

Mover para a esquerda, para a versão principal , se você usar ...

"angular": "~1"

... é o mesmo que...

"angular": "1.x"
  or:
"angular": "^1.0.0"

... e corresponde a qualquer alteração menor ou menor que 1.0.0 e menor que 2.0:

Observe a última variação acima: é chamada de 'intervalo de sinal de intercalação' . O sinal de intercalação se parece muito com um >, portanto, você deveria se desculpar por pensar que significa "qualquer versão maior que 1.0.0". (Eu certamente esqueci disso.) Não!

Os intervalos de sinal de intercalação são basicamente usados ​​para dizer que você se importa apenas com o dígito mais significativo à esquerda - geralmente a versão principal - e que permitirá alterações menores ou no nível de patch que não afetem o dígito mais à esquerda. No entanto, diferentemente de um intervalo de til que especifica uma versão principal, os intervalos de sinal de intercalação permitem especificar um ponto inicial preciso / menor de correção. Então, enquanto isso ^1.0.0 === ~1, um intervalo de sinal de intercalação como o ^1.2.3permite dizer que você fará as alterações >=1.2.3 && <2.0.0. Você não poderia fazer isso com um intervalo de til.

Tudo isso parece confuso no começo, quando você olha de perto. Mas diminua o zoom por um segundo e pense sobre o seguinte: o cursor simplesmente permite que você diga que está mais preocupado com o dígito significativo que resta mais. O til permite que você diga que está mais preocupado com o dígito mais à direita. O resto é detalhe.

É o poder expressivo do til e do sinal de intercalação que explica por que as pessoas os usam muito mais do que a .xsintaxe mais simples : eles simplesmente permitem que você faça mais. É por isso que você verá o til usado frequentemente mesmo onde .xserviria. Como um exemplo, consulte o próprio npm: seu próprio arquivo package.json inclui muitas dependências no ~2.4.0formato, em vez do 2.4.xformato que ele poderia usar. Ao seguir ~, a sintaxe é consistente em toda a lista de mais de 70 dependências com versão, independentemente de qual número de patch inicial seja aceitável.

Enfim, ainda há mais no SemVer, mas não vou tentar detalhar tudo aqui. Confira no leia-me do pacote semver do . E certifique-se de usar a calculadora de versão semântica enquanto estiver praticando e tentando entender como o SemVer funciona.


RE: Números de versão não consecutivos: A pergunta final do OP parece ser sobre a especificação de números / intervalos de versões não consecutivos (se eu o tiver editado de maneira justa). Sim, você pode fazer isso, usando o double-pipe comum "ou" operador: ||. Igual a:

"angular": "1.2 <= 1.2.9 || >2.0.0"
XML
fonte
27
Então, ~em particular, o número do patch (terceiro) pode ser maior que o especificado, por exemplo, ~1.2.3é equivalente a >=1.2.3 <1.3.0.
Z0r 22/10/14
1
Também pode ser usado para o número menor (segundo), por edições embutidas acima.
XML
interessante, que a documentação do SemVer também pareça permitir a notação x (que é muito mais intuitiva para os seres humanos).
precisa saber é o seguinte
2
A notação x é intuitiva de ler a princípio, mas muito menos flexível. Por exemplo '1.1.x' === '>=1.1.0' === '~1.1.0',. O caso 1.1.0 é fácil. Mas a notação x não pode ser granular, como pode '>=1.1.4'ou '~1.1.4'. Então, você acaba '1.1.x'em um lugar na sua lista de dependências e '~2.7.3'em outro lugar. Isso é bom e funciona, mas um desenvolvedor precisa analisar várias sintaxes para ler uma única lista. E, se você estiver escrevendo pacotes para definir programaticamente a versão, deseja uma única sintaxe. E, a maioria das pessoas quer impedir que ocorram alterações. Portanto, todos os problemas resolvidos com ~.
XML
1
Hah. Eu acho que "grok" é menos geográfico do que o cultural nerd-iluminado (e possivelmente relacionado à idade), @Clonkex. Para futuros leitores: é uma referência para de Heinlein Stranger in a Strange Land ...
XML
141

Baseado em sempre , você pode usar

  • O hífen varia XYZ - ABC 1.2.3-2.3.4 indica > = 1.2.3 <= 2.3.4

  • X-Ranges 1.2.x 1.X 1.2.*

  • Intervalos de til ~1.2.3 ~1.2 Indica permitir alterações no nível do patch ou pequenas alterações na versão.

  • Intervalos de sinal de intercalação ^ 1,2,3 ^ 0,2,5 ^ 0,0,4

    Permite alterações que não modificam o dígito diferente de zero, à esquerda, na tupla [maior, menor, do patch]

    • ^1.2.x (significa> = 1.2.0 <2.0.0)
    • ^0.0.x (significa> = 0.0.0 <0.1.0)
    • ^0.0 (significa> = 0.0.0 <0.1.0)
Jerome Anthony
fonte
21
Obrigado pela resposta absurda e fácil de ler. Eu não tive que rastrear nada, apenas, boom, há a resposta. Bem feito;)
toddmo
76

O Bower usa a sintaxe semver , mas aqui estão alguns exemplos rápidos:

Você pode instalar uma versão específica:

$ bower install jquery#1.11.1

Você pode usar ~ para especificar 'qualquer versão que comece com isso':

$ bower install jquery#~1.11

Você pode especificar vários requisitos de versão juntos:

$ bower install "jquery#<2.0 >1.10"
Wilfred Hughes
fonte
1
Estou curioso sobre o uso prático disso. Instalação de roleta?
gravidThoughts
Olhando @ resposta de XMLilley (e docs semver) 's com start' parece errado, como 1.12, 1.13, também estaria bem, desde, como versão principal não subir ...
Frank Nocke
13

Você também pode usar a latestpalavra-chave para instalar a versão mais recente disponível:

  "dependencies": {
    "fontawesome": "latest"
  }
shacker
fonte
1
Semver não menciona isso. Onde você estabeleceu sua validade? :) Diz " "*" := >=0.0.0(Qualquer versão satisfaz)", que é próxima, mas um pouco vaga, uma vez que não diz especificamente mais recente, portanto poderia ser a primeira que encontrar?
GazB 18/03/16
Para ser sincero, foi apenas tentativa e erro - tentei e funcionou! Você pode estar certo de que não é 100% válido, mas funciona.
22616 shacker
7

Se não houver um número de patch, ~é equivalente a anexar .xà versão não til. Se houver um número de patch, ~permita todos os números de patch> = o número especificado.

~1     := 1.x
~1.2   := 1.2.x
~1.2.3 := (>=1.2.3 <1.3.0)

Eu não tenho pontos suficientes para comentário sobre a resposta aceita, mas algumas das informações til está em desacordo com o ligada semver documentação: "angular": "~1.2"será não coincidir com 1.3, 1.4, 1.4.9. Também "angular": "~1"e não"angular": "~1.0" são equivalentes. Isso pode ser verificado com a calculadora npm semver .

Decima
fonte