Um in der Programmierung nicht immer das Rad neu erfinden zu müssen, gibt es das Konzept der Paketverwaltung. Damit lassen sich Basis-Komponenten installieren und langfristig verwalten. Ein zentraler Bestandteil stellt dabei die Verwaltung der Versionsabhängigkeiten dar. Darüber kann sichergestellt werden, dass eine Anwendung in einer zuvor definierten Version exakt reproduziert werden kann.
Die wohl am weitesten verbreitete Paketverwaltung für PHP heißt Composer. Das Äquivalent in JavaScript ist NPM.
Beide Systeme basieren auf einem ähnlichen Ansatz. Die Abhängigkeiten werden in einer JSON Konfigurationsdatei (composer.json
in PHP bzw. package.json
in JS) definiert. Nach dem „Semantic Versioning“-Standard gibt es dabei verschiedene Möglichkeiten die Versionsangabe innerhalb der Konfigurationsdatei zu definieren.
Versionsangabe | Beschreibung |
---|---|
1.0.0 | Installiert ein Paket exakt in dieser Version. Updates müssen manuell angestoßen werden. |
~3.1.2 | Installiert Pakete >= 3.1.2,<3.2.0 |
~3.1 | Installiert Pakete >= 3.1.0,<4.0.0 |
~0.3 | Installiert Pakete >= 0.3.0,<1.0.0 |
~3 | Installiert Pakete >= 3.0.0,<4.0.0 |
^3.1.2 | Installiert Pakete >= 3.1.2,<4.0.0 |
^3.1 | Installiert Pakete >= 3.1.0,<4.0.0 (Genau wie ~3.1) |
^0.3 | Installiert Pakete >= 0.2.0,<0.4.0 |
^3 | Installiert Pakete >= 3.0.0,<4.0.0 (Genau wie ~3) |
Um diese Abhängigkeiten das Erste mal zu installieren, gibt es den Befehl composer install
bzw. npm install
.
Wird dieser Befehl abgesetzt erstellt die Paketverwaltung eine entsprechende „.lock“-Datei. Diese sollten Sie mit in die Versionierung aufnehmen. In dieser Datei wird zwischengespeichert welche Version installiert wurde.
Existiert bereits eine „.lock“-Datei verhalten sich die beiden Paketverwaltungen jedoch unterschiedlich. Eine erneute Eingabe von composer install
würde dazu führen, dass lediglich die „.lock“-Datei geladen und verarbeitet würde. NPM hingegen würde folgende Abfragen machen:
- Existiert bereits eine package-lock.json? Dann überschreibt sie die Angaben aus der „package.json“.
- Wurde die package.json zwischenzeitlich verändert? Dann wird eine neue package-lock.json erstellt.
Hier in Beispiel
In der package.json
ist eine Abhängigkeit wie folgt definiert:
"depName": "^1.0.0"
nun wird über npm install
eine package-lock.json
mit folgendem Inhalt "depName": "1.0.0"
erstellt.
Einige Tage später veröffentlicht der Paketinhaber die Version „1.1.0“. Führt man nun erneut ein npm install
durch, wird die package-lock.json
Datei ausgelesen und das Paket in der Version 1.0.0 installiert.
Wird im nächsten Schritt die Versionsangabe in der package.json
-Datei manuell auf "depName": "^1.1.0"
erhöht, verhält sich npm install
anders. Es würde nun nicht mehr die package-lock.json
verwenden, sondern das Paket in der Version 1.1.0 installieren und die package-lock.json
mit der neuen Versionsangabe überschreiben.
Dieses Verhalten kann u.U. Nebenwirkungen mit sich bringen. Der Befehl npm ci
schafft Abhilfe und garantiert die Installation aus der package-lock.json
. Gerade in Deploy-Skripten ist dieser Ansatz zu bevorzugen.