Руководство по использованию pnpm

Как разработчик Node.js, вы наверняка слышали оnpmиyarn, это мощные инструменты для управления зависимостями проекта. Но сталкивались ли вы когда-нибудь сnode_modulesразочарованием от огромных папок, медленной скорости установки или быстрого заполнения дискового пространства? Это проблема, которую может решить pnpm.

pnpm— это быстрый, экономичный по дисковому пространству менеджер пакетов Node.js. Он хранит пакеты, используя контентную адресацию, при этом все версии зависимостей хранятся централизованно в одном месте в системе, а затем связываются с проектами через жесткие ссылки, избегая дублирования установок.

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


Установка pnpm

Существует несколько способов установки pnpm; вы можете выбрать подходящий в зависимости от ваших предпочтений и системного окружения.

Способ 1: Установка через npm (рекомендуется для всех пользователей)

Это самый универсальный и простой способ. Откройте терминал (пользователи Windows могут использовать PowerShell или CMD) и выполните следующую команду:

npm install -g pnpm

Эта команда установит pnpm в вашу глобальную среду через npm.

Проверьте, успешно ли прошла установка: после установки выполните следующую команду, чтобы проверить версию. Если номер версии отображается нормально, установка прошла успешно.

pnpm --version

Вывод примерно такой: 8.15.0

Способ 2: Установка с помощью автономного скрипта

Для пользователей macOS или Linux можно установить с помощью следующего скрипта:

# macOS/Linux
curl -fsSL https://get.pnpm.io/install.sh | sh -

# Windows (PowerShell)
iwr https://get.pnpm.io/install.ps1 -useb | iex

Использование pnpm

Теперь, когда вы узнали, как его установить, давайте начнём собственно использовать pnpm. Дизайн его команд очень интуитивен; если вы знакомы с npm, вы сможете переключиться почти без проблем.

Инициализация нового проекта

Похоже наnpm init, pnpm можно использовать для инициализации проекта и созданияpackage.jsonфайл.

# 交互式地回答问题,创建 package.json
pnpm init

# 快速创建一个带有默认值的 package.json
pnpm init -y

Запуститеpnpm init -yПосле этого вы получите очень простойpackage.jsonфайл:

Пример

