Семантические версии и диапазоны

Проверка версий по npm-диапазону (^, ~, ||, пререлизы): какие проходят, разложение на компараторы, ближайшая несовпавшая.

Пустой ввод: введите диапазон и список версий.

Перебор патча до 20, затем минор, затем мажор (1.2.20 → 1.3.0 → … → 1.20.20 → 2.0.0); максимум 200 версий, пререлиз и build стартовой отбрасываются.

Как считается

Семантика — поднабор npm semver по спецификации semver.org. Порядок версий: мажор → минор → патч числом; пререлиз меньше релиза того же корня; числовые идентификаторы пререлиза раньше строковых; build-метаданные (+build) в сравнении игнорируются.

Мажор, минор и патч — целые от 0 до 9007199254740991 (2^53 − 1). Если раскрытие caret, tilde, x-range или следующий шаг генератора выходит за этот предел, расчёт отклоняется с ошибкой, без округления; используйте явные сравнения с допустимыми границами. Числовые идентификаторы пререлиза сохраняются без ограничения количества цифр и сравниваются точно как десятичные числа, а не как буквенные строки. Ведущие нули запрещены в core и чисто числовых пререлизах, но допустимы в build. Build сохраняется в исходных строках; в декомпозиции и итоговых версиях он опускается.

Поддерживается

  • ^1.2.3 — caret: не ниже 1.2.3 и в пределах одного мажора (>=1.2.3 <2.0.0-0); для 0.x границы сужаются по npm.
  • ~1.2.3 — tilde: не ниже и в пределах минора (<1.3.0-0); ~1.2 и ~1 расширяются как в npm.
  • 1.2.x, 1.x — частичные версии с вилдкардом сегмента (то же, что 1.2).
  • >=1.4 <2 — AND-условия через пробел; операторы > >= < <= =.
  • ^1.0.0 || >=3 — OR через ||.
  • 1.0.0-alpha.1 — пререлизы. Как в npm: пререлиз совпадает только с группой условий, где задан пререлиз того же корня (кроме точного совпадения).

Не поддерживается

  • hyphen-диапазоны не поддерживаются. Пример только для 1.2 - 2.0: >=1.2.0 <2.1.0-0.
  • вилдкарды целиком * / x, вилдкард в мажорной позиции (x.2.3, ^x.2.3) и пустой диапазон — замените на >=0.0.0 или укажите мажор числом.
  • URL-, git- и тег-диапазоны, префикс v (v1.2.3), оператор &&, ведущие нули в сегментах.

Расчёт идёт на встроенном движке, без внешних библиотек.

Последние диапазоны

Готовые примеры

Что это и как пользоваться

Проверка идёт по правилам npm: диапазон раскладывается на компараторы, и рядом видно, какое условие получилось — ^1.2.3 превращается в >=1.2.3 <2.0.0-0, а ~1.2.3 в >=1.2.3 <1.3.0-0.

Разложение показывает, что диапазон означает на самом деле: ^1.2.3 — не «примерно единица», а конкретное неравенство с границей 2.0.0-0, где -0 исключает пререлизы следующего мажора.

Для версий 0.x границы сужаются по правилам npm: ^0.2.3 не пускает 0.3.0, потому что в нулевом мажоре минор считается ломающим. Это то место, где чаще всего ошибаются, читая package.json глазами.

Поддерживаются частичные версии с вилдкардом сегмента (1.2.x, 1.x), AND-условия через пробел (>=1.4 <2), OR через ||, пререлизы вида 1.0.0-alpha.1 и диапазоны без оператора.

Чего нет — сказано прямо: hyphen-диапазоны (1.2 - 2.0) и вилдкард в мажорной позиции не поддерживаются, страница об этом сообщает, а не считает наугад.

Диапазон без оператора трактуется как точное совпадение, а не как «примерно эта версия»: 1.2.3 означает ровно 1.2.3. Частичные версии достраиваются: 1.2 читается как >=1.2.0 <1.3.0-0, а 1 — как >=1.0.0 <2.0.0-0.

Когда пригодится

  • Проверить, попадёт ли новая версия библиотеки в ваш ^-диапазон до обновления lock-файла.
  • Понять, почему менеджер пакетов поставил именно эту версию: разложение на компараторы объясняет выбор.
  • Сверить несколько версий сразу: список проверяется построчно, с отметкой «проходит» или «не проходит».
  • Разобраться с 0.x-зависимостью, где ^ ведёт себя не так, как в 1.x.
  • Проверить, какие версии из changelog попадают в диапазон, прежде чем обновлять зависимость.
  • Объяснить коллеге, почему ^ в package.json не подтянул библиотеку до нового мажора, хотя тот уже вышел.
  • Сверить версию из lock-файла с диапазоном в package.json, когда они выглядят противоречиво.

Чего инструмент не делает

  • Реестр не запрашивается: страница не знает, какие версии существуют, и проверяет только введённые.
  • Метаданные сборки после + в сравнении не участвуют — так требует спецификация, и это иногда удивляет.
  • Собственные схемы версионирования (дата.сборка, календарные версии) не интерпретируются как SemVer.
  • Содержимое релиза не анализируется: страница судит по номеру версии, а не по изменениям в коде.
  • Версии сравниваются по числам, а не по строкам: 1.10.0 новее 1.9.0, хотя как строка она идёт раньше.

Примеры

Вход
                    ^1.2.0 и версия 1.5.0
                  
Выход
                    проходит: >=1.2.0 <2.0.0-0
                  
Вход
                    ~2.3.0 и версия 2.4.0
                  
Выход
                    не проходит: >=2.3.0 <2.4.0-0