Fehlerhaft: Private GitHub-Repositories mit npm installieren
Die Paketverwaltung npm kann Module nicht nur aus der öffentlichen Registry herunterladen und installieren, sondern auch von GitHub. Das funktioniert aufgrund eines Fehlers in npm unter Node.js 0.12 und io.js allerdings nur bedingt. Wie lässt sich das Problem lösen?
- Golo Roden
Die Paketverwaltung npm kann Module nicht nur aus der öffentlichen Registry herunterladen und installieren, sondern auch von GitHub. Das funktioniert aufgrund eines Fehlers in npm unter Node.js 0.12 und io.js allerdings nur bedingt. Wie lässt sich das Problem lösen?
Node.js stellt Unternehmen, die Closed-Source-Anwendungen auf Basis der Plattform entwickeln, vor ein grundlegendes Problem. Die Anwendungen sollen zwar, wie unter Node.js üblich, zum Zweck der Wiederverwendbarkeit und der Wartbarkeit in kleine und voneinander unabhängige Module zerlegt werden, allerdings dürfen die Module nicht der Allgemeinheit zugänglich sein. Das schließt die Verwendung der öffentlichen Registry aus.
Daraus ergibt sich die Frage, wo und wie sich private Module ablegen und verwalten lassen. Die von npm angekündigte Verwaltung privater Module ist derzeit noch nicht verfügbar. Der Betrieb einer eigenen Registry, beispielsweise auf Basis von npm Enterprise oder Sinopia, ist hingegen häufig zu aufwendig.
Git verwenden
Als Lösung hat sich daher die Verwendung von Git-Repositories etabliert, für die npm besondere Unterstützung enthält. In der Datei package.json lassen sich nämlich bei den Abhängigkeiten nicht nur Versionsnummern aus der öffentlichen Registry angeben, sondern auch Pfade zu Git-Repositories. Dabei werden verschiedene Protokolle wie http, https und ssh unterstützt:
"dependencies": {
"foo": "git+https://user@host:/project/foo.git",
"bar": "git+ssh://user@host:/project/bar.git"
}
Will man dabei nicht stets auf den aktuellen Stand des master-Branchs verweisen, lässt sich optional die ID eines Commits, ein Tag oder der Name eines anderen Branchs angeben:
"dependencies": {
"foo": "git+https://user@host:/project/foo.git#0.1.0",
"bar": "git+ssh://user@host:/project/bar.git#1.3.7"
}
Da npm intern das Kommandozeilenwerkzeug git verwendet, ermöglicht die Verwendung des SSH-Protokolls eine integrierte Authentifizierung, was den Zugriff auch auf nicht öffentliche Repositories erlaubt.
All das funktioniert in npm nicht nur unter Node.js 0.10, sondern auch in Verbindung mit der neuen Version 0.12 und dem Fork io.js.
GitHub verwenden
Aufgrund der Verbreitung und Relevanz von GitHub enthält npm besondere Unterstützung für die Hosting-Plattform. Anstatt den vollständigen Pfad einer Abhängigkeit angeben zu müssen, genügt es, den Benutzer- und Repository-Namen anzugeben:
"dependencies": {
"foo": "acme/foo#0.1.0",
"bar": "acme/bar#1.3.7"
}
Intern wandelt npm einen derartigen Pfad in die zuvor angegebene Syntax um, was das Verwenden von privaten GitHub-Repositories fĂĽr eigene Module besonders komfortabel macht.
Leider hat sich in die von Node.js 0.12 und io.js verwendete Version von npm ein Fehler eingeschlichen: Im Gegensatz zur Version 1.x wandelt npm in Version 2.x derartige Pfade in eine Adresse mit dem Protokoll git+https um. Der Grund für diese Änderung liegt im Modul github-url-from-username-repo, das npm intern verwendet.
Das bedeutet, dass sich Module aus privaten GitHub-Repositories derzeit nicht mehr installieren lassen, sofern sie als Abhängigkeit in der Datei package.json aufgeführt werden. Die Installation über den direkten Aufruf von npm install auf der Kommandozeile funktioniert allerdings.
Abhilfe schaffen
Abhilfe ist prinzipiell auf zwei Wegen möglich. Zum einen lässt sich auf eine alte Version von npm wechseln. Version 1.4.28, die in Node.js 0.10.35 enthalten war, funktioniert beispielsweise wie gewünscht. Dazu genügt es, das folgende Kommando auszuführen:
$ npm install -g npm@1.4.28
Zum anderen ist es selbstverständlich auch möglich, die entsprechenden Einträge in den package.json-Dateien auf die ausführlichere Syntax, die SSH explizit vorsieht, anzupassen. Das erfordert zwar etwas mehr Aufwand, ist aber die für die Zukunft tragfähigere Variante.
tl;dr: Module aus privaten GitHub-Repositories lassen sich mit npm 2.x nicht mehr installieren, sofern sie als Abhängigkeit in der Datei package.json aufgeführt werden. Abhilfe schafft ein Downgrade von npm oder das explizite Anfordern des SSH-Protokolls. ()