{
  "name": "имя-вашего-проекта",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Ошибка: тест не указан\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Установите зависимости

команда установки pnpm — этоpnpm add <package-name>, что эквивалентноnpm install <package-name>。

# 安装所有依赖
pnpm install

# 添加依赖包
pnpm add <package-name>

# 添加开发依赖
pnpm add -D <package-name>

# 添加全局包
pnpm add -g <package-name>

# 安装指定版本
pnpm add <package-name>@<version>

Обновить зависимости

# 更新所有依赖
pnpm update

# 更新指定包
pnpm update <package-name>

# 更新到最新版本(忽略 package.json 中的版本范围)
pnpm update --latest

Удалить зависимости

pnpm remove <package-name>

Запуск скриптов

# 运行 package.json 中定义的脚本
pnpm run <script-name>
# 一些常见的简写
pnpm start
pnpm test
pnpm build

Таблица сравнения команд npm и pnpm

команда npm команда pnpm
npm install pnpm install
npm install <pkg> pnpm add <pkg>
npm install <pkg> --save-dev pnpm add -D <pkg>
npm install <pkg> --global pnpm add -g <pkg>
npm update pnpm update
npm uninstall <pkg> pnpm remove <pkg>
npm run <script> pnpm run <script>
npx <command> pnpm dlx <command>
npm list pnpm list
npm outdated pnpm outdated
npm audit pnpm audit

Файл конфигурации

pnpm поддерживает настройку через файл.npmrc.

Создание этого файла в корневом каталоге проекта позволяет настроить поведение pnpm.

Примеры распространённых конфигураций

# 设置国内镜像源(淘宝)
registry=https://registry.npmmirror.com

# 自动安装 peer dependencies
auto-install-peers=true

# 严格模式
strict-peer-dependencies=true

# shamefully-hoist(提升依赖,兼容某些工具)
shamefully-hoist=true

# 指定 node_modules 目录结构
node-linker=hoisted

# 设置存储目录
store-dir=~/.pnpm-store

Просмотр текущей конфигурации

pnpm config list

Установка параметров конфигурации:

pnpm config set <key> <value>

Рабочее пространство

pnpm имеет встроенную мощную поддержку монорепозиториев.

Определите рабочее пространство, создав файл pnpm-workspace.yaml в корневом каталоге проекта.

Пример конфигурации:

packages:
  - 'packages/*'
  - 'apps/*'
<p>  - '!**/test/**'
Пример структуры проекта:
my-monorepo/
├── pnpm-workspace.yaml
├── package.json
├── packages/
│   ├── package-a/
│   │   └── package.json
│   └── package-b/
│       └── package.json
└── apps/
    └── web-app/
        └── package.json

Команды рабочего пространства

# 在所有工作区包中安装依赖
pnpm install

# 在指定工作区执行命令
pnpm --filter <package-name> <command>

# 在所有工作区执行命令
pnpm -r <command>

# 递归运行脚本
pnpm -r run build

# 为工作区添加依赖
pnpm --filter <package-name> add <dependency>

# 添加工作区内部依赖
pnpm --filter package-a add package-b@workspace:*

Протокол рабочего пространства

При ссылке на другие пакеты внутри рабочего пространства используйте протокол workspace:

json{
  "dependencies": {
    "package-a": "workspace:*",
    "package-b": "workspace:^1.0.0"
  }
}

Расширенные возможности

pnpm exec и pnpm dlx

# 执行本地安装的包
pnpm exec <command>

# 执行远程包(类似 npx)
pnpm dlx create-react-app my-app

# 使用特定版本
pnpm dlx create-react-app@latest my-app

Просмотреть дерево зависимостей

# 查看依赖树
pnpm list

# 指定深度
pnpm list --depth 2

# 只显示生产依赖
pnpm list --prod

# 查看全局包
pnpm list -g

Просмотр устаревших зависимостей

pnpm outdated

Аудит безопасности зависимостей

pnpm audit

# 自动修复安全问题
pnpm audit --fix

Очистить кэш

# 清理未使用的包
pnpm store prune

# 查看存储位置
pnpm store path

# 查看存储状态
pnpm store status

Импорт lockfile

При миграции с других менеджеров пакетов:

# 从 package-lock.json 导入
pnpm import

# 从 yarn.lock 导入
pnpm import

Патчинг пакетов

Когда необходимо временно изменить пакет зависимости:

# 创建补丁
pnpm patch <package-name>@<version>

# 应用补丁后提交
pnpm patch-commit <path>

Что такое pnpm? Каковы его ключевые преимущества?

Прежде чем углубляться в использование, нам сначала нужно понять основную философию pnpm и изменения, которые она приносит.

pnpm (Performant npm)— это менеджер пакетов Node.js, обратно совместимый с npm, а это значит, что подавляющее большинствоnpmкоманд вpnpmможно использовать напрямую.

Цель дизайна pnpm — решить узкие места традиционных менеджеров пакетов (таких как npm и yarn) в дисковом пространстве и скорости установки.

Проблемы традиционных менеджеров пакетов

Представьте, что вы работаете над 10 разными фронтенд-проектами в своей компании, и каждый проект зависит от[email protected]. При использовании npm или yarn этотlodashпакет будет полностью скачан и сохранён 10 раз, в 10 разныхnode_modulesпапках на вашем компьютере. Это приводит к огромной трате дискового пространства.

Революционный подход pnpm: хранилище с адресацией по содержимому и жёсткие ссылки

pnpm использует умный подход:

  1. Глобальное хранилище: Когда вы устанавливаете пакет, pnpm сохраняет его содержимое вглобальном репозитории с одной версией(обычно расположенном в~/.pnpm-store)。
  2. Жёсткие ссылки: В вашем проектеnode_modulesв, pnpm не копирует полные файлы пакета, а создаётжёсткие ссылки. Можно представить жёсткую ссылку как "продвинутый ярлык"; она использует те же данные на диске, что и оригинальный файл.
  3. Организация символических ссылок: Чтобы поддерживатьnode_modulesплоская структура (чтобы облегчитьrequireинструкции), pnpm создаёт сложный наборсимволических ссылок(мягких ссылок) для организации дерева зависимостей.

Благодаря этому механизму,сколько бы проектов ни зависело от одного и того же пакета, на физическом диске сохраняется только одна копия пакета.. Это даёт немедленные преимущества:

  • Экономит большой объём дискового пространства: Для разработчиков с несколькими проектами экономия чрезвычайно значительна.
  • Чрезвычайно высокая скорость установки: При последующих установках, если пакет уже существует в глобальном хранилище, pnpm нужно только создать ссылки, что на порядки быстрее, чем загрузка и распаковка.
  • Повышенная безопасность:node_modulesФайлы пакетов в нём доступны только для чтения (поскольку они являются жёсткими ссылками), что позволяет избежать риска случайного изменения содержимого пакетов зависимостей скриптами проекта и обеспечивает детерминированность зависимостей.

На рисунке выше наглядно показан основной рабочий процесс pnpm: все проекты совместно используют один и тот же файл пакета в глобальном хранилище через жёсткие ссылки, а затем в своих соответствующихnode_modulesкаталогах структура зависимостей строится с помощью символических ссылок.

Сравнение возможностей npm (v7+) / yarn pnpm
Использование дискового пространства Зависимости для каждого проекта хранятся независимо, занимая большой объём пространства. Все проекты совместно используютодну копию, что обеспечивает чрезвычайно низкое использование пространства.
Скорость установки Медленнее; требуется загрузка, распаковка и построение дерева зависимостей. Чрезвычайно быстро, особенно для последующих установок, которые в основном сводятся к созданию ссылок.
node_modulesСтруктура Плоская или полуплоская, что может приводить к поднятию зависимостей и проблемам с фантомными зависимостями. Строгаянеплоская структура, точно имитирующая связи зависимостей и устраняющая фантомные зависимости.
Поддержка монорепозиториев Поддерживается через Workspaces, но с узкими местами производительности. Нативная, эффективнаяподдержка Workspaces; производительность — его сильная сторона.
Модель управления пакетами Копирует файлы в проект во время установки. Модель ссылок (жёсткие ссылки + символические ссылки).
Безопасность Зависимости могут быть изменены скриптами проекта. Файлы зависимостей — это жёсткие ссылки, доступные только для чтения, что обеспечивает более высокий уровень безопасности.

Официальные ресурсы:

Другие расширения