Shell-Skripting mit Node.js
Sie können die Offline-Version dieses Buches (HTML, PDF, EPUB, MOBI) kaufen und damit die kostenlose Online-Version unterstützen.
(Werbung, bitte nicht blockieren.)

13 Installieren von npm-Paketen und Ausführen von Binärskripten



Die Eigenschaft "bin" in package.json ermöglicht es einem npm-Paket, anzugeben, welche Shell-Skripte es bereitstellt (weitere Informationen finden Sie in Kapitel 14 „Erstellen plattformübergreifender Shell-Skripte“). Wenn wir ein solches Paket installieren, stellt Node.js sicher, dass wir von der Kommandozeile aus auf diese Shell-Skripte (sogenannte Binärskripte) zugreifen können. In diesem Kapitel untersuchen wir zwei Möglichkeiten, Pakete mit Binärskripten zu installieren.

Wir untersuchen, was all das bedeutet und wie wir Binärskripte nach der Installation ausführen können.

13.1 Installieren von npm-Registry-Paketen global

Das Paket cowsay hat die folgende package.json-Eigenschaft

"bin": {
  "cowsay": "./cli.js",
  "cowthink": "./cli.js"
},

Um dieses Paket global zu installieren, verwenden wir npm install -g

npm install -g cowsay

Vorsicht: Unter Unix müssen wir möglicherweise sudo verwenden (wir lernen bald, wie wir das vermeiden können)

sudo npm install -g cowsay

Danach können wir die Befehle cowsay und cowthink in unseren Kommandozeilen verwenden.

Beachten Sie, dass nur die Binärskripte global verfügbar sind. Die Pakete werden ignoriert, wenn Node.js nach bloßen Modulspezifizierern in node_modules-Verzeichnissen sucht.

13.1.1 Welche Pakete sind global installiert? npm ls -g

Wir können überprüfen, welche Pakete global installiert sind und wo.

% npm ls -g
/usr/local/lib
├── corepack@0.12.1
├── cowsay@1.5.0
└── npm@8.15.0

Unter Windows ist der Installationspfad %AppData%\npm, z. B.

>echo %AppData%\npm
C:\Users\jane\AppData\Roaming\npm

13.1.2 Wo werden Pakete global installiert? npm root -g

Ergebnis unter macOS

% npm root -g
/usr/local/lib/node_modules

Ergebnis unter Windows

>npm root -g
C:\Users\jane\AppData\Roaming\npm\node_modules

13.1.3 Wo werden Shell-Skripte global installiert? npm bin -g

npm bin -g teilt uns mit, wo npm Shell-Skripte global installiert. Es stellt auch sicher, dass dieses Verzeichnis in der Shell-PATH-Variable verfügbar ist.

Ergebnis unter macOS

% npm bin -g
/usr/local/bin

% which cowsay
/usr/local/bin/cowsay

Ergebnis in der Windows-Befehlskonsole

>npm bin -g
C:\Users\jane\AppData\Roaming\npm

>where cowsay
C:\Users\jane\AppData\Roaming\npm\cowsay
C:\Users\jane\AppData\Roaming\npm\cowsay.cmd

Die ausführbare Datei cowsay ohne Dateierweiterung ist für Unix-basierte Windows-Umgebungen wie Cygwin, MinGW und MSYS.

Die Windows PowerShell gibt diesen Pfad für gcm cowsay zurück

C:\Users\jane\AppData\Roaming\npm\cowsay.ps1

13.1.4 Wo werden Pakete global installiert? Das npm-Installationspräfix

Das Installationspräfix von npm bestimmt, wo Pakete und Binärskripte global installiert werden.

Dies ist das Installationspräfix unter macOS

% npm config get prefix
/usr/local

Dementsprechend

Dies ist das Installationspräfix unter Windows

>npm config get prefix
C:\Users\jane\AppData\Roaming\npm

Dementsprechend

13.1.5 Ändern des Installationsorts für global installierte Pakete

In diesem Abschnitt untersuchen wir zwei Möglichkeiten, den Installationsort für global installierte Pakete zu ändern.

13.1.5.1 Ändern des npm-Installationspräfixes

Eine Möglichkeit, den Installationsort für global installierte Pakete zu ändern, ist die Änderung des npm-Installationspräfixes.

Unix

mkdir ~/npm-global
npm config set prefix '~/npm-global'

Windows-Befehlskonsole

mkdir "%UserProfile%\npm-global"
npm config set prefix "%UserProfile%\npm-global"

Windows PowerShell

mkdir "$env:UserProfile\npm-global"
npm config set prefix "$env:UserProfile\npm-global"

Die Konfigurationsdaten werden in einer Datei namens .npmrc im Home-Verzeichnis gespeichert.

Von nun an werden globale Installationen in das gerade angegebene Verzeichnis verschoben.

Anschließend müssen wir dem npm bin -g-Verzeichnis noch unsere Shell-PATH-Variable hinzufügen, damit unsere Shell die global installierten Binärskripte findet.

