UPDATE: Alexanders Antwort ist die bessere Lösung. Ich überlasse meine Antwort der Nachwelt. Der ursprüngliche Punkt meiner Antwort war zu zeigen, dass Sie ein kleines Node-Skript ausführen können, das auf allen Plattformen funktionieren sollte.
In Ihrem Preinstall-Skript können Sie ein Miniknotenscript ausführen, das auf allen Plattformen funktionieren sollte, während Dinge wie pgrep
(und andere übliche * nix-Befehle und -Operatoren) unter Windows erst dann funktionieren, wenn Windows 10 weit verbreitet ist .
Ich habe das folgende Skript auf Node v4.7.0 (npm v2.15.11) und Node v7.2.1 (npm v3.10.10) getestet. Ich nehme an, es funktioniert auf alles dazwischen. Es überprüft die Umgebungsvariablen des aktuell laufenden Prozesses - der npm_execpath
ist der Pfad zum aktuell laufenden "npm" -Skript. Im Fall von Garn sollte es auf /path/to/yarn/on/your/machine/yarn.js
zeigen.
Sie können mehr über npm-Skripte hier lesen: Ссылка
Was die Umgebungsvariable npm_execpath
betrifft, bezweifle ich, dass sie sich jemals ändern wird, auch wenn sie nicht dokumentiert ist. Es ist schon seit mehreren großen Releases von npm
verfügbar und es gibt nicht wirklich den "es gibt einen besseren Namen für diesen" Test.
Wie die anderen Antworten würde ich empfehlen, ein preinstall
-Skript zu verwenden und Ihre Umgebung zu überprüfen. Für eine portable Lösung, die keine falschen Positiven hat, wenn ein anderer npm-Prozess ausgeführt wird, ist die Verwendung von node -e 'JS_CODE'
wahrscheinlich die beste Option.
In diesem JS-Code können Sie den Pfad des Paketmanagers mit folgendem Befehl überprüfen:
%Vor% Das binäre Garn ist yarn.js
, verglichen mit npm-cli.js
, das von NPM verwendet wird. Wir können eine Regex wie die folgende verwenden, um zu überprüfen, dass diese Zeichenfolge mit yarn.js
endet.
Wenn Sie diese Regex verwenden, können Sie sicher sein, dass sie nicht versehentlich irgendwo früher im Dateisystem übereinstimmt. Höchstwahrscheinlich yarn
wird nicht im Dateipfad angezeigt, aber Sie können sich nie sicher sein.
Hier ist ein minimales Beispiel:
%Vor% Natürlich kann der Benutzer diese Überprüfung noch umgehen, indem er die JSON bearbeitet oder die Optionen --ignore-scripts
verwendet:
Sie können den Vorinstallations-Haken zusammen mit einem Shell-Skript verwenden, um dies zu erreichen.
Beispielpaket.json:
%Vor%Wenn Sie einfach testen möchten, ob Pakete unter Garn oder npm installiert werden, habe ich Alexander O'Maras Antwort optimiert leicht, da es für mich auf OS X funktionierte:
%Vor%In diesem kurzen Ausschnitt passiert einiges:
Der \.
-Anteil wird mit Escapezeichen versehen, so dass \
zu \
wird und ein ordnungsgemäß entkoppeltes \.
zur Erkennung eines Zeitraums in der Regex resultiert.
process.exitCode=
kann verwendet werden, um den Beendigungscode des Prozesses festzulegen, und ist sicherer als der Aufruf von process.exit(N)
aufgrund der asynchronen Natur von Node.js.
In Alexanders Beispiel führte throw new Error(\"Use yarn\")
dazu, dass der Knoten mit Code 1 beendet wurde und die Stack-Verfolgung gedruckt wurde %Code%. Sie können versuchen, diese auf der Konsole auszuführen, um zu sehen, wie das funktioniert: stderr
und node -e 'throw new Error("Oops")'
(wodurch der node -e 'throw new Error("Oops")' 2> /dev/null
-Stream auf stderr
gelenkt wird). Dann können Sie überprüfen, dass der Exit-Code 1 war mit /dev/null
(der den letzten Exit-Code ausgibt).
Die% c_de% bedingte Logik der Shell prüft den Beendigungscode von echo $?
und geht für 0 in den Fall if XXXX ; then YYYY ; else ZZZZ ; fi
(jeder andere Wert wird in den Fall XXXX
übernommen). Wenn also die Regex then
am Ende von else
erkennt, gibt sie true zurück. Dies muss negiert werden, damit der Knotenprozess mit Code 0 beendet wird und die yarn.js
erfüllt.
Sie könnten auch process.env.npm_execpath
das Regex-Ergebnis eingeben und die Ausgabe in der Shell vergleichen (das ist nur etwas ausführlicher). Hier einige Beispiele, wie Sie das tun können: Ссылка und Ссылка
Sie können if
oder console.log()
an jede Shell-Anweisung anhängen, um den Exit-Code manuell festzulegen. Zum Beispiel können Sie true ;
oder false ;
versuchen.
Sie können den true ; echo $?
-Anteil auch ganz weglassen, wenn Sie ihn nicht benötigen.
Mit all dem können Sie die Teile false ; echo $?
und else echo npm ;
durch andere Befehle ersetzen. Zum Beispiel könnten Sie mehrere Befehle in eine Subshell wie echo yarn
oder echo npm
setzen.
In meinem Fall musste ich ein Problem umgehen, bei dem eines der Pakete installiert war, aber Bugs unter Garn hatten, so dass ich im Erfolgsfall (echo yarn)
ausführen musste. Beachten Sie, dass dies wahrscheinlich nie in der Produktion gemacht werden sollte, aber es kann ein Lebensretter sein, wenn Sie nur etwas erledigen müssen oder keine Kontrolle darüber haben, welcher Paketmanager im weiteren Verlauf verwendet wird.
Ich habe das unter Windows nicht versucht, also wenn jemand die Syntax dort testen kann, werde ich meine Antwort mit dem, was funktioniert, aktualisieren. Es wäre am besten, wenn das Skript echo $(echo yarn)
sowohl unter Windows als auch unter der Mac / Linux-Shell identisch ist.
Tags und Links node.js npm yarnpkg package.json