Вы могли столкнуться с проблемами, когда npm install автоматически выбирал новую версию зависимости, которая нарушила вашу сборку. Возможно, вы также слышали об инциденте, когда программист удалил несколько пакетов npm, от которых зависели миллионы людей. К счастью, есть некоторые передовые методы, которые мы можем применить, чтобы свести к минимуму воздействие внешних факторов.

стандарт управления версиями npm

Пакеты npm следуют формату управления версиями major.minor.patch (например, 7.3.4). Хотя сами числа произвольны, как они меняются:

  • ОСНОВНЫЕ версии обновляются, когда совершается капитальный ремонт существующих интерфейсов. Это часто влечет за собой обратную несовместимость. Если вы зависите от зависимости, от которой вы обновляете основные версии, вам, возможно, придется изменить свой код.
  • Версии MINOR обновляются, когда в продукт добавляются новые функции или API. Поскольку существующие интерфейсы не изменяются обратно несовместимым образом, вы можете безопасно перейти на младшую версию без изменения кода.
  • Версии PATCH обновляются при внесении исправлений или изменений в реализацию, несущественных для пользователей. Вы почти всегда можете без проблем обновить версии патчей.

Если вы хотите узнать больше об этом протоколе управления версиями, вы можете прочитать о нем на сайте semver.org.

Разобравшись с версиями пакетов npm, давайте начнем с очевидной передовой практики управления версиями зависимостей.

Ограничить версии зависимостей

npm поддерживает токены, которые вы можете использовать вместе с версией зависимости, чтобы сообщить npm, в какие версии можно «автоматически» переходить. Вот самые важные токены:

  • Токен тильды (~): добавьте этот токен перед версией, чтобы ограничить версию зависимости до обновления только версий исправлений. Например, если вы укажете свою react зависимость в package.json как ~16.0.4, вы можете быть уверены, что останетесь на 16.0.x версиях.
  • Маркер каретки (^): добавьте эти маркеры перед версией, чтобы автоматически обновлять патч и второстепенные версии, но не основные. Ссылаясь на пример react, если вы указали ^16.0.4 в качестве зависимости в вашем package.json, разрешено автоматическое обновление в диапазоне 16.x.x, но вы никогда не перейдете к версиям ≥ 17.x.x.
  • Операторы ≥, ›, ≤,‹: вы также можете использовать операторы неравенства, чтобы объявить вашу верхнюю или нижнюю границу зависимости. Однако помните, что ≥, ›объявляют только нижнюю границу, и вы будете автоматически обновлены до новых основных версий.

В качестве быстрого совета вы также можете использовать эти токены в командной строке при установке зависимостей! Например, если вы устанавливали react и хотели ограничиться версиями 16.x.x, вы можете выполнить следующую команду

npm install --save react@^16

В момент написания это установит для вас [email protected] и вставит это в ваш package.json файл:

"react": "^16.13.1"

Фиксация вашего package-lock.json

package-lock.json является высшим источником истины; npm генерирует этот файл после npm install, сообщая вам, какие именно версии зависимостей были установлены - и зависимости этих зависимостей!

Хотя вы можете управлять прямыми версиями зависимостей, которые хотите использовать, вы не можете контролировать, какие зависимости используют эти зависимости (если это имеет смысл).

Однако package-lock.json может служить моментальным снимком точной установки, которую вы выполнили, когда ваша сборка работала. Если вы управляете версиями этого файла, вы всегда можете переустановить те же самые версии всех зависимостей! Вот цитата из документации npm по блокировкам пакетов.

Чтобы предотвратить эту потенциальную проблему, npm использует package-lock.json или, если есть, npm-shrinkwrap.json. Эти файлы называются блокировками пакетов или файлами блокировки.

Этот файл описывает точное и, что более важно, воспроизводимое node_modules дерево. Как только он появится, любая будущая установка будет основывать свою работу на этом файле, а не на пересчете версий зависимостей на основе package.json.

Бонус: что делать, если npm не работает?

Это серьезная проблема. Что делать, если репозиторий npm не работает? Любые и все команды npm, зависящие от подключения к репозиторию npm, завершатся ошибкой. Это не должно представлять угрозы для вашей производственной среды, поскольку файлы и зависимости в производственных сборках должны быть статичными. Но для сборок для разработки вы можете регулярно использовать npm install.

Если на ваш вариант использования серьезно повлияет даже несколько часов простоя, вы можете рассмотреть возможность архивирования и хранения всего node_modules дерева, чтобы вы никогда не зависели от репозитория npm.