Перейти до основного змісту
Версія: 8.x

Як вирішуються конфлікти прямих залежностей

Однією з найкращих особливостей pnpm є те, що в одному проєкті певна версія пакунка завжди матиме один набір залежностей. There is one exception from this rule, though - packages with peer dependencies.

Прямі залежності вирішуються із залежностей, встановлених вище на графі залежностей, оскільки вони мають ту саму версію, що й їхні батьки. Це означає, що якщо [email protected] має дві прямі залежності (bar@^1 і baz@^1), то він може мати декілька різних наборів залежностей в одному проєкті.

У наведеному вище прикладі [email protected] встановлено для foo-parent-1 та foo-parent-2. Обидва пакунки також мають bar та baz, але вони залежать від різних версій baz. Як наслідок, [email protected] має два різних набори залежностей: один з [email protected], а інший з [email protected]. Для підтримки цих варіантів використання pnpm має створити жорстке посилання [email protected] стільки разів, скільки існує різних наборів залежностей.

Зазвичай, якщо пакунок не має прямих залежностей, він привʼязується до теки node_modules жорстким посиланням поруч із символічними посиланнями його залежностей, наприклад, так:

node_modules
└── .pnpm
├── [email protected]
│ └── node_modules
│ ├── foo
│ ├── qux -> ../../[email protected]/node_modules/qux
│ └── plugh -> ../../[email protected]/node_modules/plugh
├── [email protected]
├── [email protected]

Однак, якщо foo має прямі залежності, для нього може існувати декілька наборів залежностей, тому ми створюємо різні набори для різних резолюцій прямих залежностей:

node_modules
└── .pnpm
├── [email protected][email protected][email protected]
│ └── node_modules
│ ├── foo
│ ├── bar -> ../../[email protected]/node_modules/bar
│ ├── baz -> ../../[email protected]/node_modules/baz
│ ├── qux -> ../../[email protected]/node_modules/qux
│ └── plugh -> ../../[email protected]/node_modules/plugh
├── [email protected][email protected][email protected]
│ └── node_modules
│ ├── foo
│ ├── bar -> ../../[email protected]/node_modules/bar
│ ├── baz -> ../../[email protected]/node_modules/baz
│ ├── qux -> ../../[email protected]/node_modules/qux
│ └── plugh -> ../../[email protected]/node_modules/plugh
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]

Ми створюємо символічні посилання або на foo, що знаходиться всередині [email protected][email protected][email protected], або на той, що знаходиться в [email protected][email protected][email protected]. Як наслідок, модуль Node.js знайде правильні прямі залежності.

Якщо пакунок не має залежностей від однорангових пакунків, але має залежності від однорангових пакунків, що розташовані вище на графі, то цей транзитивний пакунок може зʼявитися у проєкті з різними наборами залежностей. Наприклад, є пакунок [email protected] з єдиною залежністю [email protected]. [email protected] має пряму залежність c@^1. [email protected] ніколи не розпізнає прямих залежностей [email protected], тому він також стає залежним від залежностей [email protected].

Ось як ця структура буде виглядати у node_modules. В цьому прикладі [email protected] має зʼявитися двічі у node_modules проєкту — один раз за допомогою [email protected], а другий — за допомогою [email protected].

node_modules
└── .pnpm
├── [email protected][email protected]
│ └── node_modules
│ ├── a
│ └── b -> ../../[email protected][email protected]/node_modules/b
├── [email protected][email protected]
│ └── node_modules
│ ├── a
│ └── b -> ../../[email protected][email protected]/node_modules/b
├── [email protected][email protected]
│ └── node_modules
│ ├── b
│ └── c -> ../../[email protected]/node_modules/c
├── [email protected][email protected]
│ └── node_modules
│ ├── b
│ └── c -> ../../[email protected]/node_modules/c
├── [email protected]
├── [email protected]