Пакетные менеджеры: npm vs yarn vs pnpm
npm, yarn и pnpm — инструменты для установки, управления и публикации JavaScript-пакетов, каждый со своей стратегией хранения зависимостей и скоростью работы.
Зачем нужно
Пакетный менеджер автоматизирует загрузку библиотек из реестра (npmjs.com), фиксирует точные версии в lockfile и управляет скриптами проекта. Без него разработчики вручную загружали бы зависимости и не могли воспроизводить одинаковое окружение на разных машинах.
Где используется
- Установка зависимостей при клонировании проекта (
npm install) - Запуск скриптов: сборка, тесты, линтинг
- Monorepo-проекты с workspaces (yarn workspaces, pnpm workspaces)
- CI/CD пайплайны — кеширование node_modules для ускорения сборки
Сравнение
Характеристика npm yarn (classic) pnpm
─────────────────────────────────────────────────────────
Lockfile package-lock yarn.lock pnpm-lock.yaml
Хранение пакетов node_modules node_modules ~/.pnpm-store (symlinks)
Скорость ★★★ ★★★★ ★★★★★
Дисковое место много много мало (hard links)
Workspaces да да да (лучшая поддержка)
Phantoms deps да да нет (strict)
Основные команды
# Инициализация проекта
npm init -y
yarn init -y
pnpm init
# Установка всех зависимостей
npm install
yarn
pnpm install
# Добавление пакета
npm install express
yarn add express
pnpm add express
# Добавление devDependency
npm install --save-dev eslint
yarn add --dev eslint
pnpm add -D eslint
# Удаление пакета
npm uninstall express
yarn remove express
pnpm remove express
# Запуск скрипта из package.json
npm run build
yarn build
pnpm build # можно без run для стандартных скриптов
# Глобальная установка
npm install -g typescript
yarn global add typescript
pnpm add -g typescript
package.json scripts
{
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext .ts,.tsx",
"test": "vitest run",
"prepare": "husky"
}
}
Workspaces (monorepo)
// package.json корня monorepo
{
"name": "my-monorepo",
"private": true,
"workspaces": ["packages/*", "apps/*"]
}
# Установить зависимость в конкретный workspace
npm install lodash -w packages/utils
yarn workspace packages/utils add lodash
pnpm add lodash --filter packages/utils
# Запустить скрипт во всех workspace
npm run build --workspaces
pnpm -r run build
Lockfile — фиксация версий
# Никогда не удалять и всегда коммитить lockfile
git add package-lock.json() # npm
git add yarn.lock # yarn
git add pnpm-lock.yaml # pnpm
# Установить точно по lockfile (в CI)
npm ci # только npm
yarn install --frozen-lockfile
pnpm install --frozen-lockfile
Частые ошибки
- Смешивать менеджеры в одном проекте — разные lockfile конфликтуют. Выбрать один и задокументировать
- Не коммитить lockfile — разные разработчики получат разные версии транзитивных зависимостей
npm installв CI вместоnpm ci—npm ciиспользует lockfile строго и быстрее- Устанавливать production-зависимость через
--save-dev— попадает в не то поле package.json - pnpm: phantom dependencies — пакет доступен в коде, но не прописан в package.json (pnpm ловит это)