Ein Nachteil der Änderung des npm-Präfixes: npm wird auch an dem neuen Speicherort installiert, wenn wir es auffordern, sich selbst zu aktualisieren.

13.1.5.2 Verwenden eines Node.js-Versionsmanagers

Node.js-Versionsmanager ermöglichen es uns, mehrere Versionen von Node.js gleichzeitig zu installieren und zwischen ihnen zu wechseln. Beliebte sind unter anderem:

13.2 Installieren von npm-Registry-Paketen lokal

Um ein npm-Registry-Paket wie cowsay *lokal* (in ein Paket) zu installieren, gehen wir wie folgt vor:

cd my-package/
npm install cowsay

Dadurch werden folgende Daten zu package.json hinzugefügt:

"dependencies": {
  "cowsay": "^1.5.0",
  ···
}

Zusätzlich wird das Paket in das folgende Verzeichnis heruntergeladen:

my-package/node_modules/cowsay/

Unter Unix erstellt npm diese symbolischen Links für die Binärskripte:

my-package/node_modules/.bin/cowsay -> ../cowsay/cli.js
my-package/node_modules/.bin/cowthink -> ../cowsay/cli.js

Unter Windows erstellt npm diese Dateien in my-package\node_modules\.bin\:

cowsay
cowsay.cmd
cowsay.ps1
cowthink
cowthink.cmd
cowthink.ps1

Die Dateien ohne Erweiterung sind Skripte für Unix-basierte Windows-Umgebungen wie Cygwin, MinGW und MSYS.

npm bin sagt uns, wo lokal installierte Binärskripte zu finden sind – zum Beispiel:

% npm bin
/Users/john/my-package/node_modules/.bin

Hinweis: Lokal werden Pakete immer in einem Verzeichnis namens node_modules neben einer Datei package.json installiert. Wenn letztere im aktuellen Verzeichnis nicht existiert, sucht npm in einem übergeordneten Verzeichnis danach und installiert das Paket dort. Um zu prüfen, wo npm Pakete lokal installieren würde, können wir den Befehl npm root verwenden – zum Beispiel (Unix):

% cd $HOME
% npm root
/Users/john/node_modules

In John's Home-Verzeichnis gibt es keine package.json, aber npm kann nichts in einem übergeordneten Verzeichnis installieren, weshalb npm root dieses Verzeichnis anzeigt. Die lokale Installation eines Pakets am aktuellen Ort führt zur Erstellung einer package.json und zur Fortsetzung der Installation wie üblich.

13.2.1 Ausführen lokal installierter Binärskripte

(Alle Befehle in diesem Unterabschnitt werden im Verzeichnis my-package ausgeführt.)

13.2.1.1 Direktes Ausführen von Binärskripten

Wir können cowsay wie folgt von einer Shell aus ausführen:

./node_modules/.bin/cowsay Hello

Unter Unix können wir einen Helfer einrichten:

alias npm-exec='PATH=$(npm bin):$PATH'

Dann funktioniert der folgende Befehl:

npm-exec cowsay Hello
13.2.1.2 Ausführen von Binärskripten über Paket-Skripte

Wir können auch ein Paket-Skript zu package.json hinzufügen:

{
  ···
  "scripts": {
    "cowsay": "cowsay"
  },
  ···
}

Nun können wir diesen Befehl in einer Shell ausführen:

npm run cowsay Hello

Das funktioniert, weil npm temporär die folgenden Einträge zur $PATH-Variable unter Unix hinzufügt:

/Users/john/my-package/node_modules/.bin
/Users/john/node_modules/.bin
/Users/node_modules/.bin
/node_modules/.bin

Unter Windows werden ähnliche Einträge zu %Path% oder $env:Path hinzugefügt:

C:\Users\jane\my-package\node_modules\.bin
C:\Users\jane\node_modules\.bin
C:\Users\node_modules\.bin
C:\node_modules\.bin

Der folgende Befehl listet die Umgebungsvariablen und ihre Werte auf, die während der Ausführung eines Paket-Skripts vorhanden sind:

npm run env
13.2.1.3 Ausführen von Binärskripten über npx

Innerhalb eines Pakets kann npx verwendet werden, um auf Binärskripte zuzugreifen:

npx cowsay Hello
npx cowthink Hello

Mehr zu npx später.

13.3 Installieren von unveröffentlichten Paketen

Manchmal haben wir ein Paket, das wir entweder noch nicht veröffentlicht haben oder nie veröffentlichen werden und es gerne installieren möchten.

Angenommen, wir haben ein unveröffentlichtes Paket mit dem Namen @my-scope/unpublished-package, das im Verzeichnis /tmp/unpublished-package/ gespeichert ist. Wir können es wie folgt global verfügbar machen:

cd /tmp/unpublished-package/
npm link

Wenn wir das tun:

Aufgrund der Art und Weise, wie das verknüpfte Paket referenziert wird, werden alle Änderungen darin sofort wirksam. Es ist nicht notwendig, es bei Änderungen neu zu verknüpfen.

