Warum Mole weniger npm-Cache löscht als npm cache verify
Ein Nutzer schrieb kürzlich, dass der npm-Cache nach einem Wartungsdurchlauf von Mole noch da war und nach seiner eigenen Bereinigung von 8 GB auf 2 GB schrumpfte. Das war der Anlass, Entwickler-Caches erneut anzusehen: Welche Dateien werden noch gebraucht, welche haben ihre Verweise verloren, und welche Werkzeuge räumen bereits selbst auf, sodass Mole nur die nächste Kompilierung verzögern würde?
Die Untersuchung und Änderungen stammen vom 5. Oktober. Sie sind im Quellcode für eine kommende Version enthalten; das derzeit veröffentlichte Preview-Paket enthält sie noch nicht.
Warum der npm-Cache weiter wächst
Der Standard-Cache von npm liegt unter ~/.npm/_cacache. content-v2 speichert Pakete und Registry-Antworten, während index-v5 Anfragen diesen Inhalten zuordnet. Dateien sind nach ihrem Inhaltshash benannt; mehrere Indexeinträge können auf dieselbe Datei zeigen.
Ändern sich Paketmetadaten, schreibt npm eine neue Antwort. Spätere Abfragen können ältere Indexeinträge entfernen, ohne deren Inhaltsdateien zu löschen. So bleiben Dateien ohne Indexverweis zurück. Auch die npm-Dokumentation erklärt, dass der Cache Daten nicht selbst entfernt und mit weiteren Installationen wächst.
Der Nutzer hatte seinen Cache bereits bereinigt. Eine vorherige Kopie und der genau ausgeführte Befehl waren daher nicht verfügbar. Der Rückgang von 8 GB auf 2 GB ist der Ausgangspunkt der Untersuchung, keine Messung von 6 GB, die Mole freigegeben hätte, und kein Beleg dafür, dass diese 6 GB vollständig ohne Verweise waren.
Was verify in diesem Versuch gelöscht hat
Das Experiment verwendete Kopien des Caches dieses Macs mit npm 11.19.1 und cacache 20.0.4. Das Original blieb unverändert. Der Cache war etwa einen Tag alt und enthielt 309796162 Byte an gespeicherten Inhalten, also keine über Monate gewachsene Sammlung.
| Kriterium | Dateien | Größe in Byte |
|---|---|---|
| Von keinem gültigen Indexeintrag referenziert | 1 | 614295 |
Von npm cache verify tatsächlich gelöscht |
6 | 25469972 |
Der Unterschied liegt in der verify-Implementierung von cacache. Sie bereinigt Inhalte, prüft ihre Integrität und baut den Index neu auf, wobei für jeden Schlüssel der letzte Eintrag erhalten bleibt. Ältere Einträge können aber vollständige und verkürzte Metadaten für unterschiedliche Anfragen enthalten. Das sind nicht einfach alte und neue Fassungen derselben Antwort.
Auf der Kopie waren 11199796 der von verify gelöschten Bytes noch durch gültige Einträge einer anderen Anfragevariante referenziert. Einige Paketinformationen waren vor der Bereinigung offline lesbar und lieferten danach bei offline ausgeführtem npm view den Fehler ENOTCACHED. Online ließen sie sich erneut abrufen, doch der Cache verhielt sich anders als zuvor.
Mole wählt deshalb die engere Regel: Solange ein gültiger Indexeintrag auf eine Datei verweist, bleibt sie erhalten. Nur ungefähr 0,6 MB in dieser Stichprobe zu finden, rechtfertigt nicht, eine brauchbare Variante zu entfernen, um dem Ergebnis von verify näherzukommen.
Ungenutzte Dateien entfernen, den gesamten Cache nur auf Wunsch
Die neue Implementierung untersucht nur den Standardpfad ~/.npm/_cacache. Nicht referenzierte Inhalte, die älter als einen Tag sind, erscheinen als eine vorausgewählte Zeile im Bereich für Entwicklerwerkzeuge. Der gesamte npm-Cache bleibt eine gesondert zu prüfende Auswahl; überlappende Auswahlen zählen dieselben Bytes nur einmal.
Solange Befehle wie npm install oder npm ci in den Cache schreiben, bietet Mole diese Dateien nicht zur Bereinigung an. Auch bei einem unlesbaren Index bleiben sie aus der Liste. Vor dem Löschen werden die Verweise erneut geprüft; Indexdateien und temporäre Verzeichnisse bleiben unverändert. Mole führt im Hintergrund keinen npm-Bereinigungsbefehl aus.
Indexverweise zu erhalten garantiert nicht, dass jedes Projekt dauerhaft offline gebaut werden kann. Eine Lockdatei kann ein Paketarchiv direkt über seinen Hash anfordern, und private Registrys oder alte Versionen bleiben möglicherweise nicht verfügbar. Quellcode, Lockdateien und nicht wiederherstellbare Build-Ergebnisse müssen gesondert erhalten werden. Eigene npm-Cache-Pfade sind von dieser Änderung nicht abgedeckt.
Go, Cargo und pnpm brauchen unterschiedliche Entscheidungen
Go bereinigt seinen Build-Cache bereits selbst. Seine Implementierung erhält Einträge, die in den letzten fünf Tagen verwendet wurden, mit einer zusätzlichen Stunde Spielraum, also 121 Stunden. Mole bot zuvor das ganze Build-Cache-Verzeichnis zur vorausgewählten Bereinigung an. Nun gilt dieselbe Altersregel, damit kürzlich verwendete Einträge erhalten bleiben und nicht erneut kompiliert werden müssen.
Cargo hat eine automatische Cache-Bereinigung, und in dieser Stichprobe war nichts abgelaufen. Nachdem zuvor entpackte Registry-Quellen entfernt worden waren, folgten etwa 29 Stunden später rund 157 MB Downloads und 1,06 GB entpackte Daten. Mole ergänzt für diesen Speicher keine eigene automatische Bereinigung. Die vorhandenen Einträge zur manuellen Prüfung bleiben verfügbar.
Der gemeinsame Speicher von pnpm ist wieder anders. In der untersuchten APFS-Stichprobe bewies die Anzahl der Hardlinks nicht, dass Dateien ungenutzt waren; das übernommene Kriterium hätte den gesamten Speicher ausgewählt. Für pnpm wurde deshalb keine zusätzliche automatische Bereinigung eingebaut. Dafür müsste die Anzahl der Hardlinks auf diesem Dateisystem tatsächlich erkennen lassen, ob eine Datei noch genutzt wird.
Build-Ergebnisse globaler Werkzeuge und alter Xcode-Projekte
Das global installierte pake-cli enthielt ein etwa 1,48 GiB großes Verzeichnis src-tauri/target: von Rust erzeugte Dateien beim Kompilieren der Tauri-Anwendung, kein npm-Download-Cache. Solche Build-Verzeichnisse mit einer gültigen, vom Werkzeug geschriebenen CACHEDIR.TAG werden jetzt zur Prüfung angeboten. Das installierte Werkzeug und seine node_modules-Abhängigkeiten bleiben erhalten; während eines Rust-Builds werden diese Verzeichnisse nicht angeboten.
Die Untersuchung fand außerdem 24 Xcode-DerivedData-Verzeichnisse mit etwa 9 GiB, deren gespeicherte Projektpfade nicht mehr existierten. Ein ganzes Verzeichnis wird nur angeboten, wenn das Projekt auf dem Startvolume nachweislich fehlt und Xcode den zugehörigen Cache seit mindestens zwei Wochen nicht verwendet hat. Ein abgezogenes externes Laufwerk oder fehlende Leserechte beweisen kein gelöschtes Projekt. Diese Größen wurden bei der Untersuchung gemessen und sind keine Zusage, dass auf jedem Mac ebenso viel Platz frei wird; erneutes Erzeugen kostet ebenfalls Zeit.
Vorher klären, welche Ebene bereinigt wird
Dieser nur lesende Befehl fragt npm nach seinem tatsächlichen Cache-Pfad, einschließlich eigener Einstellungen.
npm config get cache
Wenn Installationen und Builds nicht mehr in diesen Cache schreiben, lässt sich entscheiden, ob npm cache verify ausgeführt werden soll. Der Befehl verändert den Cache und ist keine reine Abfrage. Projektbezogene node_modules und global installierte Befehle werden von diesem Befehl nicht bereinigt. Der Leitfaden für Entwickler-Caches beschreibt den gesamten Ablauf.