Node-Modules & Hoisting Settings

node_modules settings#

modulesDir#

  • Стандартно: node_modules
  • Тип: path

Тека, до якої буде встановлено залежності (замість node_modules).

nodeLinker#

  • Стандартно: isolated
  • Тип: isolated, hoisted, pnp

Визначає, який компонувальник слід використовувати для встановлення пакунків Node.

  • isolated — залежності компонуються з віртуального сховища за адресою node_modules/.pnpm.
  • hoisted — створюється плаский node_modules без символічних посилань. Так само як і node_modules, створені за допомогою npm або Yarn Classic. При використанні цього параметра для підйому використовується одна з бібліотек Yarn. Законні причини для використання цього налаштування:
    1. Ваші інструменти погано працюють із символічними посиланнями.
    2. Ваш проєкт буде розгорнуто на безсерверний хостинг. Деякі безсерверні провайдери (наприклад, AWS Lambda) не підтримують symlinks. Альтернативним розвʼязання цієї проблеми є пакування програми перед розгортанням.
    3. Якщо ви хочете опублікувати свій пакунок за допомогою "bundledDependencies".
    4. Якщо ви використовуєте Node.js із прапорцем --preserve-symlinks.
  • pnp — без node_modules. Plug'n'Play — це інноваційна стратегія для Node, яка використовується Yarn Berry. Рекомендується також встановити параметр symlink у значення false, якщо ви використовуєте pnp як ваш компонувальник.

nodeExperimentalPackageMap#

Додано у: v11.8.0

  • Стандартно: false
  • Тип: Boolean

When true, pnpm writes node_modules/.package-map.json during isolated and hoisted installs and injects it into pnpm-managed Node.js script environments by adding Node's --experimental-package-map option to NODE_OPTIONS.

Nothing reads the map without this setting, so pnpm does not write one. An install that stops writing the map also removes one an earlier install left.

CLI and environment configuration use the kebab-case name node-experimental-package-map.

pnpm-workspace.yaml
nodeExperimentalPackageMap: true

nodePackageMapType#

Додано у: v11.8.0

  • Default: standard
  • Type: standard, loose

Controls how node_modules/.package-map.json is generated.

  • standard - only declared dependencies are available through the package map.
  • loose - also maps packages that are reachable through the installed node_modules layout, which can allow undeclared hoisted dependencies to resolve.

CLI and environment configuration use the kebab-case name node-package-map-type.

pnpm-workspace.yaml
nodePackageMapType: loose
  • Стандартно: true
  • Тип: Boolean

Коли symlink встановлено у false, pnpm створює віртуальну теку сховища без жодних символьних посилань. Це корисний параметр разом з nodeLinker=pnp.

enableModulesDir#

  • Стандартно: true
  • Тип: Boolean

Якщо false, pnpm не записуватиме жодних файлів до теки модулів (node_modules). Це корисно, коли теку модулів змонтовано з файловою системою у просторі користувача (FUSE). Існує експериментальна версія CLI, яка дозволяє змонтувати теку модулів за допомогою FUSE: @pnpm/mount-modules.

confirmModulesPurge#

  • Стандартно: true
  • Тип: Boolean

Controls whether pnpm asks for confirmation before removing the contents of an incompatible modules directory and reinstalling it from scratch. When false, pnpm recreates the modules directory without prompting. In CI, confirmation is disabled automatically. If confirmation is enabled without a TTY and CI is not detected, pnpm aborts with ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY.

virtualStoreDir#

  • Стандартно: node_modules/.pnpm
  • Тип: path

Тека з посиланнями на сховище. Всі прямі та непрямі залежності проєкту повʼязані з цією текою.

Dependencies installed from a URL or local path get a hash suffix on their directory name when the part after the scheme contains +, #, :, ?, or another character that is not allowed in file names. This keeps distinct URLs in separate directories.

Це корисний параметр, який може усунути проблеми з довгими шляхами у Windows. Якщо у вас є залежності з дуже довгими шляхами, ви можете вибрати віртуальне сховище у корені диска (наприклад, C:\my-project-store).

Або ви можете встановити віртуальне сховище у .pnpm і додати його до .gitignore. Це зробить трасування стеку чистішим, оскільки шляхи до залежностей будуть на одну теку вище.

ПРИМІТКА: віртуальне сховище не може бути спільним для декількох проєктів. Кожен проєкт повинен мати власне віртуальне сховище (за винятком робочих просторів, де корінь є спільним).

virtualStoreDirMaxLength#

  • Стандартно:
    • У Linux/macOS: 120
    • У Windows: 60
  • Тип: number

Встановлює максимально допустиму довжину назв тек всередині теки віртуального сховища (node_modules/.pnpm). Ви можете встановити менше значення, якщо у вас виникають проблеми з довгими шляхами у Windows.

virtualStoreOnly#

Додано у: v11.0.0

  • Стандартно: false
  • Тип: Boolean

Якщо встановлено значення true, pnpm заповнює віртуальний репозиторій без створення символьних посилань імпортера, підйому, посилань на бінарні файли або запуску скриптів життєвого циклу. Це корисно для попереднього заповнення сховища (наприклад, у збірках Nix) без створення зайвих артефактів на рівні проєкту. Команда pnpm fetch використовує цей режим внутрішньо.

