Каков синтаксис версии bower (и npm)?

274

Bower позволяет мне определять требования к версиям для пакетов, используя следующий синтаксис:

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

Но я не смог найти, какой синтаксис использовать для <version>. Я знаю, что могу указать следующие версии:

  • больше определенной версии с ">1.0.0"
  • больше или равно версии: ">=1.0.0"
  • или в каком - то диапазоне: "1.0.0 - 2.0.0".

Я также знаю , что есть общая версия синтаксис , содержащие тильды: "~1.0.0". Но я не уверен, что это значит и является ли это так же, как "=1.0.0".

Мне также интересно узнать, могу ли я указать несколько непоследовательных версий, например, точно 1.0.3плюс версии больше чем 1.5.0, и т. Д ...

Самуэль Хапак
источник
3
Это может быть дубликатом stackoverflow.com/a/19040351/537738
Дэвид

Ответы:

341

В двух словах, синтаксис номеров версий Bower (и NPM) называется SemVer, что сокращенно от Semantic Versioning. Вы можете найти документацию для подробного синтаксиса SemVer, который используется в Bower и NPM в API для анализатора semver в Node / npm . Вы можете узнать больше о базовой спецификации (которая не упоминает ~или другие детали синтаксиса) на semver.org .

Есть супер-удобный визуальный калькулятор с семивром, с которым вы можете играть, что делает все это гораздо проще в поиске и тестировании.

SemVer - это не просто синтаксис! Здесь есть несколько интересных вещей о правильных способах публикации API, которые помогут понять, что означает синтаксис. Кардинально:

После того как вы определили свой публичный API, вы сообщаете об изменениях в нем с определенными приращениями к номеру вашей версии. Рассмотрим формат версии XYZ (Major.Minor.Patch) . Исправления ошибок, не влияющие на API, увеличивают версию исправления, обратно совместимые добавления / изменения API увеличивают младшую версию, а обратно несовместимые изменения API увеличивают основную версию.

Итак, ваш конкретный вопрос ~касается этой схемы Major.Minor.Patch. (Как и соответствующий оператор каретки ^.) Вы можете использовать ~для сужения диапазона версий, которые вы готовы принять:

  • последующие изменения уровня патча к той же вспомогательной версии ( «исправления ошибок, не влияющие на API» ), или:
  • последующие незначительные изменения в той же основной версии ( «обратно совместимые дополнения / изменения API» )

Например: чтобы указать, что вы будете принимать любые последующие изменения уровня патча в дереве 1.2.x, начиная с 1.2.0, но менее 1.3.0, вы можете использовать:

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

Это также дает вам те же результаты, что и при использовании .xсинтаксиса:

"angular": "1.2.x"

Но вы можете использовать тильду / ~синтаксис, чтобы быть еще более конкретным: если вы готовы принимать изменения уровня патча, начиная с 1.2.4 , но все еще менее 1.3.0, вы должны использовать:

"angular": "~1.2.4"

Двигаясь влево, к основной версии, если вы используете ...

"angular": "~1"

... это так же, как ...

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

... и соответствует любым незначительным изменениям или изменениям уровня исправлений выше 1.0.0 и ниже 2.0:

Обратите внимание, что последний вариант выше: он называется «диапазон каретки» . Каретка очень похожа на a >, так что вы будете извинены за то, что думаете, что это означает «любая версия больше 1.0.0». (Я, конечно, поскользнулся на этом.) Нет!

Диапазоны каретки в основном используются, чтобы сказать, что вы заботитесь только о самой левой значащей цифре - обычно основной версии - и что вы разрешите любые незначительные изменения или изменения уровня патча, которые не затрагивают эту самую левую цифру. Тем не менее, в отличие от диапазона тильды, в котором указана основная версия, диапазоны каретки позволяют указать точную начальную точку вспомогательного / патча. Таким образом, ^1.0.0 === ~1диапазон каретки, такой как ^1.2.3позволяет вам сказать, что вы будете принимать любые изменения >=1.2.3 && <2.0.0. Вы не могли бы сделать это с диапазоном тильды.

Поначалу все кажется странным, когда смотришь на это с близкого расстояния. Но отведите на секунду и подумайте об этом следующим образом: каретка просто позволяет вам сказать, что вас больше всего беспокоит то, какая значимая цифра остается самой левой. Тильда позволяет вам сказать, что вас больше всего волнует, какая цифра самая правая. Остальное подробно.

Именно выразительная сила тильды и кареты объясняет, почему люди используют их гораздо больше, чем простой .xсинтаксис: они просто позволяют вам делать больше. Вот почему вы увидите, что тильда часто используется даже там, где она .xбудет служить. В качестве примера посмотрите сам npm: его собственный файл package.json содержит множество зависимостей в ~2.4.0формате, а не в 2.4.xформате, который он мог бы использовать. Придерживаясь этого ~, синтаксис непротиворечив во всем списке из более чем 70 версий зависимостей, независимо от того, какой номер начального патча является приемлемым.

Во всяком случае, в SemVer есть еще кое-что, но я не буду пытаться описывать все это здесь. Проверьте это в readme пакета semver узла . И обязательно используйте калькулятор семантического контроля версий, пока вы тренируетесь и пытаетесь понять, как работает SemVer.


RE: Номера последовательных версий: последний вопрос OP, по-видимому, касается указания непоследовательных номеров / диапазонов версий (если я отредактировал их справедливо). Да, вы можете сделать это, используя общую двойную трубу «или» оператор: ||. Вот так:

"angular": "1.2 <= 1.2.9 || >2.0.0"
XML
источник
27
Таким образом, ~в частности, означает, что номер патча (третьего) может быть больше указанного, например ~1.2.3, эквивалентен >=1.2.3 <1.3.0.
z0r
1
Может также использоваться для второстепенного (второго) числа, согласно приведенным выше правкам.
XML
Интересно, что документация SemVer также, кажется, разрешает X-нотацию (которая намного более интуитивна для людей).
Франк Нок
2
Поначалу x-нотация удобна для чтения, но гораздо менее гибка. Так , например, '1.1.x' === '>=1.1.0' === '~1.1.0'. Случай 1.1.0 прост. Но x-нотация не может быть гранулированной, как может '>=1.1.4'или '~1.1.4'. Итак, вы попадаете '1.1.x'в одно место в вашем списке зависимостей и '~2.7.3'в другое место. Это нормально, и работает, но разработчик должен проанализировать несколько синтаксисов, чтобы прочитать один список. И, если вы пишете пакеты для программной установки версии, вам нужен единый синтаксис. И большинство людей хотят предотвратить серьезные изменения. Следовательно, все проблемы решены с ~.
XML
1
Хах. Я думаю, что "грок" менее географичен, чем культурный (и, возможно, связанный с возрастом), @Clonkex. Для будущих читателей: это ссылка на « Незнакомца Хайнлайна в чужой стране» ...
XML
141

Основываясь на semver , вы можете использовать

  • Диапазоны дефиса XYZ - ABC 1.2.3-2.3.4 Указывает > = 1.2.3 <= 2.3.4

  • X-диапазонов 1.2.x 1.X 1.2.*

  • Диапазоны тильды ~1.2.3 ~1.2 Указывает, что разрешено изменение уровня патча или незначительные изменения версии.

  • Диапазоны каретки ^ 1.2.3 ^ 0.2.5 ^ 0.0.4

    Позволяет вносить изменения, которые не изменяют самую левую ненулевую цифру в кортеже [major, minor, patch]

    • ^1.2.x (означает> = 1.2.0 <2.0.0)
    • ^0.0.x (означает> = 0.0.0 <0.1.0)
    • ^0.0 (означает> = 0.0.0 <0.1.0)
Джером Энтони
источник
21
Спасибо за глупость, легко читаемый ответ. Я не должен был отслеживать или что-то еще, просто, бум, есть ответ. Хорошо сделано;)
toddmo
76

Бауэр использует синтаксис semver , но вот несколько быстрых примеров:

Вы можете установить конкретную версию:

$ bower install jquery#1.11.1

Вы можете использовать ~, чтобы указать «любую версию, которая начинается с этой»:

$ bower install jquery#~1.11

Вы можете указать несколько требований к версии вместе:

$ bower install "jquery#<2.0 >1.10"
Уилфред Хьюз
источник
1
Мне любопытно практическое использование этого. Установка рулетки?
gravidThoughts
Глядя на ответ @ XMLilley (и несколько документов), «начинаем с» кажется неправильным, поскольку 1.12, 1.13 также будет в порядке, пока не выйдет основная версия ...
Фрэнк Нок
13

Вы также можете использовать latestключевое слово для установки самой последней версии:

  "dependencies": {
    "fontawesome": "latest"
  }
shacker
источник
1
Семвер не упоминает об этом. Где вы установили, что это действительно? :) Там написано " "*" := >=0.0.0(любая версия удовлетворяет)", что близко, но немного расплывчато, так как оно не говорит конкретно о последних, так что это может быть первым, что он найдет?
ГазБ
Честно говоря, это было просто методом проб и ошибок - я попробовал, и это сработало! Вы можете быть правы, что это не на 100% верно, но это работает.
шейкер
7

Если номер патча отсутствует, ~это эквивалентно добавлению .xк версии без тильды. Если есть номер патча, ~разрешает все номера патчей> = указанный.

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

У меня недостаточно баллов, чтобы комментировать принятый ответ, но некоторая информация тильды расходится с документацией, связанной с semver: не"angular": "~1.2" будет соответствовать 1.3, 1.4, 1.4.9. Кроме того, и это не эквивалентны. Это можно проверить с помощью калькулятора npm semver ."angular": "~1""angular": "~1.0"

Decima
источник