Passa al contenuto principale
Versione: Prossimo

Come vengono risolti i peer

Una delle migliori caratteristiche di pnpm è che in un progetto, una versione specifica di un pacchetto avrà sempre un set di dipendenze. C'è un'eccezione da questa regola, però: pacchetti con dipendenze peer.

Le dipendenze peer vengono risolte dalle dipendenze installate più in alto nel grafico delle dipendenze, poiché condividono la stessa versione del genitore. Ciò significa che se foo@1.0.0 ha due peer (bar@^1 e baz@^1) allora potrebbe avere diversi insiemi di dipendenze nello stesso progetto.

- foo-parent-1
- bar@1.0.0
- baz@1.0.0
- foo@1.0.0
- foo-parent-2
- bar@1.0.0
- baz@1.1.0
- foo@1.0.0

Nell'esempio sopra, foo@1.0.0 è installato per foo-parent-1 e foo-parent-2. Entrambi i pacchetti hanno anche bar e baz, ma dipendono da diverse versioni di baz. Di conseguenza, foo@1.0.0 ha due diversi insiemi di dipendenze: uno con baz@1.0.0 e l'altro con baz@1.1.0. Per supportare questi casi di utilizzo, pnpm deve collegare fisicamente foo@1.0.0 tante volte quanti diversi set di dipendenze sono presenti.

Normalmente, se un pacchetto non ha dipendenze peer, è difficilmente collegato a una node_modules accanto ai collegamenti simbolici delle sue dipendenze, in questo modo:

node_modules
└── .pnpm
├── foo@1.0.0
│ └── node_modules
│ ├── foo
│ ├── qux -> ../../qux@1.0.0/node_modules/qux
│ └── plugh -> ../../plugh@1.0.0/node_modules/plugh
├── qux@1.0.0
├── plugh@1.0.0

Tuttavia, se pippo ha dipendenze peer, potrebbero esserci più gruppi di dipendenze, quindi creiamo gruppi diversi per diverse risoluzioni di dipendenze peer:

node_modules
└── .pnpm
├── foo@1.0.0_bar@1.0.0+baz@1.0.0
│ └── node_modules
│ ├── foo
│ ├── bar -> ../../bar@1.0.0/node_modules/bar
│ ├── baz -> ../../baz@1.0.0/node_modules/baz
│ ├── qux -> ../../qux@1.0.0/node_modules/qux
│ └── plugh -> ../../plugh@1.0.0/node_modules/plugh
├── foo@1.0.0_bar@1.0.0+baz@1.1.0
│ └── node_modules
│ ├── foo
│ ├── bar -> ../../bar@1.0.0/node_modules/bar
│ ├── baz -> ../../baz@1.1.0/node_modules/baz
│ ├── qux -> ../../qux@1.0.0/node_modules/qux
│ └── plugh -> ../../plugh@1.0.0/node_modules/plugh
├── bar@1.0.0
├── baz@1.0.0
├── baz@1.1.0
├── qux@1.0.0
├── plugh@1.0.0

Creiamo collegamenti simbolici a foo che si trova all'interno di foo@1.0.0_bar@1.0.0+baz@1.0.0 o a quello in foo@1.0.0_bar@1.0.0+baz@1.1.0. Di conseguenza, il risolutore del modulo Node.js troverà i peer corretti.

Se un pacchetto non ha dipendenze peer ma ha dipendenze con peer risolti più in alto nel grafico, allora quel pacchetto transitivo può apparire nel con diversi gruppi di dipendenze. Ad esempio, c'è il pacchetto a@1.0.0 con una singola dipendenza b@1.0.0. b@1.0.0 ha una dipendenza peer c@^1. a@1.0.0 non risolverà mai i peer di b@1.0.0, quindi diventa dipendente anche dai peer di b@1.0.0.

Ecco come apparirà quella struttura in node_modules. In questo esempio, a@1.0.0 dovrà apparire due volte nei node_modules - risolto una volta con c@1.0.0 e di nuovo con c@1.1.0.

node_modules
└── .pnpm
├── a@1.0.0_c@1.0.0
│ └── node_modules
│ ├── a
│ └── b -> ../../b@1.0.0_c@1.0.0/node_modules/b
├── a@1.0.0_c@1.1.0
│ └── node_modules
│ ├── a
│ └── b -> ../../b@1.0.0_c@1.1.0/node_modules/b
├── b@1.0.0_c@1.0.0
│ └── node_modules
│ ├── b
│ └── c -> ../../c@1.0.0/node_modules/c
├── b@1.0.0_c@1.1.0
│ └── node_modules
│ ├── b
│ └── c -> ../../c@1.1.0/node_modules/c
├── c@1.0.0
├── c@1.1.0