ttools
разработкаверсионированиеnpm

Semantic Versioning: как читать версии софта (1.2.3) и не сломать зависимости

Что означают цифры в версии 1.2.3, как понять совместимость версий и почему обновление может сломать код.

Вы открываете package.json, видите "lodash": "^4.17.21", и где-то в голове мелькает мысль: «А что будет, если обновлюсь до 5.0.0?» Или запускаете docker pull node:18, а через неделю код перестаёт работать, потому что вышла версия 19. Semantic Versioning (SemVer) — это стандарт, который объясняет, какие обновления безопасны, а какие требуют правок в коде.

Что такое Semantic Versioning

SemVer — это соглашение о нумерации версий в формате MAJOR.MINOR.PATCH (например, 2.5.13). Каждая позиция отвечает за определённый тип изменений:

  • MAJOR (первая цифра) — несовместимые изменения API. Обновление с 2.x на 3.x может сломать ваш код.
  • MINOR (средняя цифра) — новые фиксы или функции, обратно совместимые. Переход с 2.5.x на 2.6.0 безопасен.
  • PATCH (последняя цифра) — исправления багов, без новых возможностей. Обновление с 2.5.13 на 2.5.14 — только фиксы.

Если версия начинается с 0.x.y, проект считается нестабильным: любое обновление MINOR может сломать совместимость.

Примеры из реального мира

npm-пакеты

Допустим, вы используете библиотеку axios:

{
  "dependencies": {
    "axios": "^1.3.4"
  }
}

Символ ^ означает «разрешены обновления MINOR и PATCH, но не MAJOR». То есть npm установит любую версию 1.x.x, но не перепрыгнет на 2.0.0. Если выйдет 1.4.0 с новым методом — он установится автоматически при npm install, и код останется рабочим. Но если автор выпустит 2.0.0 и удалит старый метод axios.get(), ваш проект без правок сломается.

Другой пример — ~1.3.4. Тильда разрешает только PATCH-обновления: можно обновиться до 1.3.9, но не до 1.4.0.

Docker-образы

В Dockerfile вы пишете:

FROM node:18

Это подтягивает последнюю минорную версию Node.js 18.x. Сегодня это может быть 18.12.1, через месяц — 18.15.0. Если между версиями изменится поведение встроенного модуля (редко, но бывает), тесты могут упасть. Безопаснее фиксировать точную версию:

FROM node:18.12.1-alpine

Так образ не обновится внезапно, и сборка останется воспроизводимой.

Частые ошибки при работе с версиями

Обновление MAJOR без проверки changelog

Вы видите, что express обновился с 4.x до 5.x, и просто правите package.json. Но в Express 5 удалили несколько методов и изменили middlewares. Код падает с ошибкой app.param is not a function. Всегда читайте CHANGELOG или migration guide перед обновлением MAJOR.

Игнорирование lock-файлов

Файлы package-lock.json или yarn.lock фиксируют точные версии зависимостей. Если их не коммитить, у коллеги при npm install установятся более свежие MINOR-версии, и код может работать по-разному. Всегда добавляйте lock-файлы в git.

Префиксы версий в CI/CD

В .gitlab-ci.yml указано:

image: python:3

Сегодня это Python 3.11, через год — 3.13. Если в новой версии изменится синтаксис или поведение библиотеки, пайплайн сломается без видимых причин. Пишите python:3.11 или используйте конкретный digest:

image: python@sha256:abc123...

Как автоматизировать проверку версий

Dependabot и Renovate

Эти боты создают pull request'ы при выходе новых версий зависимостей. Dependabot встроен в GitHub, Renovate поддерживает GitLab и Bitbucket. Они анализируют SemVer и предлагают безопасные обновления: сначала PATCH, потом MINOR, а MAJOR — отдельным PR с пометкой «breaking changes».

npm outdated

Команда показывает устаревшие пакеты с учётом диапазонов версий:

npm outdated

Вывод:

Package  Current  Wanted  Latest
axios    1.3.4    1.6.2   1.6.2
lodash   4.17.21  4.17.21 5.0.0
  • Current — установленная версия
  • Wanted — максимальная в рамках ^ или ~
  • Latest — самая свежая, включая новые MAJOR

Если Wanted и Latest совпадают, обновление безопасно.

Семантическое версионирование и время разработки

Когда вы разрабатываете библиотеку, SemVer помогает пользователям понять риск обновления:

  • Исправили баг в функции? → PATCH: 1.2.31.2.4
  • Добавили новый метод, старый не тронули? → MINOR: 1.2.41.3.0
  • Удалили deprecated-метод или изменили сигнатуру? → MAJOR: 1.3.02.0.0

Если сомневаетесь, используйте калькулятор SemVer — он сравнивает две версии и подсказывает, какой уровень изменений подходит.

Стандарт также требует, чтобы версии с номером 0.x.y считались экспериментальными: публичное API может меняться в любой момент. Релиз 1.0.0 — сигнал, что проект стабилен и готов к production.

Инструменты для проверки и сравнения версий

Если нужно быстро сравнить две версии или преобразовать данные для скриптов, используйте онлайн-инструменты. Сравнение текстов помогает увидеть изменения между двумя CHANGELOG-файлами, а JSON Formatter пригодится для валидации конфигов с версиями зависимостей. Для работы с base64-токенами в CI/CD (например, Docker registry credentials) удобен Base64 Encode/Decode.

Понимание SemVer экономит часы отладки и защищает от внезапных поломок. Зафиксировали версии в lock-файлах, настроили автообновления через Dependabot, и можно спокойно пушить в продакшен.

Инструменты по теме