packageImportMethod#

  • Стандартно: auto
  • Тип: auto, hardlink, copy, clone, clone-or-copy

Керує способом імпорту пакунків зі сховища (якщо ви хочете вимкнути symlinks всередині node_modules, то вам потрібно змінити параметр nodeLinker, а не цей).

  • auto — спробувати клонувати пакунки зі сховища. Якщо клонування не підтримується, встановіть жорстке посилання на пакунки зі сховища. Якщо ані клонування, ані звʼязування неможливі, поверніться до копіювання
  • hardlink — жорстке посилання на пакунки зі сховища
  • clone-or-copy — спробувати клонувати пакунки зі сховища. Якщо клонування не підтримується, поверніться до копіювання
  • copy — скопіювати пакунки зі сховища
  • clone —клонувати (те ж що й copy-on-write або посилатись за посиланням) пакунки зі сховища

Клонування — найкращий спосіб запису пакунків у node_modules. Це найшвидший і найбезпечніший спосіб. Коли використовується клонування, ви можете редагувати файли у ваших node_modules, і вони не будуть змінені у центральному сховищі з адресованим вмістом.

На жаль, не всі файлові системи підтримують клонування. Ми рекомендуємо використовувати файлову систему з копіюванням при записі (CoW) (наприклад, Btrfs замість Ext4 в Linux) для найкращого досвіду роботи з pnpm.

modulesCacheMaxAge#

  • Стандартно: 10080 (7 днів в хвилинах)
  • Тип: number

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

dlxCacheMaxAge#

  • Стандартно: 1440 (1 день в хвилинах)
  • Тип: number

Час у хвилинах, через який закінчується кеш dlx. Після виконання команди dlx pnpm зберігає кеш, який пропускає крок встановлення для наступних викликів тієї самої команди dlx.

virtualStoreType#

Added in: v11.23.0

  • Default: project
  • Type: project, global

Names where the virtual store lives: one store per project, or one store per machine.

pnpm-workspace.yaml
virtualStoreType: global

project is the default layout: every project gets its own virtual store inside node_modules/.pnpm. global is the global virtual store: a single store shared by every project on the machine, with each project's node_modules holding only symlinks into it.

This is the canonical spelling of enableGlobalVirtualStore, which keeps working; when a project sets both, virtualStoreType wins. It can also be set through the PNPM_CONFIG_VIRTUAL_STORE_TYPE env variable and read back with pnpm config get virtualStoreType.

The setting is independent of nodeLinker: isolated and pnp both work with either store type, and hoisted writes no virtual store at all, so it is unaffected.

enableGlobalVirtualStore#

Додано у: v10.12.1

  • Стандартно: false
  • Тип: Boolean

нотатка

Since v11.23.0, virtualStoreType is the canonical spelling of this setting: enableGlobalVirtualStore: true is virtualStoreType: global. Both work, and virtualStoreType wins when a project sets both.

нотатка

У pnpm v11 глобальні встановлення (pnpm add -g) та pnpm dlx стандартно використовують глобальне віртуальне сховище.

Якщо увімкнено, node_modules містить лише символьні посилання на центральне віртуальне сховище, а не на node_modules/.pnpm. Стандартно, це центральне сховище розташовано за адресою <store-path>/links (використовуйте pnpm store path, щоб знайти <store-path>).

У центральному віртуальному сховищі кожен пакунок жорстко повʼязаний з текою, назва якої є хешем його графа залежностей. В результаті, всі проєкти в системі можуть звʼязати свої залежності з цим спільним місцем на диску. Цей підхід концептуально подібний до того, як NixOS керує пакунками, використовуючи хеші графів залежностей для створення ізольованих та спільних тек пакунків у сховищі Nix.

Це не слід плутати з глобальним сховищем адресованого вмісту. The actual package files are still hard linked from the content-addressable store, but instead of being linked directly into node_modules/.pnpm, they are linked into the global virtual store.

Using a global virtual store can speed up installations when a warm cache is available. Однак у середовищі CI (де кеш зазвичай відсутній) це може сповільнити встановлення. If pnpm detects that it is running in CI and this setting is not set, the global virtual store is off.

important

Для підтримки піднятих залежностей при використанні глобального віртуального сховища pnpm покладається на змінну оточення NODE_PATH. Це дозволяє Node.js розпізнавати пакунки з піднятої теки node_modules. Node.js does not respect NODE_PATH for ESM imports, though, so before v11.23.0 a dependency that imports a package not declared in its own package.json (which is considered bad practice) failed to resolve under ESM.

