Семантическая версия Система нумерации, на которую зависит ваш npm install
Три цифры Semver — это договор. MAJOR нарушает, MINOR добавляет, PATCH исправляет — и когда ваша сборка ломается после npm install, в девяносто случаях из ста кто-то игнорирует этот договор. Вот как работает система нумерации, что на самом деле делают ^ и ~ в package.json, и почему обязательным является коммит локального файла.
Ваша сборка сломалась. Работало в пятницу. npm install в понедельник был втянут react-query@5 и теперь половина ваших хуков исчезла. Вы смотрите на стек-трейс, который раньше не существовал, и где-то в стороне собирается пыль в изменении версий.
Это история по semver. Конкретно, это ваша вина.
Что означают три цифры на самом деле
MAJOR.MINOR.PATCH — это всё. Три слота, три правила:
- ОБНОВИТЬ (1.2.3 → 1.2.4): Исправление ошибки. В вашем коде ничего не нужно менять. Вам просто нужно меньше поведения, которое сломано.
- МИНОР (1.2.3 → 1.3.0): Добавлена новая функция, совместима с обратной совместимостью. Вы не обязаны использовать её, но она есть.
- МАЙОР (1.2.3 → 2.0.0): Что-то сломалось. Функция была переименована, удалена или изменила сигнатуру. Устаревший API исчез или работает иначе.
Ключевое слово в трёх случаях — обратная совместимость. МИНОР и ПАТЧ — это обещания: «мы не нарушили ничего, что вы уже использовали». МАЙОР — это предупреждение: «мы нарушили».
Когда поддерживатель повышает МАЙОР, и вы не замечаете, потому что фиксировали ^1.0.0 в package.json и файл с блокировками был устаревшим — это ваша вина. Спецификация работала ровно так, как и было предусмотрено.
Социальный контракт по semver
Semver — это конвенция, а не закон. Пакеты могут утверждать, что следуют за ним, и затем выпускать МИНОР с разрушающими изменениями. Когда это происходит, это плохая воля со стороны поддерживателя. Но когда пакет правильно повышает МАЙОР для сигнализации о разрушении и вы его втягиваете без осознания — вы сами нарушаете свою собственную сборку.
Это и есть причина существования изменений. Ввод CHANGELOG.md пункт, который гласит «Удалено устаревшее v1Api — используйте v2Api вместо» — это то, что поддерживатель выполняет свою часть. Не читать это — это ваша игнорирование своей части. Изменение — это двуминутное чтение. Сессия отладки, которую оно предотвращает, не может быть такой.
^ против ~ — реальные механизмы
В package.json, ^ (caret) и ~ (tilde) определяют диапазоны версий. Они выглядят похоже и ведут себя совершенно по-разному.
Caret (^): Позволяет любую версию, не повышающую МАЙОР. Это по умолчанию npm при запуске npm install some-package.
^1.2.3решает>=1.2.3 <2.0.0^0.2.3решает>=0.2.3 <0.3.0— особый случай:0.xрассматривает МИНОР как разрушающий^0.0.3решает>=0.0.3 <0.0.4—0.0.xфиксирует точно, без возможности изменений
Tilde (~): Позволяет обновления ПАТЧ только в рамках указанного МИНОР.
~1.2.3решает>=1.2.3 <1.3.0~1.2решает>=1.2.0 <1.3.0— то же самое, что~1.2.0~1решает>=1.0.0 <2.0.0— эквивалентно^1.0.0на данном этапе
Примеры диапазонов версий
| Диапазон | Что он позволяет | Точные совпадения |
|---|---|---|
1.2.3 | То же самое версия | Только 1.2.3 |
^1.2.3 | Любые МИНОР/ПАТЧ ≥ 1.2.3 | 1.2.4, 1.3.0, 1.99.0 — НЕТ 2.0.0 |
^0.2.3 | ПАТЧ в пределах 0.2.x только | 0.2.4, 0.2.99 — НЕТ 0.3.0 |
~1.2.3 | ПАТЧ в пределах 1.2.x только | 1.2.4, 1.2.99 — НЕТ 1.3.0 |
~1.2 | Любое обновление ПАТЧ в 1.2.x | 1.2.0, 1.2.1, 1.2.99 |
>=1.2.3 <2.0.0 | Явный диапазон | То же самое, что и ^1.2.3 |
1.2.x | Любое обновление ПАТЧ в 1.2 | 1.2.0, 1.2.1, 1.2.99 |
* | Любое возможное | Всё, что чувствует npm сегодня |
The * Диапазон — это стратегия «доверяй, не проверяй» по версиям. Вы не фиксируете ничего. Если библиотека выпускает полностью переписанную API, вы получите это на следующем v9.0.0 с чистым кэшем. Используйте только в приложениях на верхнем уровне, которые не зависят от других пакетов — и даже тогда, только если воспроизводимость действительно не важна для вас (она важна). npm install с чистой кэш-памятью. Используйте его только в приложениях первого уровня, которые не зависят от других пакетов — и даже тогда, только если воспроизводимость действительно не имеет для вас значения (она имеет).
Идентификаторы предварительных выпусков
Перед стабильным выпуском, поддерживатели ставят метку предварительного выпуска:
1.0.0-alpha.1— ранний, нестабильный, API, вероятно, всё ещё меняется1.0.0-beta.2— функционально завершён, всё ещё подвергается тестированию, ожидайте некоторых несовершенств1.0.0-rc.1— кандидат на выпуск, должен быть пригоден для производства, если не появится что-то в финальных тестах
Предварительные выпуски сортируются ниже стабильного выпуска: 1.0.0-alpha.1 < 1.0.0. И критически, ^1.0.0 установит нет — предварительные выпуски совпадают только в том случае, если вы явно указываете их в диапазоне. Это поведение предотвращает случайное включение альфа-версии, когда вы хотели отслеживать стабильные выпуски. 2.0.0-beta.1 — предварительные выпуски соответствуют только в том случае, если вы явно указываете их в диапазоне. Это поведение предотвращает случайное включение альфа-версии, когда вы хотели отслеживать стабильные выпуски.
Если вы используете пакет, который имеет только предварительные выпуски, фиксируйте полную строку версии: "some-package": "1.0.0-beta.2". Не используйте ^ или ~ с предварительными выпусками, если вы не знаете, что поддерживатель их тщательно относится — большинство не так делают.
Проверка диапазона до того, как вы его закрепите
Перед закреплением диапазона версий в package.json, стоит убедиться, что вы действительно соглашаетесь устанавливать. Инструмент Semver Version Calculator принимает диапазон версий и список кандидатов и показывает, какие из них совпадают — полезно, когда вы не уверены, охватывает ли ~2.3 конкретную версию, которую вам нужно, или когда вы рассматриваете запрос и диапазон кажется неправильным.
Три режима сбоев
Большинство сбоев, связанных с semver, следуют одному из трёх шаблонов:
^+ повышение МАЙОР + удалённый файл блокировки: Вы закрепили^1.0.0, поддерживатель выпустил2.0.0, файл блокировки был удалён или никогда не был зафиксирован, CI устанавливает 2.0.0. Исправление: зафиксируйте свой файл блокировки. В каждом проекте. Никаких исключений.*в библиотеке, которую вы публикуете: Вы — автор библиотеки, который использовал*для зависимости. Каждый пользователь, который использует ваш пакет, наследует вашу звёздочку. Вы сделали их граф зависимостей вашей проблемой. Исправление: используйте явные диапазоны в любом пакете, который вы публикуете в npm.- Предварительный выпуск без файла блокировки: Разрешённый диапазон втянул
1.0.0-alpha.3, API изменился сalpha.1, ничего не работает. Исправление: явно фиксируйте предварительные выпуски и — скажите это со мной — зафиксируйте файл блокировки.
Читайте изменение
Когда выпускается версия МАЙОР для чего-либо в вашей зависимости, потратите две минуты на изменение. Разработчики написали его так, чтобы вы не пришлось разбираться в разрушении из стека-трейса в 3 часа ночи.
Если библиотека выпускает разрушающие изменения под МИНОР с отсутствием изменений — это плохая воля. Оставьте заявку. Назовите это публично. Но если МАЙОР был очевидным, руководство по миграции было подробным, и вы его втянули без проверки — инструменты сделали то, что вы и говорили. Контракт был написан в трёх цифрах. Вы просто не прочитали его.
Вам также может понравиться
Установите наши расширения
Добавьте инструменты ввода-вывода в свой любимый браузер для мгновенного доступа и более быстрого поиска
恵 Табло результатов прибыло!
Табло результатов — это интересный способ следить за вашими играми, все данные хранятся в вашем браузере. Скоро появятся новые функции!
Подписаться на новости
все Новые поступления
всеОбновлять: Наш последний инструмент was added on Июн 26, 2026
