Ein Node-Projekt von npm auf pnpm umstellen, ohne das Team zu stören
npm gegen pnpm im Hinblick auf die Dateistruktur, Phantom-Abhängigkeiten und Lockfiles, anschließend eine Migration eines Node.js-Teams mit pnpm import, only-allow sowie einem festgelegten packageManager-Feld.
Quellen: Switching from npm to pnpm
Paketmanager entscheiden darüber, wie Abhängigkeiten auf der Festplatte abgelegt werden, welches Lockfile kommittet wird und wie streng die Importregeln gelten, wenn etwas schiefgeht. Für viele Node-Projekte ist npm nach wie vor die Standardwahl. Teams, die mehrere Repositorien verwalten, müssen zudem ständig mit Sicherheitshinweisen umgehen, die ein Erhöhen der Version fordern. Dependabot kann einige dieser Updates automatisch durchführen; andere Upgrades erfordern manuelle Arbeit, weil transitive Fixes miteinander kollidieren oder weil die dauerhafte Lösung darin besteht, ein Paket vollständig auszutauschen.
Ungefähr zur gleichen Zeit passte GitHub Dependabot so an, dass nicht-sicherheitsrelevante Version-PRs drei Tage warten müssen, bevor sie geöffnet werden. Diese Richtlinienänderung steht im Großen und Ganzen nicht in Zusammenhang mit der Wahl des Paketmanagers, signalisiert aber, wie störend automatische Updates geworden waren.
In der Zwischenzeit tauchen immer wieder Vorfälle in der Lieferkette in den Schlagzeilen auf. Kompromittierte oder anfällige Pakete befinden sich in Anwendungen, die Icon-Sete, Authentifizierungs-Hilfsprogramme sowie Token-Tools verwenden, wodurch sich der Ausbreitungsbereich mit jeder weiteren Verknüpfung vergrößert. Sicherheitswarnungen kommen selten einzeln. Ein Laptop, der einige Dienste kloniert, erhält in derselben Woche Warnungen bezüglich transitiver Parser, UI-Kitse sowie Authentifizierungs-Middlewares. Automatische Bots helfen, wenn das Problem mechanischer Natur ist; sie stoßen jedoch auf Schwierigkeiten, wenn eine neue Version APIs umschreibt oder zwei Abhängigkeiten sich bezüglich eines gemeinsamen Partners nicht einigen können. In solchen Fällen ist es berechtigt, zu fragen, ob der Installer selbst das Risiko verringern kann – indem er falsche Abhängigkeiten ablehnt, Inhalte auf der Festplatte gemeinsam nutzt, sodass bei Prüfungen nur eine Kopie einer Version sichtbar ist, und indem er völlig neue Veröffentlichungen verlangsamt, bis das Ökosystem sie überprüft hat.
Ein häufig vorgeschlagener Tausch ist npm gegen pnpm: ähnliche alltägliche Befehle, ein strengeres Installationsmodell und in der Regel weniger Festplattenbelastung. Die folgenden Abschnitte vergleichen die beiden Tools, ohne einen universellen Gewinner zu behaupten – lediglich genügend Details, um zu entscheiden, ob ein Wechsel die Migrationskosten lohnt.
Allgemeine Informationen zu npm / pnpm
Ein kurzer Überblick zu jedem Tool:
npm
- Kommt standardmäßig mit Node.js als Paketmanager.
- Übernimmt die Installation von Abhängigkeiten sowie die Verwaltung der
package.json-Skripte. - Zu den gängigen Befehlen gehören
npm install(Installation aus dem Lock/Manifest),npm install <Name>(Hinzufügen einer Abhängigkeit),npm run <Skript>undnpm uninstall <Name>. - Erstellt die Datei
package-lock.json. - Lagert die Pakete unter
node_modulesab.
npm liefert außerdem npx mit, das ein Paket ausführt, ohne es im Projekt hinzuzufügen oder global zu installieren. Scaffold-Tools wie npx create-vite@latest project-name laden temporär herunter, führen es aus und lassen package.json unverändert. Der Unterschied zu npm install ist beabsichtigt: einmalige Ausführung im Gegensatz zu einer dauerhaften Abhängigkeit.
pnpm
- Ein von Dritten entwickelter Paketmanager mit derselben Funktionalität – Abhängigkeiten und Skripte – der sich jedoch anders auf der Festplatte strukturiert.
- Die bekannten Befehle sind ähnlich:
pnpm install,pnpm add <name>,pnpm run <script>,pnpm remove <name>. - Er benötigt in der Regel weniger Speicherplatz und führt Installationen schneller durch, da jede Version nur einmal gespeichert wird.
- Er beschränkt die Importe auf das, was in
package.jsondeklariert ist.
pnpm-lock.yaml anstelle von package-lock.json verwendet.Der einmalige Ausführer, der npx ähnelt, ist pnpm dlx – nützlich beispielsweise beim Erstellen von Projekten mit create-vite in der neuesten Version. Viele Generatoren akzeptieren ebenfalls pnpm create. Für Binärdateien, die bereits in node_modules vorhanden sind, dient pnpm exec als lokaler Ausführer.
Vorteile und Nachteile von pnpm
Ausgleichsbedarf ist genauso wichtig wie Slogans:
- npm kopiert Pakete in das
node_modulesjedes Projekts, wodurch Inhalt in verschiedenen Repositorien doppelt vorhanden ist; pnpm behält eine eindeutig adressierbare Kopie pro Version bei und verknüpft die Projekte damit. - Diese Struktur verringert in der Regel den Festplattennutzung und beschleunigt wiederholte Installationen.
- Npm ermöglicht aufgrund seiner historisch flacheren Auflösung, dass Code ein Paket verlangt, das nie deklariert wurde; pnpm weist solche nicht deklarierten Importe ab, wodurch die unbeabsichtigte Angriffsfläche verringert wird.
- Durch die verzögerte Übernahme brandneuer Versionen durch pnpm sinkt die Wahrscheinlichkeit, sofort eine kompromittierte Veröffentlichung herunterzuladen.
- Npm hat im Laufe der Zeit ähnliche Funktionen hinzugefügt, doch einige bleiben weiterhin optional und nicht standardmäßig aktiviert.
- PNPM erfordert einen separaten Installierungs Schritt; npm ist bereits mit Node enthalten.
- Ältere Plugins, die von Npm’s Struktur ausgehen, müssen unter Pnpm’s strengeren Verknüpfungsregeln möglicherweise angepasst werden.
- Die „Muskelgedächtnisse“ der Teams neigen weiterhin zu Npm, wodurch eine Einarbeitung in Pnpm einen kurzen Anpassungszeitraum erfordern kann.
Unterschiede im Dateisystemlayout treten schnell bei CI-Servern auf, die node_modules unzureichend cachen, sowie bei Entwicklerrechnern, auf denen Dutzende von Anwendungen gespeichert sind. Content-addressable Storage bedeutet, dass das zweite und dritte Projekt, die lodash@4.x benötigen, in der Regel nur Verweise erstellen anstelle eines weiteren vollständigen Dateisystems. Eine strengere Sichtbarkeit der Abhängigkeiten verändert außerdem das Debuggen: Wenn eine Importierung fehlschlägt, weil das Paket nie deklariert wurde, tritt der Fehler bereits bei der Installation oder beim Typprüfen deutlich zutage, anstatt erst zur Laufzeit überraschend aufzutauchen – und zwar nur, weil ein anderes Paket es zufällig mit eingebunden hat.
Auf pnpm umsteigen
Eine minimale globale Installation sieht so aus:
// Installation command (once)
npm install -g pnpm
// Usage
pnpm install
pnpm add [package name]
pnpm run [script name]
pnpm remove [package name]
Nach der ersten erfolgreichen Installation in einem Projekt sollte pnpm-lock.yaml neben (und letztendlich anstelle von) package-lock.json vorhanden sein.
Es existieren weitere Installationsmethoden, darunter eigenständige Skripte; die pnpm-Installationsdokumentation listet sie auf.
Beim Migrieren eines bestehenden npm-Projekts bedeutet dies in der Regel das Löschen von node_modules und package-lock.json, gefolgt vom Ausführen von pnpm install. Die meisten Anwendungen funktionieren danach einwandfrei; unhandliche native Erweiterungen oder veraltete Resolver erfordern möglicherweise einmalige Korrekturen.
Um Versionen aus einer vorhandenen Lockdatei einzubringen, führt man pnpm import aus. Um npm-Überreste zu beseitigen:
// For macOS/Linux/Git Bash:
rm -rf node_modules package-lock.json
// For Windows PowerShell:
rm -Recurse -Force node_modules, package-lock.json
Um ein zufälliges npm install später zu verhindern, fügt man einen preinstall-Guard hinzu:
"scripts": {
"preinstall": "npx only-allow pnpm"
}
Dann fügt man den Hilfsprogramm als Entwicklungskomponente hinzu:
pnpm add -D only-allow
Die Festlegung der genauen CLI für Mitwirkende erfolgt über das Feld packageManager (ersatzweise kann die Versionszeichenkette angepasst werden):
{
"packageManager": "pnpm@11.22.0"
}
Dieser Pin hält CI-Systeme und Laptops bei derselben CLI-Version; vergessen Sie nicht, ihn absichtlich anzupassen, wenn das Team ein Upgrade durchführt.
Überprüfen und selbst aktualisieren mit:
pnpm --version
pnpm self-update
Falls die Selbstaktualisierung Probleme verursacht, installieren Sie pnpm global mit npm install -g pnpm und starten Sie die Shell neu.
Nach einem erfolgreichen Wechsel sollten Sie Folgendes sehen:
package-lock.jsonist verschwunden.pnpm-lock.yamlist vorhanden.package.jsonbleibt unverändert, außer bei den von Ihnen hinzugefügten Pins oder Skripten.node_moduleswurde unter Verwendung von pnpms Linker neu erstellt (oder durch einen neuenpnpm installerzeugt).- Tägliche Befehle unterscheiden sich meist nur durch den Namen des verwendeten Tools.
- Einzelmalige Ausführungen über
pnpm dlxanstelle vonnpx.
Die offizielle Dokumentation bleibt der richtige Ort, um Randfälle zu untersuchen; die oben genannten Hinweise reichen aus, um die Migration zu bewerten und einen routinemäßigen Umstieg durchzuführen.
Betrachten Sie das erste migrierte Repository als Probe: Führen Sie den Testsuite aus, überprüfen Sie, ob die Docker-Builds weiterhin funktionieren, und stellen Sie sicher, dass alle nativen Erweiterungen unter dem neuen Linker kompiliert werden. Sobald dieser Prozess reibungslos abläuft, sorgt das Verwenden desselben packageManager-Werts sowie der gleichen only-allow-Einschränkung in den verwandten Diensten dafür, dass die gesamte Infrastruktur konsistent bleibt. Falls ein veraltetes Tool tatsächlich die Struktur von pnpm nicht unterstützt, isolieren Sie es lieber, anstatt überall andere, strengere Standards aufzugeben.