Zum Hauptinhalt springen
Version: 6.x

FAQ - Häufig gestellte Fragen

Warum verwendet mein node_modules Ordner Plattenplatz, wenn Pakete in einem globalen Store gespeichert werden?

pnpm erstellt Hardlinks vom globalen Speicher zu den node_modules Ordnern des Projekts. Hardlinks verweisen auf dieselbe Stelle auf der Festplatte, an der sich die ursprünglichen Dateien befinden. Wenn Sie zum Beispiel foo in Ihrem Projekt als Abhängigkeit haben und 1MB Speicherplatz belegen, dann sieht es so aus, als belege es 1MB Speicherplatz im node_modules Ordner des Projekts und die gleiche Menge an Speicherplatz im globalen Store. Diese 1 MB sind jedoch derselbe Speicherplatz auf dem Datenträger, der von zwei verschiedenen Speicherorten adressiert wird. Insgesamt belegt foo also 1 MB, nicht 2 MB.

Mehr zu diesem Thema:

Funktioniert es unter Windows?

Kurze Antwort: Ja. Lange Antwort: Die Verwendung von symbolischen Verknüpfungen unter Windows ist, gelinde gesagt, problematisch, aber pnpm bietet eine Behelfslösung. Für Windows verwenden wir stattdessen Junctions.

Aber der verschachtelte node_modules Ansatz ist nicht mit Windows kompatibel?

Early versions of npm had issues because of nesting all node_modules (see this issue. However, pnpm does not create deep folders, it stores all packages flatly and uses symbolic links to create the dependency tree structure.

Although pnpm uses linking to put dependencies into node_modules folders, circular symlinks are avoided because parent packages are placed into the same node_modules folder in which their dependencies are. So foo's dependencies are not in foo/node_modules, but foo is in node_modules together with its own dependencies.

Ein Paket kann verschiedene Abhängigkeiten auf einem Rechner haben.

In project A foo@1.0.0 can have a dependency resolved to bar@1.0.0, but in project B the same dependency of foo might resolve to bar@1.1.0; so, pnpm hard links foo@1.0.0 to every project where it is used, in order to create different sets of dependencies for it.

Direct symlinking to the global store would work with Node's --preserve-symlinks flag, however, that approach comes with a plethora of its own issues, so we decided to stick with hard links. For more details about why this decision was made, see this issue.

Funktioniert pnpm über mehrere Laufwerke oder Dateisysteme hinweg?

Der Paketspeicher sollte auf dem selben Laufwerk und dem Dateisystem wie die Installation liegen, andernfalls werden Pakete kopiert, nicht verknüpft. This is due to a limitation in how hard linking works, in that a file on one filesystem cannot address a location in another. See Issue #712 for more details.

pnpm funktioniert in den folgenden zwei Fällen anders:

Speicherpfad ist angegeben

If the store path is specified via the store config, then copying occurs between the store and any projects that are on a different disk.

Wenn Sie pnpm install auf Datenträger A ausführen, muss sich der pnpm-Speicher auf dem Datenträger A befinden. Wenn sich der pnpm-Speicher auf der Festplatte B-befindet, werden alle erforderlichen Pakete direkt an den Projektspeicherort kopiert, anstatt verknüpft zu werden. Dies behindert die Speicher- und Leistungsvorteile von pnpm stark.

Speicherpfad ist NICHT angegeben

Wenn der Speicherpfad nicht festgelegt ist, werden mehrere Speicher erstellt (einer pro Laufwerk oder Dateisystem).

If installation is run on disk A, the store will be created on A .pnpm-store under the filesystem root. If later the installation is run on disk B, an independent store will be created on B at .pnpm-store. Die Projekte würden weiterhin die Vorteile von pnpm beibehalten, aber jedes Laufwerk kann redundante Pakete haben.

What does pnpm store prune do? Is it harmful?

Der Befehl pnpm store prune entfernt nicht referenzierte Pakete.

Nicht referenzierte Pakete sind Pakete, die von keinem Projekt auf dem System verwendet werden. Packages can become unreferenced after most installation operations, for instance when dependencies are made redundant.

For example, during pnpm install, package foo@1.0.0 is updated to foo@1.0.1. pnpm will keep foo@1.0.0 in the store, as it does not automatically remove packages. If package foo@1.0.0 is not used by any other project on the system, it becomes unreferenced. Running pnpm store prune would remove foo@1.0.0 from the store.

Die Ausführung von pnpm store prune ist nicht schädlich und hat keine Nebeneffekte auf Ihre Projekte. Wenn zukünftige Installationen entfernte Pakete erfordern, lädt pnpm sie erneut herunter.

It is best practice to run pnpm store prune occasionally to clean up the store, but not too frequently. Manchmal werden nicht referenzierte Pakete erneut erforderlich. Dies kann beim Wechseln von Zweigen und der Installation älterer Abhängigkeiten auftreten, in diesem Fall müsste pnpm alle entfernten Pakete erneut herunterladen, was den Installationsprozess kurzzeitig verlangsamen kann.

Wofür steht pnpm ?

pnpm steht für performantes npm. @rstacruz kam auf den Namen.

pnpm funktioniert nicht mit <IHR-PROJEKT-HIER>?

In den meisten Fällen bedeutet dies, dass eine der Abhängigkeiten Pakete benötigt, die nicht in package.json deklariert sind. Es ist ein häufiger Fehler, der durch flache node_modules verursacht wird. In diesem Fall handelt es sich um einen Fehler in der Abhängigkeit, und die Abhängigkeit sollte behoben werden. Dies kann allerdings einige Zeit in Anspruch nehmen, daher unterstützt pnpm Workarounds, damit die fehlerhaften Pakete funktionieren.

Lösung 1

Im folgenden Beispiel hat eine Abhängigkeit nicht das iterall Modul in der eigenen Liste der Abhängigkeiten.

Die einfachste Lösung, um fehlende Abhängigkeiten der fehlerhaften Pakete zu beheben, besteht darin, iterall als Abhängigkeit zur package.json unseres Projekts hinzuzufügen.

Sie können dies tun, indem Sie es über pnpm add iterall installieren, es wird automatisch der package.json Ihres Projekts hinzugefügt.

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

Lösung 2

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.

Lösung 3

In case there are too many issues, you can use the shamefully-hoist option. This creates a flat node_modules structure similar to the one created by npm or yarn, which is not recommended as avoiding this structure is the primary purpose of pnpm's node_modules approach.

To use it, try pnpm install --shamefully-hoist.