Since v11.23.0, every process pnpm spawns for the project (pnpm run, pnpm exec, lifecycle scripts, and the tools pnpm dlx runs) receives both NODE_PATH and a NODE_OPTIONS --import flag that registers a resolve hook restoring NODE_PATH lookups for ESM. Such imports now resolve for CommonJS and ESM alike, without the @pnpm/plugin-esm-node-path config dependency that used to be needed (#9618).

Two things fall outside that: a node process you start yourself rather than through pnpm, and a project that sets extendNodePath to false, which turns the whole NODE_PATH mechanism off and takes the resolve hook with it. Use packageExtensions to declare the missing dependencies if you need them to resolve in either case.

Dependency hoisting settings#

hoist#

  • Стандартно: true
  • Тип: Boolean

Коли true, всі залежності підіймаються до node_modules/.pnpm/node_modules. Це робить не перелічені залежності доступними для всіх пакунків всередині node_modules.

hoistPattern#

  • Стандартно: ['*']
  • Тип: string[]

Вказує pnpm, які пакунки слід підняти до node_modules/.pnpm/node_modules. Стандартно, всі пакунки буде піднято — однак, якщо ви знаєте, що лише деякі пакунки мають фантомні залежності, ви можете скористатися цим параметром, щоб підняти лише фантомні залежності (рекомендується).

Наприклад:

pnpm-workspace.yaml
hoistPattern:
- "*eslint*"
- "*babel*"

Ви також можете заборонити підйом шаблонів за допомогою !.

Наприклад:

pnpm-workspace.yaml
hoistPattern:
- "*types*"
- "!@types/react"

In a workspace, the pattern is matched against the names of the workspace projects too, unless hoistWorkspacePackages is turned off.

publicHoistPattern#

  • Стандартно: []
  • Тип: string[]

На відміну від hoistPattern , який підіймає залежності до прихованої теки модулів у віртуальному сховищі, publicHoistPattern підіймає залежності, що відповідають шаблону, до кореневої теки модулів. Підняття до кореневої теки модулів означає, що код застосунку матиме доступ до фантомних залежностей, навіть якщо вони неправильно змінять стратегію розвʼязання.

Цей параметр корисний при роботі з деякими недосконалими інструментами, що підключаються, які не обробляють залежності належним чином.

Наприклад:

pnpm-workspace.yaml
publicHoistPattern:
- "*plugin*"

Зауваження: Встановлення shamefullyHoist у true аналогічно встановленню publicHoistPattern у *.

Ви також можете заборонити підйом шаблонів за допомогою !.

Наприклад:

pnpm-workspace.yaml
publicHoistPattern:
- "*types*"
- "!@types/react"

In a workspace, the pattern is matched against the names of the workspace projects too, unless hoistWorkspacePackages is turned off.

hoistWorkspacePackages#

  • Стандартно: true
  • Тип: Boolean

When true, the projects of the workspace are hoisting candidates too, not only the packages that come from a registry.

hoistPattern and publicHoistPattern then decide where each project lands, exactly as they do for a registry dependency. publicHoistPattern is checked first, so a project matching both patterns goes to the root only:

  • A project whose name matches publicHoistPattern is symlinked into <workspace_root>/node_modules.
  • A project whose name matches only hoistPattern is symlinked into <workspace_root>/node_modules/.pnpm/node_modules.
  • A project whose name matches neither is not hoisted.

Because hoistPattern defaults to ['*'] and publicHoistPattern to [], the default is that every workspace project is symlinked into <workspace_root>/node_modules/.pnpm/node_modules.

This is how a tool that resolves packages by name from the workspace root finds a project of the workspace. The usual case is ESLint loading a plugin that is developed in the same monorepo:

pnpm-workspace.yaml
publicHoistPattern:
  - "*eslint*"

With that setting, a workspace project named eslint-plugin-acme appears at <workspace_root>/node_modules/eslint-plugin-acme, even if no package.json lists it as a dependency.

Details worth knowing:

  • A project is matched by the name in its package.json, not by its directory name.
  • Every project of the workspace is a candidate, including a project that nothing else depends on. The workspace root project is never hoisted.
  • The symlink points at the project's own directory in the workspace, so there is nothing to keep in sync.
  • A direct dependency wins a name conflict. If a package with the same name is a direct dependency of any workspace project, that package is hoisted and the workspace project is not. Frozen installs preserve this choice even when the dependency is unchanged.
  • The setting only adds candidates. When hoistPattern and publicHoistPattern are both empty, nothing is hoisted at all, workspace projects included. Setting hoist to false empties hoistPattern.

shamefullyHoist#

  • Стандартно: false
  • Тип: Boolean

Стандартно pnpm створює напівсувору теку node_modules, тобто залежності мають доступ до неоголошених залежностей, а модулі поза межами node_modules — ні. За такої схеми більшість пакунків в екосистемі працюють без проблем. Однак, якщо деякі інструменти працюють лише тоді, коли підняті залежності знаходяться у корені node_modules, ви можете встановити цей параметр у true, щоб підняти їх для вас.

hoistingLimits#

Додано у: v11.5.0

  • Default: none
  • Type: none, workspaces, dependencies

Controls how far dependencies are hoisted when using nodeLinker: hoisted. This setting mirrors Yarn's nmHoistingLimits.

  • none - hoist as far as possible (the default).
  • workspaces - hoist only as far as each workspace package, preventing dependencies from being hoisted above the workspace package that depends on them.
  • dependencies - hoist only up to each workspace package's direct dependencies, preventing transitive dependencies from being hoisted into the workspace package's node_modules.