Fragen rund um die package-lock.json

Klemens Kühle
coodoo
Published in
4 min readFeb 19, 2021

--

Die rätselhafte Datei package-lock.json.
Sie wird gelöscht, sie sorgt für Merge-Konflikte, sie wird nicht richtig verstanden. Hier eine Übersicht, wozu sie dient, welche Fragen sie aufwirft sowie Antworten darauf.

Beschreibung

Projekte, die auf den Paketmanager npm von Node.js basieren, kennen seit npm Version 5 neben der package.json auch eine package-lock.json. Sie wird automatisch für alle Vorgänge generiert, bei denen npm-Befehle entweder den node_modules-tree oder die package.json modifizieren. Sie beschreibt den genauen erzeugten Abhängigkeiten-Baum. Nachfolgende Installationen, zum Beispiel auf anderen Geräten, können mit ihr den identischen Baum erzeugen — unabhängig von zwischenzeitlichen Aktualisierungen der Abhängigkeiten.

In den npm-Docs werden vier Punkte genannt, wozu sie genau dient:

  • Sie repräsentiert den kompletten Abhängigkeitsbaum des Projekts, sodass bei Kollegen, bei Deployments oder bei Continuous-Integration garantiert die gleichen Abhängigkeiten installiert werden.
  • Sie bietet Entwicklern die Möglichkeit “Zeitreisen” zu früheren Zuständen von node_modules vorzunehmen, ohne das Verzeichnis selbst committen zu müssen.
  • Sie ermöglicht eine bessere Einsicht von Änderungen am Abhängigkeitsbaum durch lesbare Quellcode-Diffs.
  • Sie optimiert den Installationsprozess, indem npm die wiederholte Auflösung von Metadaten für bereits installierte Pakete überspringt.

Klingt erstmal ganz einleuchtend. In der Praxis gibt es dennoch oft Gerüchte um und Probleme mit dieser Datei. Daher hier ein paar mir häufig begegnete Aspekte als FAQ:

FAQ

Trivia: Es gibt im Netz zu verschiedenen Fragen unterschiedliche Meinungen, da die package-lock.json ihre Funktionalität nach ihrer Einführung in npm v.5.0.0 sogleich mit npm v5.1.0 konzeptionelle Änderungen durchgemacht hat (siehe diese Diskussion in Stackoverflow, in der jemand gut zusammengefasst hat, wie paradox diese changes vom weltgrößten package-manager sind).

F: Warum braucht man eine package-lock.json?
A:
Die oben genannten Punkte der npm-Docs geben Aufschluss über ihren Dienst. Was ich lange nicht verstanden habe, ist, dass die package-lock.json auch die Abhängigkeiten der Abhängigkeiten festzurrt, auf die ich in der package.json keinen Einfluss habe. Wenn ich eine library auf einer spezifischen Version fix einbinde, aber diese ihre eigenen Abhängigkeiten mittels version ranges einbindet (bsp. ‘~1.2.3’, ‘^2.3.4’ oder ‘>=3.4.5’), habe ich ohne lock keinen Einfluss darauf, ob bei einem nächsten npm install meine eingebundene library eine andere Version ihrer Abhängigkeiten installiert und somit wohmöglich Funktionalität geändert wird, die mein System braucht.

F: Sollte ich die package-lock.json löschen?
A:
Wenn keine package-lock.json mehr vorliegt, werden bei einem Install die in der package.json beschriebenen packages in ihren Versionen, sowie deren Abhängigkeiten in ihren Versionen oder eventuell auch aktuellere installiert. So kann es passieren, dass Funktionen gebrochen werden. Daher sollte man sie nicht löschen.

F: Sollte ich die package-lock.json in mein Versionierungstool einchecken?
A:
Ja, die npm-Docs selbst empfehlen es, damit Kollegen und tools bei deployments oder bei continuous-integration den exakt gleichen Abhängigkeitsbaum erstellen können.

F: Warum bekomme ich immer Merge-Konflikte in der package-lock.json?
A:
Im dritten der oben genannter Punkte wozu die package-lock.json dient, wird “eine bessere Einsicht […] durch lesbare Quellcode-Diffs” aufgezählt, dennoch beschweren sich Nutzer oft über das Gegenteil. Wenn man von dem von npm empfohlenen Umgang mit ihr ausgeht, gibt es Änderungen nur bei neuen Installationen oder Aktualisierungen von Abhängigkeiten. Als Fazit daraus könnte man ziehen, dass man sich im Team besser absprechen muss, wenn es bei parallel laufenden Aufgaben zeitgleich zu Änderungen oder Erweiterungen der Abhängigkeiten kommt.

F: Kann ich nicht einfach alle Versionen selbst festzurren? Wozu dienen SemVer-Ranges?
A:
Beim Installieren einer neuen Abhängigkeit installiert npm diese, wenn keine Version angegeben wird, in der aktuellsten Version und stellt der Versionsnummer ein ‘^' voran. Hierbei handelt es sich um eine spezifische Wildcard, auch SemVer-Ranges genannt. Von npm genutzte Ranges für die SemVer-Struktur von MAJOR.MINOR.PATCH sind eben beschriebenes ‘^', welches MINOR-Updates erlaubt und ‘~’, welches PATCH-Updates erlaubt. MAJOR-Updates könnte man auch per ‘*’ erlauben, ist aber nicht wirklich empfehlenswert, da man diese definitiv überlegt angehen sollte, denn laut SemVer-Pattern finden hier definitiv Brüche in der API statt.

npm — About semantic versioning
Der in den npm-docs empfohlene Umgang mit Releases und deren Versionierung, der leider nicht immer eingehalten wird und auf den man daher beim Aktualisieren von Abhängigkeiten nicht blind vertrauen sollte.

Installierte Abhängigkeiten mit Ranges werden nicht automatisch aktualisiert. Die Ranges dienen vor allem dem Maintainer des Projektes, der mittels Tooling wie npm update oder npm outdated einen Überblick behalten kann, welche libraries neue Updates haben und aktualisiert werden können.

Fazit

Dies ist natürlich eine sehr subjektive Auswahl an Fragen und Antworten, die aber eben genau die Aspekte angehen, die mir persönlich nach einiger Zeit der Nutzung von npm via Angular immer wieder begegneten. Dennoch hoffe ich, dass es vielleicht dem Einen oder Anderen einen besseren Überblick verschafft über die praktische Datei package-lock.json.

Weiterführende Links

npm:
- npm ci — npm-Docs: Install-Befehl abhängig von der package-lock.json
package-lock.json:
- npm-Docs über package-locks — Immer die Doku lesen!
- Blog-Artikel dev.to — Basics über package-lock.json, aber interessant, da Kat Marchán, die die Datei zu npm hinzugefügt hat, darunter kommentierte.
SemVer:
- SemVer-Cheatsheet — ein schneller Überblick über die Struktur von SemVer.
- SemVer-Calculator — praktisch um Ranges zu überprüfen.
- Why Semantic Versioning Isn’t — Interessante Gedanken, warum SemVer “in Ordnung für Roboter, aber schlecht für uns” ist.

--

--