Обновление зависимостей: как не получить проект, который не собирается
Год без обновлений — и безопасное исправление превращается в неделю работы. Разбираем, как держать зависимости свежими без риска для продакшена.

Зависимости — это чужой код, который вы приняли на обслуживание. Он продолжает жить: в нём находят уязвимости, выходят новые версии, старые перестают поддерживать. Проект, который не обновляли год, обычно ещё работает. Проект, который не обновляли два, чаще всего не собирается на новой машине разработчика.
Как накапливается долг
| Отставание | Что происходит | Работа на приведение в порядок |
|---|---|---|
| До 3 месяцев | Мелкие версии, обновление почти автоматическое | 1–2 часа в месяц |
| Полгода | Появились крупные версии отдельных пакетов | 1–2 дня |
| Год | Крупная версия фреймворка, изменения в API | 3–5 дней |
| Два года и больше | Часть пакетов заброшена, нужна замена | от двух недель |
Разница между первой и последней строкой — не в объёме кода, а в том, что при большом отставании обновления перестают быть независимыми. Новая версия одного пакета требует новой версии второго, та не работает со старой сборкой, и вместо десяти небольших шагов получается один прыжок без возможности откатиться частично.
Рабочий цикл обновлений
- Раз в неделю — автоматические заявки на исправляющие и минорные версии
- Раз в месяц — обзор крупных версий и решение по каждой отдельно
- Внеочередно — уязвимости с высокой критичностью в используемом коде
- Раз в квартал — проверка, не заброшены ли ключевые пакеты
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: npm
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 5
groups:
# Мелкие версии — одной заявкой: разбирать их по отдельности
# незачем, а сорок открытых заявок никто не читает
patch-and-minor:
patterns: ["*"]
update-types: ["minor", "patch"]
ignore:
# Крупные версии обновляем осознанно и по плану
- dependency-name: "*"
update-types: ["version-update:semver-major"]Смысл этой настройки — разделить рутину и решения. Мелкие версии проходят через тесты и вливаются почти без участия человека. Крупные версии не появляются в списке заявок сами и планируются отдельной задачей с оценкой.
Что должно быть до автоматизации
- Заблокированный файл версий в репозитории: без него сборка невоспроизводима
- Тесты, покрывающие основные сценарии — иначе обновление проверить нечем
- Предварительное окружение, куда попадает каждая ветка перед продакшеном
- Возможность быстро откатить релиз
Без этого автоматические обновления опасны: они будут вливаться и ломать продакшен незаметно. Именно поэтому мы обычно начинаем поддержку унаследованного проекта не с обновлений, а с приведения в порядок сборки и проверок.
Крупные версии фреймворка
Переход на новую крупную версию — отдельный проект со своей оценкой. Схема, которая себя оправдывает: читаем руководство по миграции целиком, оцениваем объём, выполняем в отдельной ветке, держим её недолго. Ветка миграции, живущая месяц, обречена на болезненное слияние.
Обновления — это не улучшение продукта. Это плата за то, чтобы улучшения оставались возможными.
Частые вопросы
- Как часто нужно обновлять зависимости
- Мелкие и исправляющие версии — раз в одну-две недели, крупные — по плану раз в квартал или при появлении важных изменений. Такой ритм занимает несколько часов в месяц и не даёт долгу накопиться.
- Что делать, если пакет заброшен
- Оценить риск и запланировать замену: заброшенный пакет с уязвимостью нельзя ни исправить, ни обновить. Иногда правильный выход — форк или перенос нужной функции в свой код, если она небольшая.
- Можно ли обновляться без тестов
- Формально да, практически это лотерея. Минимальный набор проверок основных сценариев — регистрация, оформление заказа, оплата — окупается на первом же обновлении, которое что-то ломает.
Похожая задача в вашем проекте?
Разберём вашу ситуацию и пришлём оценку по этапам — без обязательств и общих слов.
Обсудить задачу

