Passa al contenuto principale

La node_modules flat non è l'unico modo

· 3 minuti di lettura

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 utilizzare node_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:

  1. è completamente compatibile con Node.js
  2. 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.