JavaScript >> Javascript-Tutorial >  >> Tags >> npm

Keine globalen Npm-Pakete mehr

Die JavaScript-Entwickler-Community begrüßt jedes Jahr Dutzende neuer und leistungsstarker Tools, fast zu schnell, als dass Sterbliche damit Schritt halten könnten. Viele dieser Tools werden mit npm-Paketen geliefert, die Sie global installieren können, sodass Sie das Befehlszeilentool von überall auf Ihrem Computer verwenden können. Das kann sehr bequem sein, ist aber richtig Weg, es zu tun? Gibt es eine bessere Alternative?

Ist es richtig?

Ja, das ist es sicher… aber nein. Na, was ist das!?!? Beide. Wenn Sie mit einem Tool experimentieren oder es nur allgemein verwenden, können Sie es gerne als globales Befehlszeilentool verwenden. Wenn Ihr Projekt tatsächlich von dem Tool abhängig ist, ist die globale Installation wahrscheinlich nicht der beste Weg.

Warum nicht? Nun, wie so ziemlich jedes Paket auf npm sind die Befehlszeilentools versioniert. Wenn Ihr lokaler Computer/Entwicklungscomputer über eine andere Version des Tools verfügt als ein anderer Computer, auf dem dieses Tool für dieses Projekt ausgeführt werden muss, kann es zu Inkompatibilitäten kommen. Es wäre schön, wenn wir eine Option hätten, globale Abhängigkeiten innerhalb von package.json zu speichern , aber ehrlich gesagt ein Paket Datei sollte global nicht enthalten Dienstprogramme, wie in einem GitHub-Problem für npm besprochen.

Grunt hat dieses Problem gut minimiert, indem es ein separates npm-Paket für das CLI-Tool erstellt hat, das extrem minimal ist, sodass Sie es mit minimalen Inkompatibilitätsrisiken global installiert lassen können. Es gibt jedoch immer noch keine Garantien.

Was ist die Alternative?

npm ist die Alternative. Insbesondere sollten Sie Ihre Entwicklungstools in devDependencies aufnehmen in package.json . So können sie für jedes Projekt versioniert werden. Aber wie führen Sie es dann auf der Befehlszeile aus? Niemand möchte node ./node_modules/.bin/grunt eingeben müssen jedes Mal, wenn sie einen Grunt-Befehl ausführen möchten. Während dies für die meisten Tools funktionieren würde, gibt es einen etwas einfacheren Weg:npm-Skripte. Sie können npm run WHATEVER verwenden um jeden Befehl auszuführen, den Sie in scripts eingeben Abschnitt Ihres package.json Datei, und wenn Sie auf einen Befehl verweisen, der auf dem PATH Ihres Computers nicht vorhanden ist, durchsucht er die Knotenmodule Ihres Projekts danach.

Zum Beispiel, wenn Sie die Grunt-CLI nicht global installiert hatten, aber diese in Ihrem package.json hatten Datei:

1
2
3
4
5
6
7
8
9
10
11
12
...
devDependencies: {
"grunt-cli": "~0.1",
"grunt": "~0.4",
"grunt-contrib-jshint": "~0.6",
...
},
scripts {
"lint": "grunt lint",
...
},
...

… Sie könnten npm run lint ausführen und es würde grunt lint ausführen korrekt. Wenn Sie npm v2 oder höher verwenden, können Ihre npm-Skripte außerdem Argumente akzeptieren:

1
2
3
4
5
6
...
scripts {
"grunt": "grunt",
...
},
...

Jetzt können Sie npm run grunt -- lint ausführen und es wird grunt lint ausgeführt . Diese neue Funktion mit Version 2 ermöglicht uns die Verwendung von -- um Argumente an den Befehl zu übergeben, den npm ausführt. Sie können dies auch verwenden, um sicherzustellen, dass einige Optionen immer an Ihre bevorzugten Befehle weitergegeben werden. Zum Beispiel können Sie Grunt immer im ausführlichen Modus laufen lassen, ohne ihn jedes Mal angeben zu müssen:

1
2
3
4
5
6
...
scripts {
"grunt": "grunt -v",
...
},
...

Sie können es auf die gleiche Weise ausführen, aber es wird jetzt immer ausführlich sein. Auf diese Weise können Sie sicherstellen, dass einige Optionen, die Sie immer festlegen möchten, verwendet werden, ohne sie jedes Mal neu angeben zu müssen.

