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
! The second trick of pnpm's node_modules
structure is that the dependencies of packages are on the same directory level as the real location of the dependent package. 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.