EnglishРусский Map

Ограничения версий по умолчанию

title
Ограничения версий по умолчанию
type
concept
summary
Задаёт ли команда add пакетного менеджера верхнюю границу по SemVer по умолчанию и к чему приводит её отсутствие
tags
package-management, semver, developer-experience
created
2026-05-22
updated
2026-05-22
lang
ru
source_updated
2026-05-22
translated
2026-09-01
translator
lllm/antigravity/gemini-3.7-flash-medium

Когда вы запускаете npm add X, cargo add X, poetry add X или uv add X, инструмент сам выбирает ограничение версии, которое запишет в манифест. Этот выбор по умолчанию кажется мелочью, но влечёт долгосрочные последствия: большинство проектов просто оставляют то, что сгенерировал инструмент, и больше к этому не возвращаются.

Два лагеря:

Экосистема Поведение add X по умолчанию (текущая версия 1.2.3) Есть верхняя граница?
npm / pnpm / yarn ^1.2.3 (карет = совместимая мажорная версия) Да - неявная на границе мажорной версии
Cargo (Rust) 1.2.3 (подразумевается карет; то же, что ^1.2.3) Да
Poetry (Python) >=1.2.3,<2.0.0 (или ^1.2.3 в свежих версиях) Да
Bundler (Ruby) ~> 1.2 (пессимистичное ограничение) Да
uv (Python) >=1.2.3 Нет
pip-tools (Python) точная фиксация через compile Да (излишне строго)

Аргумент в пользу неявной верхней границы: по правилам SemVer смена мажорной версии может ломать публичный API, поэтому инструмент без фиксации мажорной версии обрекает любой проект на потенциальные поломки при выполнении update или upgrade. Аргумент против верхней границы (выбор uv): соблюдение SemVer лишь декларируется, а не гарантируется; верхние границы создают проблемы resolver'у, когда зависимость выпускает мажорный релиз без реальных ломающих изменений; к тому же в Python накопилась долгая история бесполезных конфликтов из-за верхних границ (известно, как poetry add отказывался ставить многие библиотеки из-за транзитивных ограничений, которые самим библиотекам были не нужны).

Проблемы возникают в разные моменты:

  • С верхними границами: чаще появляются ошибки вроде "resolver не может подобрать версии", чаще приходится поднимать версии вручную.
  • Без верхних границ: рутинный upgrade молча подтягивает ломающие изменения, что приводит к падению сборок спустя дни или недели, когда выясняется, что в транзитивном обновлении что-то удалили.

uv сейчас по умолчанию находится в лагере без верхних границ и предлагает флаг --bounds major как экспериментальную опцию. Аргумент в loopwerk-uv-ux-mess заключается в том, что небезопасный вариант не должен быть поведением по умолчанию: большинство пользователей не станут настолько тщательно изучать diff'ы lockfile'ов, чтобы заметить мажорное обновление транзитивной зависимости, а цена слишком строгого ограничения (быстро поднять версию вручную) намного ниже цены незаметной поломки (сбоя, причину которого придётся искать бисекцией).

Это ещё и вопрос о том, кто несёт издержки. Авторы библиотек предпочитают отсутствие верхних границ у своих зависимостей, чтобы избежать взрыва конфликтов версий. Разработчики приложений предпочитают верхние границы, потому что именно им приходится чинить сломанные сборки. Поведение ограничений по умолчанию - это выбор пакетным менеджером стороны в данном конфликте.

См. также

  • loopwerk-uv-ux-mess - подробные аргументы Kevin Renskers против поведения uv по умолчанию
  • supply-chain-security - более широкий контекст безопасности цепочки поставок; период охлаждения (open-source-security-astral) служит ортогональной мерой защиты