Um zu überprüfen, ob die globale Installation funktioniert hat, können wir npm ls -g verwenden, um alle global installierten Pakete aufzulisten.

Nachdem wir unser unveröffentlichtes Paket global installiert haben (siehe vorheriger Unterabschnitt), haben wir die Möglichkeit, es lokal in einem unserer Pakete zu installieren (das veröffentlicht oder unveröffentlicht sein kann):

cd /tmp/other-package/
npm link @my-scope/unpublished-package

Dadurch wird der folgende Link erstellt:

/tmp/other-package/node_modules/@my-scope/unpublished-package
-> ../../../unpublished-package

Standardmäßig wird das unveröffentlichte Paket nicht als Abhängigkeit zu package.json hinzugefügt. Der Grund dafür ist, dass npm link oft verwendet wird, um vorübergehend mit einer unveröffentlichten Version eines Registry-Pakets zu arbeiten – was nicht in den Abhängigkeiten auftauchen sollte.

Lokale Verknüpfung aufheben:

cd /tmp/other-package/
npm uninstall @my-scope/unpublished-package

Globale Verknüpfung aufheben:

cd /tmp/unpublished-package/
npm uninstall -g

13.3.4 Installieren von unveröffentlichten Paketen über lokale Pfade

Eine weitere Möglichkeit, ein unveröffentlichtes Paket lokal zu installieren, ist die Verwendung von npm install und die Referenzierung über einen lokalen Pfad (und nicht über seinen Paketnamen):

cd /tmp/other-package/
npm install ../unpublished-package

Das hat zwei Effekte:

Erstens wird der folgende symbolische Link erstellt:

/tmp/other-package/node_modules/@my-scope/unpublished-package
-> ../../../unpublished-package

Zweitens wird eine Abhängigkeit zu package.json hinzugefügt:

"dependencies": {
  "@my-scope/unpublished-package": "file:../unpublished-package",
  ···
}

Diese Art der Installation von unveröffentlichten Paketen funktioniert auch global:

cd /tmp/unpublished-package/
npm install -g .

13.3.5 Andere Wege, unveröffentlichte Pakete zu installieren

13.4 npx: Ausführen von Binärskripten in npm-Paketen, ohne sie zu installieren

npx ist ein Shell-Befehl zum Ausführen von Binärskripten, der mit npm gebündelt ist.

Seine gebräuchlichste Verwendung ist:

npx <package-name> arg1 arg2 ...

Dieser Befehl installiert das Paket mit dem Namen package-name im npx-Cache und führt das Binärskript aus, das denselben Namen wie das Paket hat – zum Beispiel:

npx cowsay Hello

Das bedeutet, wir können Binärskripte ausführen, ohne sie vorher zu installieren. npx ist am nützlichsten für einmalige Aufrufe von Binärskripten – zum Beispiel bieten viele Frameworks Binärskripte zur Einrichtung neuer Projekte an, und diese werden oft über npx ausgeführt.

Nachdem npx ein Paket zum ersten Mal verwendet hat, ist es in seinem Cache verfügbar und nachfolgende Aufrufe sind viel schneller. Wir können jedoch nicht sicher sein, wie lange ein Paket im Cache verbleibt. Daher ist npx kein Ersatz für die globale oder lokale Installation von Binärskripten.

Wenn ein Paket Binärskripte enthält, deren Namen sich vom Paketnamen unterscheiden, können wir sie wie folgt aufrufen:

npx --package=<package-name> <bin-script> arg1 arg2 ...

Zum Beispiel

npx --package=cowsay cowthink Hello

13.4.1 Der npx-Cache

Wo befindet sich der Cache von npx?

Unter Unix können wir dies mit dem folgenden Befehl herausfinden:

npx --package=cowsay node -p \
  "process.env.PATH.split(':').find(p => p.includes('_npx'))"

Dies gibt einen Pfad zurück, der diesem ähnelt:

/Users/john/.npm/_npx/8f497369b2d6166e/node_modules/.bin

Unter Windows können wir (eine Zeile in zwei aufgeteilt) verwenden:

npx --package=cowsay node -p
  "process.env.Path.split(';').find(p => p.includes('_npx'))"

Dies gibt einen Pfad zurück, der diesem ähnelt (einzelner Pfad in zwei Zeilen aufgeteilt):

C:\Users\jane\AppData\Local\npm-cache\_npx\
  8f497369b2d6166e\node_modules\.bin

Beachten Sie, dass der Cache von npx anders ist als der Cache, den npm für die installierten Module verwendet.

Das übergeordnete Verzeichnis beider Caches kann ermittelt werden über:

npm config get cache

Weitere Informationen zum npm-Cache finden Sie in der npm-Dokumentation.

Im Gegensatz zum npx-Cache werden aus dem npm-Cache niemals Daten entfernt, nur hinzugefügt. Wir können seine Größe wie folgt unter Unix überprüfen:

du -sh $(npm config get cache)/_cacache/

Und in der Windows PowerShell:

DiskUsage /d:0 "$(npm config get cache)\_cacache"