Passa al contenuto principale
Versione: 7.x

Domande frequenti (FAQ)

Perché la mia cartella node_modules utilizza spazio su disco se i pacchetti sono salvati in un archivio globale?

pnpm crea "collegamenti fisici" dall'archivio globale alla cartella node_modules del progetto. I collegamenti fisici puntano allo stesso spazio sul disco dove si trovano i file originali. Quindi, ad esempio, se hai foo nel tuo progetto come dipendenza e occupa 1 Mb di spazio, sembrerà che occupi 1 Mb di spazio nella cartella node_modules del progetto e la stessa quantità di spazio nell'archivio globale. Tuttavia, 1 Mb è lo stesso spazio sul disco indirizzato da due posizioni diverse. Quindi in totale foo occupa 1MB, non 2MB.

Per saperne di più su questo argomento:

Funziona su Windows?

Risposta breve: sì. Risposta lunga: Usare i collegamenti simbolici su Windows è a dir poco problematico, tuttavia, pnpm ha una soluzione alternativa. Per Windows, usiamo le giunzioni.

Ma l'approccio annidato di node_modules è incompatibile con Windows?

Le prime versioni di npm hanno avuto problemi a causa del annidamento di tutti i node_modules (vedi questo ticket). Tuttavia, pnpm non crea cartelle profonde, memorizza tutti i pacchetti pianamente e utilizza collegamenti simbolici per creare la struttura ad albero delle dipendenze.

E i collegamenti simbolici circolari?

Sebbene pnpm utilizzi il collegamento per inserire le dipendenze nella cartella node_modules, collegamenti simbolici circolari vengono evitati perché i pacchetti padre vengono inseriti nella stessa node_modules in cui si trovano le loro dipendenze. Quindi le dipendenze di foo non sono in foo/node_modules, ma foo è in node_modules insieme alle sue dipendenze.

Perché avere collegamenti fisici alla fine? Perché non collegare simbolicamente direttamente all'archivio globale?

Un pacchetto può avere diversi insiemi di dipendenze su una macchina.

Nel progetto A foo@1.0.0 può avere una dipendenza risolta in bar@1.0.0, ma nel progetto B la stessa dipendenza di foo potrebbe risolversi in bar@1.1.0; quindi, pnpm collega fisicamente foo@1.0.0 a ogni progetto in cui viene utilizzato, per creare diversi insiemi di dipendenze per esso.

Il collegamento simbolico diretto all'archivio globale funzionerebbe con il flag --preserve-symlinks di Node, tuttavia, questo approccio ha una pletora dei suoi problemi, quindi abbiamo deciso di attenerci ai collegamenti fisici. Per maggiori dettagli sul perché stata presa questa decisione, vedere questo ticket.

Pnpm funziona su più unità o filesystem?

L'archivio dei pacchetti dovrebbe trovarsi sulla stessa unità e filesystem delle installazioni, altrimenti i pacchetti verranno copiati, non collegati. Ciò è dovuto a una limitazione nel funzionamento del collegamento fisico, in quanto un file su un file system non può indirizzare una posizione in un altro. Vedi il ticket #712 per maggiori dettagli.

pnpm funziona in modo diverso nei 2 casi seguenti:

Il percorso dell'archivio è specificato

Se il percorso dell'archivio è specificato tramite la configurazione dell'archivio, la copia avviene tra l'archivio e tutti i progetti che si trovano su un disco diverso.

Se si esegue pnpm install sul disco A, l'archivio pnpm deve trovarsi sul disco A. Se l'archivio pnpm si trova sul disco B, tutti i pacchetti richiesti verranno copiati direttamente nella posizione del progetto invece di essere collegati. Questo inibisce gravemente i vantaggi di archiviazione e prestazioni di pnpm.

Il percorso dell'archivio NON è specificato

Se il percorso dell'archivio non è impostato, vengono creati più archivi (uno per unità o filesystem).

Se l'installazione viene eseguita sul disco A, l'archivio verrà creato su A in .pnpm-store nella radice del filesystem. Se in seguito l'installazione viene eseguita sul disco B, verrà creato un archivio indipendente su B in .pnpm-store. I progetti manterrebbero ancora i vantaggi di pnpm, ma ogni unità potrebbe avere pacchetti ridondanti.

Cosa significa pnpm?

pnpm significa npm performante. @rstacruz ha inventato il nome.

pnpm non funziona con <IL TUO-PROGETTO-QUI>?

Nella maggior parte dei casi significa che una delle dipendenze richiede pacchetti non dichiarati in package.json. È un errore comune causato da una node_modules piatta. Se ciò accade, si tratta di un errore nella dipendenza e dovrebbe essere corretta. Tuttavia, ciò potrebbe richiedere del tempo, quindi pnpm supporta soluzioni alternative per far funzionare i pacchetti difettosi.

Soluzione 1

In case there are issues, you can use the node-linker=hoisted setting. This creates a flat node_modules structure similar to the one created by npm.

Soluzione 2

In the following example, a dependency does not have the iterall module in its own list of deps.

The easiest solution to resolve missing dependencies of the buggy packages is to add iterall as a dependency to our project's package.json.

You can do so, by installing it via pnpm add iterall, and will be automatically added to your project's package.json.

  "dependencies": {
...
"iterall": "^1.2.2",
...
}

Soluzione 3

One of the solutions is to use hooks for adding the missing dependencies to the package's package.json.

An example was Webpack Dashboard which wasn't working with pnpm. It has since been resolved such that it works with pnpm now.

It used to throw an error:

Error: Cannot find module 'babel-traverse'
at /node_modules/inspectpack@2.2.3/node_modules/inspectpack/lib/actions/parse

The problem was that babel-traverse was used in inspectpack which was used by webpack-dashboard, but babel-traverse wasn't specified in inspectpack's package.json. It still worked with npm and yarn because they create flat node_modules.

The solution was to create a .pnpmfile.cjs with the following contents:

module.exports = {
hooks: {
readPackage: (pkg) => {
if (pkg.name === "inspectpack") {
pkg.dependencies['babel-traverse'] = '^6.26.0';
}
return pkg;
}
}
};

After creating a .pnpmfile.cjs, delete pnpm-lock.yaml only - there is no need to delete node_modules, as pnpm hooks only affect module resolution. Then, rebuild the dependencies & it should be working.