Passa al contenuto principale
Version: Prossimo

Struttura `node_modules` con collegamenti simbolici

info

Questo articolo descrive solo come è strutturata la cartella node_modules di pnpm quando non ci sono pacchetti con dipendenze peer. Per lo scenario più complesso di dipendenze con i peer, vedere come vengono risolti i peer.

il layout node_modules pnpm utilizza collegamenti simbolici per creare una struttura nidificata di dipendenze.

Ogni file di ogni pacchetto all'interno di node_modules è un collegamento fisico all'archivio indirizzabile al contenuto. Diciamo che installi [email protected] che dipende da [email protected]. pnpm collegherà entrambi i pacchetti a node_modules in questo modo:

node_modules└── .pnpm    ├── [email protected]    │   └── node_modules    │       └── bar -> <store>/bar    │           ├── index.js    │           └── package.json    └── [email protected]        └── node_modules            └── foo -> <store>/foo                ├── index.js                └── package.json

Questi sono gli unici file "reali" in node_modules. Una volta che tutti i pacchetti sono collegati fisicamente a node_modules, vengono creati collegamenti simbolici per creare la struttura del grafico delle dipendenze annidata.

Come potresti aver notato, entrambi i pacchetti sono collegati fisicamente in una sottocartella all'interno di una cartella node_modules ([email protected]/node_modules/foo). Ciò è necessario per:

  1. permettere ai pacchetti di importarsi. foo dovrebbe essere in grado di eseguire require('foo/package.json') o import * as package from "foo/package.json".
  2. evitare i collegamenti simbolici circolari. Le dipendenze dei pacchetti sono posizionate nella stessa cartella in cui si trovano i pacchetti dipendenti. Per Node.js non fa differenza se le dipendenze si trovano all'interno di node_modules del pacchetto o in qualsiasi altro node_modules delle cartelle superiori.

La fase successiva dell'installazione è il collegamento simbolico delle dipendenze. bar sarà collegato simbolicamente alla cartella [email protected]/node_modules:

node_modules└── .pnpm    ├── [email protected]    │   └── node_modules    │       └── bar -> <store>/bar    └── [email protected]        └── node_modules            ├── foo -> <store>/foo            └── bar -> ../../[email protected]/node_modules/bar

Successivamente, vengono gestite le dipendenze dirette. pippo verrà collegato simbolicamente nella cartella root node_modules perché foo è una dipendenza del progetto:

node_modules├── foo -> ./.pnpm/[email protected]/node_modules/foo└── .pnpm    ├── [email protected]    │   └── node_modules    │       └── bar -> <store>/bar    └── [email protected]        └── node_modules            ├── foo -> <store>/foo            └── bar -> ../../[email protected]/node_modules/bar

Questo è un esempio molto semplice. Tuttavia, il layout manterrà questa struttura indipendentemente dal numero di dipendenze e dalla profondità del grafico delle dipendenze.

Aggiungiamo [email protected] come dipendenza di bar e foo. Ecco come apparirà la nuova struttura:

node_modules├── foo -> ./.pnpm/[email protected]/node_modules/foo└── .pnpm    ├── [email protected]    │   └── node_modules    │       ├── bar -> <store>/bar    │       └── qar -> ../../[email protected]/node_modules/qar    ├── [email protected]    │   └── node_modules    │       ├── foo -> <store>/foo    │       ├── bar -> ../../[email protected]/node_modules/bar    │       └── qar -> ../../[email protected]/node_modules/qar    └── [email protected]        └── node_modules            └── qar -> <store>/qar

Come puoi vedere, anche se il grafico ora è più profondo (pippo > bar > qar), la cartella nel file system è sempre la stessa.

Questo layout potrebbe sembrare strano a prima vista, ma è completamente compatibile con l'algoritmo di risoluzione del modulo di Node! Quando risolve i moduli, Node ignora i collegamenti simbolici, quindi quando è richiesto bar da [email protected]/node_modules/foo/index.js, Node non usa bar da [email protected]/node_modules/bar, ma invece bar è risolto nella sua posizione reale ([email protected]/node_modules/bar). Di conseguenza, bar può anche risolvere le sue dipendenze che sono in [email protected]/node_modules.

Un grande bonus di questo layout è che solo i pacchetti che sono davvero nelle dipendenze sono accessibili. Con una struttura node_modules appiattita, tutti i pacchetti installati sono accessibili. Per saperne di più sul perché questo è un vantaggio, vedi "la severità di pnpm aiuta ad evitare bug stupidi"