Ich bin jedoch auf einen erheblichen Haken gestoßen, als ich dies in Powershell unter Windows tat. Angenommen, wir verwenden immer noch den "grunt": "grunt" Skript-Setup. Wenn ich versuche, npm run grunt -- -h einzugeben in Powershell dann die -h Argument wird tatsächlich an npm run gesendet statt an grunt Befehl. Alle Argumente, die Sie zu übergeben versuchen, beginnen mit - oder -- wird nicht an den Befehl im scripts gesendet Konfiguration, sondern auf npm run Befehl. Dies scheint weder ein Problem mit dem Standard-cmd oder Git Bash unter Windows zu sein, noch sieht es so aus, als wären Linux-/Mac-Benutzer betroffen.

Aus unzähligen Kommentaren, die ich im Internet gelesen habe, klingt es nicht so, als ob es da draußen schrecklich viele Powershell + npm-Benutzer gibt, aber ich bezweifle es sehr stark dass ich der einzige bin. Auf jeden Fall tritt dieses Problem nicht allzu oft auf, da ich dazu neige, alle Befehle, die ich tatsächlich ausführen werde, in den scripts zu schreiben , also muss ich selten Argumente übergeben und ich neige dazu, mit netten Aliasen zu enden, die es tatsächlich so machen, dass npm run COMMAND ist kürzer als der eigentliche Befehl, den es ausführt.

Tatsächlich schaue ich mich um und versuche, über Grunt, Gulp und dergleichen hinauszugehen, also versuche ich, Tools einzeln zu verwenden, anstatt ihre Task-Runner-Plugins (z. B. mit dem JSHint-Befehlszeilentool anstelle des Grunt-Plugins). ). Weitere Informationen finden Sie unter „How to use npm as a Build Tool“, aber ich experimentiere immer noch damit und versuche sicherlich noch nicht, Sie davon zu überzeugen. In diesem Artikel geht es einfach darum, die Notwendigkeit globaler npm-Pakete zu beseitigen.

Vor- und Nachteile

Dieser Ansatz hat sicherlich einige Vor- und Nachteile, also schauen wir uns einige an:

Nachteile

  • Es dauert normalerweise mehr Tastenanschläge, da npm run ausgelöst werden muss vor allem und muss -- hinzufügen jedes Mal, wenn Sie einige zusätzliche Argumente einwerfen möchten. Natürlich wird dies negiert, wenn Sie die Skripte verwenden, um lange Befehlsnamen in einen kurzen Alias ​​umzuwandeln.
  • Es erfordert im Vorfeld etwas zusätzliche Arbeit, die Skripte in package.json einzufügen Datei.

Pros

  • Sie haben einen einfachen Ort, um Dokumentation darüber zu finden, welcher Befehl ausgeführt werden sollte. Geben Sie einfach npm run ein allein zeigt alle Aliase und Befehle, die für diese Aliase ausgeführt werden.
  • Je nachdem, wie Sie die npm-Skripte einrichten, können sie als Abstraktionsschicht fungieren, sodass Sie, wenn Sie von Grunt zu Gulp oder ähnlichem wechseln möchten, einfach ändern können, welche Befehle innerhalb von scripts Konfiguration und müssen nie die Befehle ändern, die Sie tatsächlich in die Befehlszeile eingeben.
  • Offensichtlich hat ein Vorteil damit zu tun, wie ich diesen Beitrag begonnen habe:Beseitigen von Problemen mit Versionskonflikten aus globalen Paketen.
  • Wenn schließlich jemand Ihr Projekt klont, erhöht sich die Wahrscheinlichkeit, dass er lediglich npm install ausführen muss und sie bekommen tatsächlich alle Abhängigkeiten installiert.

Abschlussfragen

Wenn ich irgendwelche Vor- oder Nachteile übersehen habe, lass es mich wissen. Was meint ihr jedenfalls? Ist es den Aufwand wert, globale Paketversionskonflikte zu verhindern? Wenn Sie ja sagen, wie sehr verlassen wir uns dann auf npm-Skripte, anstatt andere Tools wie Task Runner die eigentliche Arbeit erledigen zu lassen? Dies sind sicherlich Fragen, die Sie selbst beantworten oder mit Ihrem Team besprechen müssen und nicht etwas, auf das ich Ihnen nur die „richtige“ Antwort geben kann. Ich würde immer noch gerne Ihre Gedanken zur Verwendung von npm-Skripten in jedem Umfang hören, also lassen Sie es mich hören! Gott segne und frohes Programmieren!