Всем привет! Я уверен, что вы видели использующие разные менеджеры пакетов, например: проекты Node.js, (по умолчанию) npm пряжа пнпм Я видел это сам и работал со всем вышеперечисленным, но у меня всегда был вопрос: что заставляет людей/команды использовать или вместо ? Каковы плюсы? Есть ли минусы? Yarn pnpm npm Что ж… Давайте узнаем! Правила сравнения производительности Я решил сравнить , и с точки зрения их «скорости»… npm Yarn pnpm Ниже вы увидите 3 меры: Создайте файл блокировки без кэша. Установите зависимости из существующих файлов блокировки без кэша. Установите зависимости из существующих файлов блокировки с глобальным кешем. Существует два типа кэша: Глобальный. Обычно хранится в домашнем каталоге пользователя (fe, ). ~/.yarn/berry/cache Местный. Хранится в каталоге проекта (fe, ). <project-dir>/.yarn Хотя, по моему опыту, наиболее распространенными вариантами использования являются и , на всякий случай я также выбрал (хотя это очень редкий случай). № 2 № 3 № 1 В качестве примера для тестов я использовал пример проекта из . create-react-app НПМ Это менеджер пакетов по умолчанию для экосистемы — что еще сказать? Он поставляется с установочным пакетом, поэтому он практически готов к использованию при установке на свой компьютер (или в любом поставщике , если вы там настроили ). Node.js Node.js CI Node.js На мой взгляд, это огромный плюс – вам не нужно устанавливать его отдельно! Ничего выдающегося, просто… работает! И за прошедшие годы я не заметил каких-либо серьезных ошибок — он кажется довольно стабильным и выполняет свою работу. Возможности которые я использовал до сих пор: npm, Управление зависимостями (установка, удаление, обновление) Публикация пакетов (частных, общедоступных) Ссылка на локальные пакеты Управляйте рабочими пространствами. Управление зависимостями хранит зависимости в папке в корне вашего проекта. Довольно просто. npm node_modules ℹ️ хранит информацию о реестрах для перечисленных пакетов — это удобно, если у вас есть пакеты из одной области, т.е. в разных реестрах (например — & ): package-lock.json ОЧЕНЬ @example-company npm GitHub Packages Теперь давайте посмотрим, как он работает с точки зрения скорости установки… Создать package-lock.json без кеша Потребовалось чтобы сгенерировал и установил зависимости без кеша. 1 минута npm package-lock.json Используемая команда: npm i Установите зависимости из package-lock.json без кеша Потребовалось для для установки зависимостей из без кеша. 18 секунд npm package-lock.json Используемая команда: npm ci Установите зависимости из package-lock.json с глобальным кешем Потребовалось для для установки зависимостей из с глобальным кешем. 8 секунд npm package-lock.json Используемая команда: npm ci Управление рабочими пространствами Мне удалось создать и управлять зависимостями для всего рабочего пространства сразу и для конкретных проектов отдельно. рабочее пространство Другими словами, он выполняет свою работу без каких-либо ошибок/проблем, а официальная документация довольно проста. Функции рабочей области, которые я использовал до сих пор: Установите зависимости для всех проектов в рабочей области. Установите зависимости для одного конкретного проекта. Рекурсивно запускайте один скрипт для всех проектов одновременно. пряжа Честно говоря, некоторые особенности я особо не пробовала. Я имею в виду, что я много использовал его в плане «установки зависимостей» при работе над некоторыми проектами, и все. пряжи В комплект поставки не входит установщик , поэтому вам придется установить его отдельно. Это означает, что в ваших конвейерах будет дополнительный шаг — вам придется настроить перед установкой зависимостей проекта. Yarn Node.js CI пряжу Управление зависимостями есть два подхода к установке зависимостей: В Yarn « » (по умолчанию) — создает папку и перечисляет пакеты в файлах и . Нулевые установки .yarn yarn.lock .pnp.cjs Обычный, аналогичный , сохраняет зависимости в и перечисляет их в файле . npm node_modules yarn.lock ℹ️ файлы блокировки хранят информацию о реестрах для всех перечисленных пакетов если вы используете старый (обычный) подход к установке. пряжи ТОЛЬКО ⚠️ Имейте в виду, что « », похоже, хранят пакеты в локальном кеше и предоставляют ссылки на ваши файлы блокировки: Нулевые установки Это может быть важно для вас, если у вас есть или -конвейер, в котором вы устанавливаете зависимости в одну чистую среду, а затем хотите переместить их в другую (вам придется скопировать и папку , и локальный кеш). Dockerfile CI .yarn Поскольку подход по умолчанию для Yarn сейчас — « » и имеет лучшую производительность, чем старый подход — мы собираемся записывать тесты только с этим подходом. Нулевые установки Генерировать файлы блокировки без кэша Потребовалось чтобы сгенерировал файл и установил зависимости без кеша. 16,5 секунд Yarn yarn.lock Используемая команда: yarn install Установите зависимости из существующих файлов блокировки без кэша Потребовалось для для установки зависимостей с использованием подхода «Zero Install» и без какого-либо кеша. 11 секунд Yarn Используемая команда: yarn install --frozen-lockfile Установите зависимости из существующих файлов блокировки с помощью глобального кэша Потребовалось для для установки зависимостей с использованием подхода «Zero Install» и глобального кеша. 8 секунд Yarn Используемая команда: yarn install --frozen-lockfile Управление рабочими пространствами Мне удалось создать и управлять зависимостями для всех проектов сразу и для конкретных проектов отдельно. рабочее пространство Функции рабочей области, которые я использовал до сих пор: Установите зависимости для всех проектов в рабочей области. Установите зависимости для одного конкретного проекта. Рекурсивно запускайте один скрипт для всех проектов одновременно. Документация хорошая, но имена и флаги команд несколько сбивают с толку. Например, мне нужно выполнить это, чтобы запустить скрипт в ( ) и вложенном проекте : test корневом . b2b yarn workspaces foreach -A --include '{.,b2b}' run test По сравнению с : npm npm run test --workspace=b2b --include-workspace-root пнпм сейчас на хайпе — . pnpm его используют множество компаний и проектов с открытым исходным кодом Как и в случае с , не поставляется с установщиком , поэтому его придется устанавливать отдельно. Это означает, что в ваших конвейерах будет дополнительный шаг — вам придется настроить перед установкой зависимостей проекта. Yarn pnpm Node.js CI pnpm Управление зависимостями считается … pnpm « » быстрым менеджером пакетов, эффективно использующим дисковое пространство Действительно, я согласен с утверждением с точки зрения локального управления зависимостями. об «эффективном дисковом пространстве» По умолчанию устраняет дубликаты общих зависимостей. создает символические ссылки для пакетов, которые используются в нескольких зависимостях. т. е. если пакеты и используют пакет в качестве зависимости, сохранит пакет как одну копию и создаст символические ссылки для пакетов и . Таким образом, менеджер пакетов не создает бумажные копии и экономит память на вашем SSD/HDD. pnpm pnpm a b c pnpm c a b ℹ️ не хранит информацию о реестрах для перечисленных пакетов. pnpm-lock.yaml ⚠️ Имейте в виду, что иногда хранит зависимости в глобальном кеше, а не как проект. pnpm Создать pnpm-lock.yaml без кеша Потребовалось чтобы сгенерировал и установил зависимости без кэша. 31 секунда pnpm pnpm-lock.yaml Используемая команда: pnpm install Установите зависимости из pnpm-lock.yaml без глобального кэша Потребовалось для для установки зависимостей из без кеша. 16 секунд pnpm pnpm-lock.yaml Используемая команда: pnpm i --frozen-lockfile Установите зависимости из существующего файла блокировки с глобальным кешем Потребовалось для для установки зависимостей из с глобальным кешем. 5 секунд pnpm pnpm-lock.yaml Используемая команда: pnpm i --frozen-lockfile Управление рабочими пространствами Вот тут-то всё и становится по-настоящему интересным… имеет множество опций конфигурации, но некоторые основные функции просто не работают! pnpm Давайте рассмотрим пару ошибок, с которыми я столкнулся: pnpm установить --фильтр Важно иметь возможность устанавливать зависимости только для конкретных проектов — это весьма полезно для монорепозиториев, когда вы создаете конвейеры, связанные с конкретными проектами в рабочей области. т. е. представьте, что в вашем рабочем пространстве есть: веб-приложение, внутренний сервер, тестовый проект (сквозные тесты). Все это отдельные проекты , но они являются частью одного репо ☝️ npm Теперь вам нужно, чтобы конвейер запускал только сквозные тесты. Итак, вам нужны только сквозные тестовые зависимости, верно? Ну, вы не сможете этого сделать — заставляет вас устанавливать зависимости для всей рабочей области! pnpm должен был устанавливать зависимости только для выбранных проектов, но это не работает. pnpm install --filter <project-name> Это ошибка годичной давности, и недавно она была закрыта с нерабочим исправлением. рекурсивная установка = false по умолчанию устанавливает зависимости для всей рабочей области (всех проектов) при запуске pnpm pnpm install Вы можете изменить это поведение, если установите в в корне вашего рабочего пространства. recursive-install=false .npmrc НО . это вводит еще одну ошибку, которой уже почти 2 года файл общей рабочей области-lockfile = false по умолчанию хранит список зависимостей в одном файле блокировки (так же, как и ). pnpm npm Yarn Вы также можете изменить это поведение, если в в корне вашего рабочего пространства. shared-workspace-lockfile=false .npmrc Это позволило бы нам сохранить функцию рабочей области и использовать флаг для установки зависимостей для конкретного проекта. --ignore-workspace В любом случае, этот параметр создает еще несколько проблем: и выдают ошибку в моих конвейерах . eslint tsc --noEmit «JavaScript Heap Out of Memory» действий GitHub Некоторые зависимости хранятся в глобальном кеше и имеют символические ссылки в . node_modules/.pnpm Результаты сравнения производительности # НПМ пряжа пнпм Создать файл блокировки 60 секунд 16,5 сек. 31 секунда Установить зависимости без кеша 18 секунд 11 секунд 8 секунд Установите зависимости с глобальным кешем 8 секунд 8 секунд 5 секунд Согласно приведенному выше тесту, — самый медленный менеджер пакетов ☝️ npm В любом случае, давайте интерпретируем эти результаты… Создать файл блокировки Это редкий случай. Обычно файл блокировки создается при инициализации проекта, а затем расширяется при установке/обновлении пакетов. Учитывая это, кажется, что при выборе менеджера пакетов не так уж важно полагаться на него. Установить зависимости В большинстве случаев ваши проекты хранят определенный список зависимостей, и вы редко что-то добавляете/удаляете. Скорее всего, вы будете время от времени обновлять версии своих пакетов — эти изменения невелики, и вы будете повторно использовать остальные пакеты из кеша. Другими словами, общий вариант использования — получение новых пакетов из реестра пакетов и получение остальных из кеша. (5-8 сек) почти в два раза быстрее, чем (8-18 сек) с (8-11 сек) посередине. pnpm npm пряжей Заключение Факты действительно является менеджером пакетов — в текущем обзоре это совершенно ясно! pnpm «быстрым и экономичным» В функции рабочего пространства есть ошибки, и некоторые из них не устраняются уже много лет. pnpm И , и требуют дополнительной настройки в конвейерах CI, а — нет. pnpm Yarn npm И , и не хранят информацию о реестре пакетов в своих файлах блокировки, в то время как это делает. pnpm Yarn npm Мысли автора Я думаю, что лучше всего справляется со своей задачей, если ваши требования к менеджеру пакетов такие же простые, как «устанавливать только зависимости». pnpm Несмотря на то, что не поставляется с готовым установщиком , его легко настроить в конвейерах CI с помощью или . pnpm Node.js Corepack существующих действий Я предпочитаю , потому что: npm он стабилен (особенно рабочие области), поставляется с и не требует дополнительной настройки в конвейере CI, Node.js хранит реестры пакетов в , поэтому вы можете устанавливать зависимости с одной областью из разных реестров. package-lock.json Эти плюсы перевешивают секунды скорости и дискового пространства, которые я бы сэкономил с помощью или . Yarn pnpm Каковы ваши критерии выбора пакетного менеджера? Не стесняйтесь и дайте мне знать свои мысли в разделе комментариев ниже! 👇😊