Was sind Lockdateien?

Pakete sind ein wichtiger Bestandteil eines Projekts. Sie ermöglichen es uns, die verschiedensten Frameworks und Bibliotheken in unserem Projekt zu nutzen. Doch auch Pakete werden stetig weiterentwickelt und verbessert. So kann es im schlimmsten Fall vorkommen, dass das Paket nach einem Update Fehler produziert. Um das zu vermeiden, wollen wir die funktionierenden Paketversionen speichern. Hier kommen Lockdateien ins Spiel.

Paketversionen in der package.json

Die package.json ist die zentrale Konfigurationsdatei unseres Projektes. Hier definieren wir alle wichtigen Projektinformationen: den Namen, die Version, die Autoren usw.
Außerdem werden in der package.json alle im Projekt benutzten Pakete und die gewünschte mindest Versionsnummer gespeichert.

{
    "dependencies": {
        "axios": "~1.2.3",
        "next": "14.2.5",
        "nextjs-routes": "^2.2.1",
        "react": "^18.3.1",
        "react-dom": "^18.3.1"
    }
}

Jeder Package Manager (z. B. npm oder yarn) installiert die aktuellsten Versionen der unter dependencies definierten Pakete. Das kann jedoch durch die Benutzung der Versionsprefixen ~ und ^ oder der Angabe der exakten Versionsnummer gesteuert werden:

  • Wird die exakte Versionsnummer angegeben, z. B. "next": "14.2.5" , wird jedes Mal beim Ausführen von npm install die Version 14.2.5 von next installiert
  • ^ updated das Paket automatisch auf die nächste Minorversion. Falls verfügbar, würde bei npm install also automatisch die Version "1.3.0" des "axios" Paketes installiert werden. Es wird aber nie auf die nächste Mainversion 2.0.0 updaten.
  • ~ updated das Paket automatisch auf die nächste Patchversion. So würde react bei npm install höchstens auf Version 18.3.2 updaten. Die höchste Version, die installiert werden würde, wäre 18.3.9. Also wird nie auf die nächste Minorversion 18.4.0 geupdatet.

Je nach verwendetem Package Manager haben die Dateien einen anderen Namen oder einen minimal anderen Aufbau. Im Kern enthalten sie aber alle die gleichen Informationen.

Die genaue Definition der Versionsnummern ist wichtig, um zu verstehen, was die package.json von anderen Lockdateien, wie zum Beispiel der npm Lockdatei package-lock.json unterscheidet.

Unterschiede zwischen package.json und Lockdateien

Wie schon erwähnt, müssen die in der package.json definierten Versionen nicht den installierten Versionen entsprechen. Diese "Versionsspielräume" werden als version ranges bezeichnet. Durch diese version ranges kann es vorkommen, dass beim Installieren der Pakete jedes Mal unterschiedliche Versionen des Paketes geladen werden.

Um immer die gleichen Versionen eines Paketes laden zu können, müssen die exakten Versionsnummern gespeichert werden. Dafür gibt es die Lockdatei. Hier werden alle genauen Versionsnummern der installierten Pakete und deren Unterpakete gespeichert. So wird sichergestellt, dass alle benötigten Pakete immer mit der vom Entwickler gewünschten und bei der Entwicklung des Projekts verwendeten Version installiert werden.

Wichtig hierbei zu erwähnen ist, dass die definierten Paketversionen nur für das Hauptpaket gelten. Die jeweiligen Pakete haben natürlich noch eigene Paketabhängigkeiten, die auch mit version ranges definiert werden. Das kann dazu führen, dass beim Installieren der Pakete andere Versionen der Unterpakete installiert werden als zuvor. Das kann wiederum zu Fehlern führen. In den Lockdateien werden deswegen auch die Versionen der Unterpakete gespeichert. Wie man ein Paket sicher auf die nächste Version updated findet Ihr in unserem Blogbeitrag zum richtigen Dependencies updaten .

Wieso meine Lockdatei auch für andere wichtig ist

Wenn nun alle Pakete, die in der package.json definiert sind, installiert werden sollen (z. B. npm install, yarn install), und keine Lockdatei im Projektordner liegt, werden die aktuellsten Versionen (abhängig von den version ranges) installiert. Falls aber eine Lockdatei im Projektordner vorhanden ist, werden die Pakete in der Version installiert, die in der Lockdatei hinterlegt ist.

Es ist wichtig, die Lockdatei in das Projektrepository zu pushen! Das bringt entscheidende Vorteile:

  1. Man stellt sicher, dass alle Entwickler mit den gleichen Paketversionen arbeiten. So wird verhindert, dass es durch unterschiedliche Paketversionen zu unterschiedlichem Verhalten der App kommt.
  2. Änderungen der Paketversionen werden direkt im Pullrequest und beim Review deutlich.
  3. Es ist immer eine klare Historie vorhanden, an der man sehen kann, mit welchem Pullrequest welche Paketversion geändert wurde.
  4. So wird auch sichergestellt, dass das Projekt in der Produktionsumgebung genauso läuft wie beim lokalen Entwickeln oder in der Testumgebung.

Lockdateien stellen also vor allem sicher, dass jeder Entwickler jederzeit mit den korrekten und identischen Paketversionen arbeitet.