Mir ist unter Windows aufgefallen, dass sich npm
seltsam langsam verhält, wenn man es mit Prozessüberwachung ausführt und systemweit ein Proxy konfiguriert ist.
Folgendes Beispiel soll dies veranschaulichen:
PS C:\Users\kirk> Measure-Command {npm -v}
Days : 0
Hours : 0
Minutes : 1
Seconds : 9
Milliseconds : 88
Ticks : 690884385
TotalDays : 0,000799634704861111
TotalHours : 0,0191912329166667
TotalMinutes : 1,151473975
TotalSeconds : 69,0884385
TotalMilliseconds : 69088,4385
Dem geschulten Auge fällt auf: 69 Sekunden Laufzeit?!
Was passiert hier?
Startet man eine Aktion mit npm
wird die gewünschte Aktion flink ausgeführt. Aber um ganz sicher zu gehen, dass es sich auch wirklich um die aktuellste Version von npm
handelt wird ein weiterer Prozess gestartet welcher im Internet nachschaut.
Findet npm
keine neue Version wird vermerkt wann zuletzt nachgeschaut wurde und der Prozess beendet sich.
Das passiert in der Regel so schnell, dass es keinem wirklich auffallen sollte.
Soweit zur Theorie.
Eine eigentlich nützlich erscheinende Funktion stellt sich unter bestimmten Umständen als herausragende "Effektivitätsbremse 2.0" dar.
Hat man sein System vorbildlich auf den Einsatz mit einem Proxy vorbereitet und führt Measure-Command {npm -v}
in einer PowerShell aus wundert man sich über anfangs aufgeführtes Ergebnis.
Schaut man genauer hin stellt man fest, dass dieser Aufruf 2 nodejs
Prozesse startet. Diese bleiben dann in meinem Fall 69 Sekunden da und tuen nichts.
Noch etwas genauer hingeschaut erkennt man, dass einer dieser Prozesse mit folgendem Aufruf gestartet wurde:
"C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\node_modules\update-notifier\check.js" "{\"pkg\":{\"name\":\"npm\",\"version\":\"5.6.0\"}}"
Ok, schauen wir noch genauer hin:
update-notifier ist ein npm
Paket welches eine Abhängigkeit auf latest-version hat. Jenes wiederum ist abhängig von package-json und besitzt seinerseits eine Abhängigkeit auf got.
Ein klein wenig genauer hingeschaut und einem fällt ein Issue ins Auge welches der Ersatz für einen weiteres Issue ist.
Aus diesem möchte ich hier gern den Entwickler zitieren: "I don't really care about proxy support"
Zwischenergebnis
npm
kann für den Umgang mit Proxys konfiguriert werden aber der Check welcher bei jedem Aufruf ausgeführt wird ignoriert die Einstellungen einfach! Dies hat zur Folge, dass der Request zur Versionsabfrage im Nirvana verendet und kein Ergebnis zurückgeben kann. Wenn der Request in das Timeout rennt, stirbt der Prozess und tut nichts weiter.
Daraus folgt, dass beim nächsten Aufruf von npm
der selbe Spaß von vorn los geht.
Was ist jetzt daran das Problem?
Ist der npm
- Aufruf in ein System eingebettet welches die gestarteten Prozesse überwacht beginnt der Hamster schnell zu humpeln. Als Beispiel sei hier ein msbuild
Skript oder die Tasks im TFS genannt.
Der überwachende Prozess wartet natürlich vorbildlich bis alle Kinder des aufgerufenen Programms beendet sind. Dass da dieser sinnlose "Ich warte mal auf eine Versionsinformation aus dem Internet" Prozess dabei ist kann der Aufrufer nicht wissen.
Lösungsvorschläge?
Die sinnvollste Lösung ist aus meiner Sicht einen Konfigurationsparameter für npm
zu haben welcher die Versionsüberprüfung komplett abschaltet.
Gibt es nicht! Nächster!
update-notifier prüft einen Parameter --no-update-notifier
.
Dieser wird von npm
allerdings nicht weitergereicht. Nächster!
update-notifier prüft eine Umgebungsvariable NO_UPDATE_NOTIFIER
. Wenn diese den Wert 1
hat wird die Prüfung übersprungen. Treffer!
Lösung
Auf Maschinen welche nicht auf die Prüfung angewiesen sind und welche Aufgaben mit npm
ausführen sollen ist es ratsam die Umgebungsvariable NO_UPDATE_NOTIFIER
auf den Wert 1
zu setzen.
Ergebnis
PS C:\Agents> Measure-Command {npm -v}
Days : 0
Hours : 0
Minutes : 0
Seconds : 1
Milliseconds : 785
Ticks : 17855814
TotalDays : 2,06664513888889E-05
TotalHours : 0,000495994833333333
TotalMinutes : 0,02975969
TotalSeconds : 1,7855814
TotalMilliseconds : 1785,5814
Schon irgendwie besser.
Anmerkungen
Das hier beschriebene Verhalten ist bereits in einem Issue im npm
Projekt erfasst.
Ich konnte leider nicht prüfen ob auch andere Systeme als Windows davon betroffen sind.
Das Setzen der Umgebungsvariable NO_UPDATE_NOTIFIER
hat zur Folge, dass das für alle Pakete deaktiviert wird welche update-notifier verwenden.