Глобальне віртуальне сховище

By default, pnpm creates a .pnpm directory inside each project's node_modules. This is the "virtual store". Тека містить жорсткі посилання на файли у сховищі з адресованим вмістом. Every project gets its own projection of this virtual store: pnpm hardlinks files from the content-addressable store into the .pnpm directory structure. Фактичний вміст файлів зберігається на диску лише один раз, але структура тек відтворюється для кожного проєкту, щоб алгоритм визначення модулів Node.js міг знайти потрібні залежності для кожного пакунка.

The global virtual store (virtualStoreType: global, spelled enableGlobalVirtualStore: true before v11.23.0) changes this. Замість того, щоб кожен проєкт мав власну теку node_modules/.pnpm, pnpm підтримує єдине спільне віртуальне сховище (розташоване в теці <store-path>/links/; щоб дізнатися, де саме знаходиться <store-path>, виконайте команду pnpm store path). Тека node_modules кожного проєкту містить лише символічні посилання, що ведуть до цього спільного місця.

Стандартна поведінка та глобальне віртуальне сховище#

Стандартна поведінка (віртуальне сховище для кожного проєкту)#

project-a/
└── node_modules/
    ├── lodash → .pnpm/lodash@4.17.21/node_modules/lodash
    └── .pnpm/
        └── lodash@4.17.21/
            └── node_modules/
                └── lodash/            ← жорсткі посилання на сховище з адресацією за вмістом
project-b/
└── node_modules/
    ├── lodash → .pnpm/lodash@4.17.21/node_modules/lodash
    └── .pnpm/
        └── lodash@4.17.21/
            └── node_modules/
                └── lodash/            ← ті самі жорсткі посилання, дубльована структура тек

Кожен проєкт має свою власну структуру .pnpm з жорсткими посиланнями. Вміст файлів на диску не дублюється (жорсткі посилання використовують спільні inodes), натомість структура тек дублюється. У разі великих монорепозиторіїв або великої кількості паралельних перемикань час, витрачений на створення тисяч жорстких посилань під час виконання команди pnpm install, стає значним.

Глобальне віртуальне сховище#

project-a/
└── node_modules/
    └── lodash → <global-store>/links/@/lodash/4.17.21/<hash>/node_modules/lodash
project-b/
└── node_modules/
    └── lodash → <global-store>/links/@/lodash/4.17.21/<hash>/node_modules/lodash  ← теж саме місце призначення

Обидва проєкти мають символічні посилання, що ведуть безпосередньо до одного й того самого місця у глобальному віртуальному сховищі. Немає структури .pnpm в кожному проєкті. The global virtual store itself contains the hardlinks to the content-addressable store, but that happens only once per dependency graph (more on that below), not per project.

Як працює ідентифікація пакунків#

У глобальному віртуальному сховищі кожна тека пакунка має імʼя, що відповідає хешу її графа залежностей. Два проєкти, які використовують lodash@4.17.21 з однаковим деревом транзитивних залежностей, вказуватимуть на одну й ту саму теку. Якщо дерева залежностей відрізняються (наприклад, мають різні прямі залежності) — pnpm створює окремі записи. Це концептуально схоже на те, як NixOS керує пакунками за допомогою хешів графів залежностей.

Коли використовувати глобальне віртуальне сховище#

The global virtual store is most useful when you have multiple checkouts of the same project on disk. For example, when using git worktrees for multi-agent development. У такому випадку кожне робоче дерево отримує node_modules, майже без накладних витрат, оскільки весь реальний вміст пакунка вже існує у спільному сховищі.

Це також прискорює процес встановлення для різних проєктів на одній машині, оскільки будь-яка версія пакунка, яка вже була встановлена будь-яким проєктом, стає доступною миттєво.

Обмеження#

  • Середовища неперервної інтеграції: У середовищах неперервної інтеграції кеші зазвичай відсутні, тому немає готового глобального сховища, яким можна було б скористатися. Глобальне віртуальне сховище, як правило, не використовується в CI.
  • Shared trust domain: The global virtual store and the content-addressable store are shared writable state. Use them only for projects, users, and jobs that trust each other, and protect the store path with filesystem permissions.
  • ESM hoisting: pnpm uses the NODE_PATH environment variable to support hoisted dependencies with the global virtual store, and Node.js does not respect NODE_PATH for ESM imports. Since v11.23.0, every process pnpm spawns for the project (pnpm run, pnpm exec, lifecycle scripts, and the tools pnpm dlx runs) also gets a NODE_OPTIONS --import flag registering a resolve hook that restores those lookups, so a dependency importing a package it does not declare resolves under ESM too (#9618). A node process started outside pnpm does not get that environment, and setting extendNodePath to false turns the whole NODE_PATH mechanism off, resolve hook included; declare the missing dependencies with packageExtensions if you need them to resolve in either case.

нотатка

Наразі глобальне віртуальне сховище зазвичай вимкнено для встановлень проєктів і позначено як експериментальне, оскільки деякі інструменти можуть працювати некоректно з текою node_modules, до якої створено символічне посилання. You need to explicitly set virtualStoreType: global in pnpm-workspace.yaml to use it for project installs. У pnpm v11 глобальне віртуальне сховище зазвичай увімкнено для пакунків, встановлених за допомогою pnpm dlx (pnpx), а також для пакунків, встановлених глобально. Мета полягає в тому, щоб у майбутній версії зробити це стандартним налаштуванням для всіх встановлень.

Глобальні пакунки#

У pnpm v11 глобальні встановлення (pnpm add -g) та pnpm dlx стандартно використовують глобальне віртуальне сховище. Дивіться Глобальні пакунки, щоб ознайомитися з повним посібником щодо роботи системи управління глобальними пакунками у версії 11, зокрема щодо ізольованих інсталяцій та нового розташування бінарних файлів.

Налаштування#

See the virtualStoreType setting reference for all configuration details. virtualStoreType was added in v11.23.0 as the canonical spelling of enableGlobalVirtualStore, which keeps working.