Back

Более умные обновления пакетов с npm-check-updates

Более умные обновления пакетов с npm-check-updates

Дрейф зависимостей медленно убивает проекты. Вы пропускаете несколько обновлений, потом ещё несколько, и внезапно перед вами 47 устаревших пакетов — половина с breaking changes, некоторые с уязвимостями безопасности, и нет чёткого пути вперёд. Запуск npm update напоминает русскую рулетку. Массовые обновления ломают CI. Безопасным выбором становится бездействие, которое вовсе не безопасно.

npm-check-updates (ncu) предлагает другой подход: разделение решения о том, что обновлять, от процесса установки и тестирования. Это различие имеет большее значение, чем осознают большинство команд.

Ключевые выводы

  • ncu изменяет диапазоны версий в package.json без изменения node_modules или lockfile, давая вам контроль над моментом установки
  • Используйте --target minor или --target patch для ограничения обновлений до изменений без breaking changes
  • Флаг --peer предотвращает предложение обновлений, которые вызовут конфликты peer-зависимостей
  • Всегда коммитьте package.json и package-lock.json вместе после тестирования обновлений
  • Используйте поле overrides в npm для принудительной установки конкретных версий транзитивных зависимостей при устранении уязвимостей

Почему слепые обновления ломают сборки

Основная проблема управления пакетами JavaScript не в поиске устаревших зависимостей — с этим справляется npm outdated. Проблема в том, что обновление до “latest” игнорирует ограничения peer-зависимостей, границы semver и реальность того, что ваш lockfile существует не просто так.

Когда вы запускаете npm update, npm соблюдает диапазоны версий в вашем package.json. Он не перейдёт с ^2.0.0 на 3.0.0, даже если версия 3 существует. Это сделано намеренно. Но это также означает, что настоящие обновления, требующие изменения диапазонов, застревают на неопределённый срок.

ncu решает это путём прямого изменения package.json — обновления диапазонов версий — без изменения node_modules или вашего lockfile. Вы контролируете, когда происходит установка.

Современные рабочие процессы ncu для управления зависимостями Node.js

Глобальные установки больше не являются моделью по умолчанию. С ncu v18+ запускайте его напрямую через ваш менеджер пакетов:

npx npm-check-updates
# или
pnpm dlx npm-check-updates
# или
bunx npm-check-updates

Это проверяет наличие обновлений без изменения чего-либо. Вы видите, что доступно, с цветовой кодировкой по уровню semver: красный для major, голубой для minor, зелёный для patch.

Критический флаг — это -u, который записывает изменения в package.json. Но вот что важно: это обновляет только манифест. Ваш lockfile остаётся неизменным, пока вы явно не запустите npm install.

Это разделение обеспечивает более безопасный рабочий процесс обновления зависимостей:

  1. Запустите ncu -u --target minor для обновления package.json с изменениями без breaking changes
  2. Запустите npm install для регенерации lockfile
  3. Запустите ваш набор тестов
  4. Если тесты проходят, закоммитьте package.json и package-lock.json вместе

Для major-обновлений обрабатывайте их индивидуально с помощью ncu -u --filter package-name, просмотрите changelog, затем протестируйте.

Peer-зависимости и проверка совместимости

Конфликты peer-зависимостей вызывают большинство сбоев при обновлении. Библиотека компонентов React может требовать React 18, но ваш проект закреплён на React 17. Слепое обновление библиотеки ломает сборку.

Флаг --peer в ncu проверяет совместимость peer-зависимостей перед предложением обновлений. Это предотвращает предложение обновлений, которые немедленно провалят установку.

Для более строгого контроля комбинируйте это с --target:

ncu --peer --target minor

Это показывает только обновления, которые не нарушат ограничения peer-зависимостей и не пересекут границы major-версий.

Lockfile и интеграция с CI-пайплайнами

Ваш lockfile представляет известное рабочее состояние. Относитесь к нему соответственно.

В CI всегда используйте npm ci вместо npm install. Команда ci завершается с ошибкой, если package.json и package-lock.json рассинхронизированы — именно то, что вам нужно. Это выявляет ситуации, когда кто-то обновил package.json, но забыл регенерировать lockfile.

Для автоматизированных рабочих процессов обновления зависимостей в CI паттерн выглядит так:

ncu -u --target patch
npm install
npm test

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

Контроль транзитивных зависимостей с помощью Overrides

Иногда проблема не в ваших прямых зависимостях — а в том, от чего зависят они. Уязвимость на три уровня глубже в дереве зависимостей требует обновления пакета, которым вы не управляете.

Поле overrides в npm позволяет принудительно установить конкретные версии транзитивных зависимостей:

{
  "overrides": {
    "vulnerable-package": "2.0.1"
  }
}

Это стандартная часть управления пакетами JavaScript. Используйте это, когда вам нужен патч безопасности до того, как upstream-мейнтейнеры обновят свои зависимости.

Заключение

Автоматизация обновления зависимостей не означает постоянное обновление всего. Это означает наличие повторяемого процесса, который разделяет обнаружение и установку, соблюдает границы semver и поддерживает синхронизацию вашего lockfile с манифестом.

ncu подходит для этого рабочего процесса, потому что рассматривает обновления package.json как отдельный шаг. Вы решаете, что обновлять, когда устанавливать и когда тестировать. Инструмент обрабатывает рутинную часть — проверку реестров и изменение диапазонов версий — оставляя оценочные решения вам.

Обновляйте патчи еженедельно. Проверяйте minor-версии ежемесячно. Обрабатывайте major-версии обдуманно. Держите ваш lockfile в коммитах. Ваш CI скажет вам спасибо.

Часто задаваемые вопросы

npm update устанавливает более новые версии в пределах существующих диапазонов версий в вашем package.json, но не пересечёт границы major-версий. npm-check-updates изменяет сами диапазоны версий в package.json, позволяя обновляться до любой версии, включая major-релизы. ncu изменяет манифест, в то время как npm update изменяет node_modules.

Да. ncu работает с любым менеджером пакетов, так как изменяет только package.json. Запустите его с помощью pnpm dlx npm-check-updates или npx npm-check-updates независимо от вашего менеджера пакетов. После того как ncu обновит ваш package.json, используйте предпочитаемый менеджер пакетов для установки обновлённых зависимостей.

Используйте флаг reject с именем пакета или паттерном. Например, ncu --reject typescript исключает TypeScript из обновлений. Вы также можете использовать ncu --reject '/react.*/' для исключения нескольких пакетов, соответствующих паттерну. Это полезно для пакетов, которые вы хотите обновлять вручную.

Запуск ncu -u только изменяет package.json без установки чего-либо. Риск возникает при последующем запуске npm install без тестирования. Всегда запускайте набор тестов после обновления и установки. Начните с patch-обновлений, используя ncu -u --target patch для наиболее безопасного подхода.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay