Менеджеры пакетов  —  это инструменты, которые помогают управлять дополнительными битами и частями (зависимостями), необходимыми для создания программного обеспечения.

Наиболее популярными менеджерами пакетов являются NPM и YARN. Меньшую известность получил пока PNPM.

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


Менеджеры пакетов JavaScript

При разработке Node-приложения используются определенные зависимости: дополнительные библиотеки, помощники и другие инструменты. Допустим, вы работаете над React-проектом. Чтобы добавить в него маршрутизацию, надо установить пакет react-router-dom. Приложение может использовать и множество других пакетов. Для управления ими внутри среды выполнения Node.js требуется менеджер пакетов.

По умолчанию у JS-разработчиков есть node package manager, который поставляется в комплекте с установкой Node.js. Но он может не удовлетворить все требования проекта.

Поэтому стоит рассмотреть другие варианты менеджеров пакетов для Node.js, их преимущества и недостатки.


Какие задачи решает менеджер пакетов?

  • Управление зависимостями: менеджеры пакетов занимаются установкой и управлением зависимостями, обеспечивая корректность версий и доступность этих зависимостей для проекта.
  • Установка: менеджеры пакетов устанавливают утилиты для выполнения самых разных процессов  —  от предоставления команд для загрузки до управления, оценки уязвимостей и безопасности на локальном компьютере.
  • Скрипты и команды: дополнительные команды могут быть определены в файле package.json для упрощения общего процесса разработки  —  запуска сервера, проведения тестов, сборки активов и т. д. (выполняются через инструмент командной строки менеджера пакетов).
  • Безопасность: менеджеры пакетов часто предоставляют инструменты для сканирования пакетов на наличие известных уязвимостей (например, npm audit), а также предусматривают другие аспекты обеспечения безопасности, такие как фиксация зависимостей, подтверждение подписи и проведение верификации пакетов.

NPM

NPM (Node Package Manager)  —  это стандартный менеджер пакетов для JavaScript-приложений, поставляемый в комплекте при установке Node. NPM является наиболее популярным менеджером пакетов благодаря своей широкой поддержке.

Проблемы, свойственные ранним версиям NPM:

  • Отсутствие поддержки lock-файла. Это означало, что в менеджере пакетов не хранились точные данные о версиях зависимостей, используемых в приложении. Отсутствие контроля версий часто приводило к проблемам совместимости, так как в разных средах могли использоваться разные версии зависимостей.
  • Использование разных версий пакетов на разных компьютерах. Такая гибкость приводила к критическим изменениям, поскольку разработчики полагались на функции или поведение, которые предусматривались в одних версиях и отсутствовали в других.

Позже, когда Yarn исправил эти проблемы, NPM также устранил их в обновленных версиях.


Как работает NPM

  1. В централизованном реестре NPM хранятся тысячи пакетов. Эти пакеты могут быть библиотеками, фреймворками, помощниками, утилитами или инструментами. При запуске npm install перечисленные пакеты загружаются из реестра NPM в файл package.json.
  2. После загрузки зависимостей NPM генерирует lock-файл (package-lock.json). В этом файле указаны точные версии всех зависимостей (прямых и транзитивных), загруженных для разработки проекта. Он действует как детерминированный протокол, гарантирующий, что при будущих установках, даже на разных компьютерах, будут загружаться одинаковые версии.
  3. Если lock-файл отсутствует или удален, то NPM попытается загрузить последнюю совместимую версию, которая удовлетворяет диапазонам версий, указанным в файле package.json. В этих диапазонах используются семантические соглашения о версиях (semver), такие как ^ (совместимые минорные версии), ~ (совместимые версии патчей) и точные номера версий (1.2.3).
  4. NPM использует вложенное дерево зависимостей, обеспечивая получение каждым пакетом точной версии своих зависимостей.

Ниже приведен снимок файла package-lock.json с данными пакета react-dom. Этот пакет включает зависимость под названием scheduler, которая будет загружена автоматически вместе с установкой react-dom. Однако react-dom также содержит одноранговые зависимости, которые необходимы для его функциональности, но не будут загружаться NPM автоматически. Ожидается, что эти одноранговые зависимости будут присутствовать, способствуя работе пакета.

Package-lock.json REACT-DOM

Примечание. Обычно рекомендуется сохранять lock-файл (package-lock.json или yarn.lock), так как он обеспечивает детерминированную установку и воспроизводимость сред.


Теперь рассмотрим плюсы и минусы NPM.

Плюсы

  • Обширная поддержка. NPM содержит крупнейший в мире реестр пакетов JavaScript.
  • Облегченное управление зависимостями. NPM автоматизирует процесс поиска, установки и управления зависимостями наиболее упрощенным способом.
  • Простота использования. NPM прост в настройке и использовании, что делает его доступным для разработчиков любого уровня подготовки.

Минусы

  • Потребность в большом пространстве на диске. Поскольку NPM использует подход вложенного дерева зависимостей для сохранения пакетов, ему требуется больше дискового пространства для сохранения нескольких копий одного и того же пакета, если они требуются разным зависимостям.
  • Раздувание зависимостей. Если зависимости/пакеты не управляются должным образом в долгосрочной перспективе, может накопиться большое количество ненужных пакетов, что чревато увеличением размера проекта и проблемами с совместимостью.
  • Недостаточная производительность. По сравнению с другими менеджерами пакетов, NPM выполняет установку пакетов медленнее, особенно при использовании его в крупном проекте с большим количеством зависимостей. Это связано с тем, что NPM последовательно загружает пакеты.

YARN

Вы тоже думаете, что YARN расшифровывается как “yet another resource negotiator” (еще одна/новая/альтернативная система управления ресурсами)? Честно говоря, мне так и не удалось найти вразумительного ответа на этот вопрос.

Как упоминалось выше, Yarn  —  менеджер пакетов для Node-проектов, разработанный Facebook для решения проблем, имевшихся у NPM, который в то время не указывал точную версию зависимостей и не поддерживал lock-файл.

Принцип работы YARN очень напоминает NPM, но в некоторых аспектах YARN предоставляет больше преимуществ.

Рассмотрим основные команды этого менеджера пакетов.

Как работает YARN

  1. Сначала используется команда yarn init для инициализации проекта с помощью YARN, которая создаст файл package.json в проекте.
  2. Команда yarn add <имя_пакета> позволит добавить любой пакет.
  3. Если нужно установить зависимости в предварительно настроенный проект, команда yarn install загрузит все зависимости из реестра NPM и сгенерирует lock-файл.

Плюсы

  • Более быстрая установка. В отличие от NPM, YARN устанавливает пакеты параллельно, что позволяет сократить время установки.
  • Поддержка оффлайн. YARN работает быстрее также за счет реализации локального кэширования. Он хранит кэши пакетов в глобальном месте, которое затем может совместно использоваться различными проектами, что делает его быстрее, а также обеспечивает поддержку оффлайн, которой нет в NPM. Команда yarn cache dir позволяет узнать, в каком каталоге YARN хранит кэши пакетов.
  • Экономное использование дискового пространства. YARN задействует плоскую структуру зависимостей, которая позволяет избежать дублирования и вложенности пакетов, что приводит к минимальному использованию места на диске.
  • Поддержка монорепозитория. Разработчики YARN предусмотрели поддержку монорепозитория с помощью функции Yarn Workspaces. Монорепозиторий  —  это репозиторий, единый для нескольких пакетов, каждый из которых имеет свой package.json. Yarn Workspaces упрощает управление зависимостями, позволяя устанавливать зависимости для всех пакетов из центрального места.

Минусы

  • Менее развитая экосистема. Хотя популярность YARN набирает обороты, у NPM более долгая история и более широкое сообщество.
  • Ограниченная поддержка нативных модулей. YARN может быть несовместим с некоторыми функциями или пакетами, которые ориентированы на специфические функции NPM.
  • Зависимость от реестра NPM. Несмотря на эффективное управление зависимостями, YARN зависит от реестра NPM для загрузки пакетов. Это означает, что возникающие в NPM проблемы могут косвенно отразиться и на YARN.

PNPM

PNPM расшифровывается как “performant NPM” (высокопроизводительный NPM). Он разработан для решения проблем, возникающих при работе с YARN и NPM.

После установки PNPM можно использовать команды, аналогичные командам NPM и YARN.

  • pnpm init: инициализирует новый проект, аналогично npm init или yarn init.
  • pnpm install <имя_пакета>: устанавливает пакет и его зависимости.
  • pnpm list: составляет список пакетов, установленных в проекте.
  • pnpm remove <имя_пакета>: удаляет пакет.
  • pnpm run <имя_скрипта>: запускает скрипт, определенный в файле package.json.

Плюсы

  • Эффективное использование места на диска. В отличие от NPM и YARN, в PNPM используется подход глобального хранилища, при котором все пакеты хранятся глобально в одном месте. При установке пакета PNPM связывает файлы из глобального хранилища с node_modules проекта, поэтому не нужно хранить пакеты для каждого приложения отдельно, что делает PNPM эффективным с точки зрения использования места на диске.
  • Lock-файл. Несмотря на то, что pnpm использует неплоскую внутреннюю структуру, он предоставляет “плоское представление” зависимостей через lock-файл (часто называемый pnpm-lock.yaml).
  • Скорость и легкость. PNPM быстрее и легче, чем NPM и YARN, поскольку использует кэширование и не устанавливает пакеты каждый раз. Если пакет находится глобально, символические/жесткие ссылки прикрепляются в node_module этого проекта/приложения.

Минусы

  • Новый игрок на рынке. Хотя PNPM быстрее, чем NPM и YARN, не так много людей знают о нем, поскольку, в отличие от своих конкурентов, он недавно появился на рынке.
  • Ограниченная поддержка нативных модулей. Могут возникнуть проблемы с совместимостью с нативными модулями, которые ориентируются на функциональность, специфичную для NPM.
  • Зависимость от глобального хранилища. Глобальное хранилище пакетов в pnpm дает преимущества в плане эффективности, но также может создавать потенциальные накладные расходы на управление. Например, вам придется подумать над решением таких задач, как очистка глобального хранилища и управление конфликтами, если нескольким проектам требуются разные версии одного и того же пакета.

Выбор правильного инструмента

Вот краткое руководство, которое поможет вам решить, какой менеджер пакетов выбрать.

  • Скорость и эффективность. Если скорость установки и минимальное использование места на диске являются главными приоритетами, PNPM  —  отличный выбор, особенно для больших проектов.
  • Для устоявшихся экосистем. Если вам нужен доступ к более широкому сообществу и огромному количеству ресурсов, NPM может оказаться более подходящим вариантом благодаря своей более длительной истории и большой базе пользователей.
  • Для сложных нативных модулей. Если проект сильно зависит от нативных модулей, NPM и YARN могут предложить лучшую совместимость из-за их более длительного опыта работы в этой области.

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

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Neha Gupta: NPM, PNPM, YARN Package Managers

Предыдущая статьяЗачем нужен CORS: просто о сложном
Следующая статьяОсвоение безопасной для типов JSON-сериализации в TypeScript