La node_modules flat non è l'unico modo
I nuovi utenti di pnpm mi chiedono spesso della strana struttura di node_modules
che crea pnpm. Perché non è piatta? Dove sono tutte le dipendenze secondarie?
Presumo che i lettori dell'articolo abbiano già familiarità con la cartella
node_modules
piatta creata da npm e Yarn. Se non capisci perché npm 3 ha dovuto iniziare a utilizzarenode_modules
flat nella v3, puoi trovare un po' di preistoria in Perché dovremmo usare pnpm?.
Perché allora node_modules
di pnpm è insolito? Creiamo due cartelle ed eseguiamo npm add express
in una di esse e pnpm add express
nell'altra. Ecco la parte superiore di ciò che si ottiene in node_modules
della prima cartella:
.bin
accepts
array-flatten
body-parser
bytes
content-disposition
cookie-signature
cookie
debug
depd
destroy
ee-first
encodeurl
escape-html
etag
express
Puoi vedere l'intera cartella qui.
E questo è ciò che ottieni in node_modules
creato da pnpm:
.pnpm
.modules.yaml
express
Puoi controllarlo qui.
Allora, dove sono tutte le dipendenze? C'è solo una cartella in node_modules
chiamata .pnpm
e un collegamento simbolico chiamato express
. Bene, abbiamo installato solo express
, quindi questo è l'unico pacchetto a cui la tua applicazione deve avere accesso
Leggi di più sul perché la severità di pnpm è una buona cosa qui
Vediamo cosa c'è dentro express
:
▾ node_modules
▸ .pnpm
▾ express
▸ lib
History.md
index.js
LICENSE
package.json
Readme.md
.modules.yaml
express
non ha node_modules
? Dove sono tutte le dipendenze di express
?
Il trucco è che express
è solo un collegamento simbolico. Quando Node.js risolve le dipendenze, utilizza le loro posizioni reali, quindi non conserva i collegamenti simbolici. Ma dov'è la vera posizione di express
, si potrebbe chiedere?
Qui: node_modules/.pnpm/express@4.17.1/node_modules/express.
OK, ora conosciamo lo scopo della cartella .pnpm/
. .pnpm/
memorizza tutti i pacchetti in una struttura di cartelle piatte, quindi ogni pacchetto può essere trovato in una cartella denominata con questo modello:
.pnpm/<name>@<version>/node_modules/<name>
La chiamiamo cartella dell'archivio virtuale.
Questa struttura piatta evita i problemi di percorso lunghi che sono stati causati dai node_modules
annidati creati da npm v2 ma mantiene i pacchetti isolati a differenza dei node_modules
piatti creati da npm v3,4,5,6 o yarn v1.
Ora diamo un'occhiata alla vera posizione di express
:
▾ express
▸ lib
History.md
index.js
LICENSE
package.json
Readme.md
È una truffa? Manca ancora la cartella node_modules
! Il secondo trucco della struttura node_modules
di pnpm è che le dipendenze dei pacchetti sono sullo stesso livello di cartella su cui si trova la posizione reale del pacchetto dipendente. Quindi le dipendenze di express
non sono in .pnpm/express@4.17.1/node_modules/express/node_modules/
ma in .pnpm/express@4.17.1/node_modules/:
▾ node_modules
▾ .pnpm
▸ accepts@1.3.5
▸ array-flatten@1.1.1
...
▾ express@4.16.3
▾ node_modules
▸ accepts
▸ array-flatten
▸ body-parser
▸ content-disposition
...
▸ etag
▾ express
▸ lib
History.md
index.js
LICENSE
package.json
Readme.md
Tutte le dipendenze di express
sono collegamenti simbolici a cartelle appropriate in node_modules/.pnpm/
. Posizionare le dipendenze di express
un livello in alto permette di evitare i collegamenti simbolici circolari.
Quindi, come puoi vedere, anche se la struttura node_modules
di pnpm sembra inizialmente inusuale:
- è completamente compatibile con Node.js
- i pacchetti sono ben raggruppati con le loro dipendenze
La struttura è un po' più complessa per i pacchetti con dipendenze peer ma l'idea è la stessa: usare collegamenti simbolici per creare un annidamento con una struttura di cartelle piatta.