Frage

Wie verwende ich eine lokale Version eines Moduls in node.js.Zum Beispiel habe ich in meiner App coffee-script installiert:

npm install coffee-script

Dies installiert es in ./node_modules und das Kaffeekommando ist in ./node_modules/.bin/coffee.Gibt es eine Möglichkeit, diesen Befehl auszuführen, wenn ich mich im Hauptordner meines Projekts befinde?Ich denke, ich suche nach etwas Ähnlichem bundle exec in Bündelung.Grundsätzlich möchte ich eine Version von coffee-script angeben, die alle am Projekt Beteiligten verwenden sollten.

Ich weiß, ich kann das hinzufügen -g flag, um es global zu installieren, damit Kaffee überall gut funktioniert, aber was ist, wenn ich verschiedene Versionen von Kaffee pro Projekt haben möchte?

War es hilfreich?

Lösung

UPDATE:Wie Seyeong Jeong in ihrer Antwort unten hervorhebt, können Sie seit npm 5.2.0 verwenden npx [command], was bequemer ist.

ALTE ANTWORT für Versionen vor 5.2.0:

Das Problem mit dem Putten

./node_modules/.bin

in Ihrem PFAD steht, dass es nur funktioniert, wenn Ihr aktuelles Arbeitsverzeichnis das Stammverzeichnis Ihrer Projektverzeichnisstruktur ist (dh.der Standort von node_modules)

Unabhängig von Ihrem Arbeitsverzeichnis können Sie den Pfad der lokal installierten Binärdateien mit abrufen

npm bin

Um eine lokal installierte coffee binär unabhängig davon, wo Sie sich in der Projektverzeichnishierarchie befinden, können Sie dieses Bash-Konstrukt verwenden

PATH=$(npm bin):$PATH coffee

Ich habe dies auf npm-exec abgekürzt

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

Also, jetzt kann ich

npm-exec coffee

um die richtige Kopie von Kaffee laufen zu lassen, egal wo ich bin

$ pwd
/Users/regular/project1

$ npm-exec which coffee
/Users/regular/project1/node_modules/.bin/coffee

$ cd lib/
$ npm-exec which coffee
/Users/regular/project1/node_modules/.bin/coffee

$ cd ~/project2
$ npm-exec which coffee
/Users/regular/project2/node_modules/.bin/coffee

Andere Tipps

Nice example

Sie müssen nicht manipulieren $PATH nicht mehr!

Von npm@5.2.0, npm schiffe mit npx paket, mit dem Sie Befehle von einem lokalen ausführen können node_modules/.bin oder aus einem zentralen Cache.

Einfach laufen:

$ npx [options] <command>[@version] [command-arg]...

Standardmäßig, npx wird prüfen, ob <command> existiert in $PATH, oder in den lokalen Projektbinärdateien, und führen Sie diese aus.

Aufruf npx <command> wenn <command> ist nicht schon in deinem $PATH installiert automatisch ein Paket mit diesem Namen aus der NPM-Registrierung für Sie und ruft es auf.Wenn dies erledigt ist, befindet sich das installierte Paket nirgendwo in Ihren Globals, sodass Sie sich langfristig keine Sorgen über Umweltverschmutzung machen müssen.Sie können dieses Verhalten verhindern, indem Sie Folgendes angeben --no-install Option.

Für npm < 5.2.0, können Sie installieren npx packen Sie das Paket manuell, indem Sie den folgenden Befehl ausführen:

$ npm install -g npx

Verwenden Sie die npm bin befehl zum Abrufen des Knotenmoduls / bin-Verzeichnisses Ihres Projekts

$ $(npm bin)/<binary-name> [args]

beispielsweise.

$ $(npm bin)/bower install

Verwenden npm run[-script] <script name>

Nachdem Sie npm verwendet haben, um das bin-Paket auf Ihrem lokalen zu installieren ./node_modules verzeichnis, ändern package.json hinzufügen <script name> wie das:

$ npm install --save learnyounode
$ edit packages.json
>>> in packages.json
...
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "learnyounode": "learnyounode"
},
...
$ npm run learnyounode

Es wäre schön, wenn npm install eine Option --add-script oder so etwas hätte oder wenn npm run funktionieren würde, ohne dem Skriptblock etwas hinzuzufügen.

Verwenden npm-run.

Aus der Readme:

npm-ausführen

Lokale ausführbare Dateien von node_modules suchen und ausführen

Jede ausführbare Datei, die einem npm Lifecycle-Skript zur Verfügung steht, ist verfügbar für npm-run.

Nutzung

$ npm install mocha # mocha installed in ./node_modules
$ npm-run mocha test/* # uses locally installed mocha executable 

Installation

$ npm install -g npm-run

Update: Ich empfehle diese Methode nicht mehr, sowohl aus den genannten Sicherheitsgründen als auch nicht zuletzt aus den neueren npm bin Befehl.Ursprüngliche Antwort unten:

Wie Sie herausgefunden haben, befinden sich alle lokal installierten Binärdateien in ./node_modules/.bin.Um Binärdateien immer in diesem Verzeichnis und nicht in global verfügbaren Binärdateien auszuführen, falls vorhanden, schlage ich vor, dass Sie Folgendes eingeben ./node_modules/.bin zuerst auf deinem Weg:

export PATH="./node_modules/.bin:$PATH"

Wenn du das in deine steckst ~/.profile, coffee wird es immer sein ./node_modules/.bin/coffee wenn vorhanden, sonst /usr/local/bin/coffee (oder unter welchem Präfix auch immer Sie Knotenmodule installieren).

Die Pfadlösung hat das Problem, dass, wenn $ (npm bin) in Ihrem platziert ist.Profil/.bashrc / etc es wird einmal ausgewertet und für immer auf das Verzeichnis gesetzt, in dem der Pfad zuerst ausgewertet wurde.Wenn Sie stattdessen den aktuellen Pfad ändern, wird Ihr Pfad bei jeder Ausführung des Skripts größer.

Um diese Probleme zu umgehen, habe ich eine Funktion erstellt und diese verwendet.Es verändert Ihre Umgebung nicht und ist einfach zu bedienen:

function npm-exec {
   $(npm bin)/$@  
}

Dies kann dann so verwendet werden, ohne Änderungen an Ihrer Umgebung vorzunehmen:

npm-exec r.js <args>

Wenn du npm behalten willst, dann npx sollte tun, was du brauchst.


Wenn der Wechsel zu Garn (ein NPM-Ersatz von Facebook) für Sie eine Option ist, können Sie anrufen:

 yarn yourCmd

skripte innerhalb des Pakets.json hat Vorrang, wenn keines gefunden wird, wird es in das ./node_modules/.bin/ Ordner.

Es gibt auch aus, was es ausgeführt hat:

$ yarn tsc
yarn tsc v0.27.5
$ "/home/philipp/rate-pipeline/node_modules/.bin/tsc"

Sie müssen also nicht für jeden Befehl in Ihrem Skript Skripte einrichten package.json.


Wenn Sie ein Skript unter definiert hätten .scripts in deinem package.json:

"tsc": "tsc" // each command defined in the scripts will be executed from `./node_modules/.bin/` first

yarn tsc wäre äquivalent zu yarn run tsc oder npm run tsc:

 yarn tsc
 yarn tsc v0.27.5
 $ tsc

Update:Wenn Sie auf dem letzten npm sind (Version> 5.2)

Sie können verwenden:

npx <command>

npx sucht nach Befehl in .bin verzeichnis, wenn Ihr node_modules

alte Antwort:

Für Windows

Speichern Sie Folgendes in einer Datei mit dem Namen npm-exec.bat und füge es deinem hinzu %PATH%

@echo off
set cmd="npm bin"
FOR /F "tokens=*" %%i IN (' %cmd% ') DO SET modules=%%i
"%modules%"\%*

Nutzung

Dann kannst du es wie folgt verwenden npm-exec <command> <arg0> <arg1> ...

Beispielsweise

Ausführen wdio im lokalen Verzeichnis node_modules installiert, führen Sie Folgendes aus:

npm-exec wdio wdio.conf.js

also.es wird laufen .\node_modules\.bin\wdio wdio.conf.js

Ich ziehe es vor, mich nicht auf Shell-Aliase oder ein anderes Paket zu verlassen.

Hinzufügen einer einfachen Zeile zu scripts abschnitt Ihres package.json, können Sie lokale npm-Befehle wie ausführen

npm run webpack

Paket.json

{
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "webpack": "webpack"
  },
  "devDependencies": {
    "webpack": "^4.1.1",
    "webpack-cli": "^2.0.11"
  }
}

Wenn Sie möchten, dass Ihre PATH-Variable basierend auf Ihrem aktuellen Arbeitsverzeichnis korrekt aktualisiert wird, fügen Sie diese am Ende Ihrer hinzu .bashrc-äquivalent (oder nach allem, was definiert PATH):

__OLD_PATH=$PATH
function updatePATHForNPM() {
  export PATH=$(npm bin):$__OLD_PATH
}

function node-mode() {
  PROMPT_COMMAND=updatePATHForNPM
}

function node-mode-off() {
  unset PROMPT_COMMAND
  PATH=$__OLD_PATH
}

# Uncomment to enable node-mode by default:
# node-mode

Dies kann jedes Mal, wenn die Bash-Eingabeaufforderung gerendert wird, zu einer kurzen Verzögerung führen (höchstwahrscheinlich abhängig von der Größe Ihres Projekts), sodass sie standardmäßig deaktiviert ist.

Sie können es in Ihrem Terminal aktivieren und deaktivieren, indem Sie Folgendes ausführen node-mode und node-mode-off, jeweils.

Ich habe immer den gleichen Ansatz wie @guneysus verwendet, um dieses Problem zu lösen, bei dem ein Skript im Paket erstellt wird.json-Datei und verwenden Sie sie mit npm run script-name.

In den letzten Monaten habe ich jedoch verwendet npx und ich liebe es.

Zum Beispiel habe ich ein Angular-Projekt heruntergeladen und wollte die Angular-CLI nicht global installieren.Also, wenn npx installiert ist, anstatt den globalen Angular-CLI-Befehl (wenn ich ihn installiert hätte) wie folgt zu verwenden:

ng serve

Ich kann das von der Konsole aus machen:

npx ng serve

Hier ist ein Artikel Ich habe über NPX geschrieben und das geht tiefer hinein.

zxc ist wie "bundle exec" für nodejs.Es ist ähnlich wie bei der Verwendung von PATH=$(npm bin):$PATH:

$ npm install -g zxc
$ npm install gulp
$ zxc which gulp
/home/nathan/code/project1/node_modules/.bin/gulp

Die gleiche akzeptierte Lösung von @ regular, aber Fischschalengeschmack

if not contains (npm bin) $PATH
    set PATH (npm bin) $PATH
end

Sie können auch direnv verwenden und die Variable $ PATH nur in Ihrem Arbeitsordner ändern.

$ cat .envrc
> export PATH=$(npm bin):$PATH

Fügen Sie dieses Skript zu Ihrem hinzu .bashrc.Dann können Sie anrufen coffee oder irgendetwas vor Ort.Dies ist praktisch für Ihren Laptop, aber verwenden Sie es nicht auf Ihrem Server.

DEFAULT_PATH=$PATH;

add_local_node_modules_to_path(){
  NODE_MODULES='./node_modules/.bin';
  if [ -d $NODE_MODULES ]; then
    PATH=$DEFAULT_PATH:$NODE_MODULES;
  else
    PATH=$DEFAULT_PATH;
  fi
}

cd () {
  builtin cd "$@";
  add_local_node_modules_to_path;
}

add_local_node_modules_to_path;

beachten:dieses Skript macht Aliase von cd befehl und nach jedem Aufruf von cd es überprüft node_modules/.bin und füge es deinem hinzu $PATH.

anmerkung2:sie können die dritte Zeile ändern in NODE_MODULES=$(npm bin);.Aber das würde machen cd befehl zu langsam.

Für Windows verwenden Sie dies:

/* cmd into "node_modules" folder */
"%CD%\.bin\grunt" --version

Ich bin auf das gleiche Problem gestoßen und ich mag es nicht besonders, Aliase zu verwenden (as regelmäßigvorgeschlagen), und wenn Sie sie auch nicht mögen, dann ist hier eine andere Problemumgehung, die ich verwende: Sie müssen zuerst ein winziges ausführbares Bash-Skript erstellen, sagen wir setenv.sh:

#!/bin/sh

# Add your local node_modules bin to the path
export PATH="$(npm bin):$PATH"

# execute the rest of the command
exec "$@"

und dann können Sie dann alle ausführbaren Dateien in Ihrem lokalen verwenden /bin mit diesem Befehl:

./setenv.sh <command>
./setenv.sh 6to5-node server.js
./setenv.sh grunt

Wenn Sie verwenden scripts im Paket.json dann:

...,
scripts: {
    'start': './setenv.sh <command>'
}

Ich würde gerne wissen, ob dies eine unsichere / schlechte Idee ist, aber nachdem ich ein wenig darüber nachgedacht habe, sehe ich hier kein Problem:

Ändern Sie die unsichere Lösung von Linus, um sie am Ende hinzuzufügen, indem Sie Folgendes verwenden npm bin um das Verzeichnis zu finden und das Skript nur aufzurufen npm bin wenn ein package.json ist in einem Elternteil vorhanden (für Geschwindigkeit), dafür habe ich mir das ausgedacht zsh:

find-up () {
  path=$(pwd)
  while [[ "$path" != "" && ! -e "$path/$1" ]]; do
    path=${path%/*}
  done
  echo "$path"
}

precmd() {
  if [ "$(find-up package.json)" != "" ]; then
    new_bin=$(npm bin)
    if [ "$NODE_MODULES_PATH" != "$new_bin" ]; then
      export PATH=${PATH%:$NODE_MODULES_PATH}:$new_bin
      export NODE_MODULES_PATH=$new_bin
    fi
  else
    if [ "$NODE_MODULES_PATH" != "" ]; then
      export PATH=${PATH%:$NODE_MODULES_PATH}
      export NODE_MODULES_PATH=""
    fi
  fi
}

Für bash, anstatt das zu verwenden precmd haken, können sie die verwenden $PROMPT_COMMAND variabel (ich habe das nicht getestet, aber Sie haben die Idee):

__add-node-to-path() {
  if [ "$(find-up package.json)" != "" ]; then
    new_bin=$(npm bin)
    if [ "$NODE_MODULES_PATH" != "$new_bin" ]; then
      export PATH=${PATH%:$NODE_MODULES_PATH}:$new_bin
      export NODE_MODULES_PATH=$new_bin
    fi
  else
    if [ "$NODE_MODULES_PATH" != "" ]; then
      export PATH=${PATH%:$NODE_MODULES_PATH}
      export NODE_MODULES_PATH=""
    fi
  fi   
}

export PROMPT_COMMAND="__add-node-to-path"

Ich bin ein Windows benutzer und das hat bei mir funktioniert:

// First set some variable - i.e. replace is with "xo"
D:\project\root> set xo="./node_modules/.bin/"

// Next, work with it
D:\project\root> %xo%/bower install

Glück.

Falls Sie verwenden fish shell und will nicht hinzufügen $path Sicherheitsgründen.Wir können die folgende Funktion hinzufügen, um ausführbare Dateien für lokale Knoten auszuführen.

### run executables in node_module/.bin directory
function n 
  set -l npmbin (npm bin)   
  set -l argvCount (count $argv)
  switch $argvCount
    case 0
      echo please specify the local node executable as 1st argument
    case 1
      # for one argument, we can eval directly 
      eval $npmbin/$argv
    case '*'
      set --local executable $argv[1]
      # for 2 or more arguments we cannot append directly after the $npmbin/ since the fish will apply each array element after the the start string: $npmbin/arg1 $npmbin/arg2... 
      # This is just how fish interoperate array. 
      set --erase argv[1]
      eval $npmbin/$executable $argv 
  end
end

Jetzt kannst du so etwas laufen lassen:

n coffee

oder mehr Argumente wie:

n browser-sync --version

Beachten Sie, wenn Sie sind bash benutzer, dann @Bob9630 Antworten ist der Weg zu gehen, indem Sie Bashs nutzen $@, die in nicht verfügbar ist fishshell.

Kaffeeskript in Paket einschließen.json mit der spezifischen Version, die in jedem Projekt benötigt wird, normalerweise so:

"dependencies":{
  "coffee-script": ">= 1.2.0"

Führen Sie dann npm install aus, um Abhängigkeiten in jedem Projekt zu installieren.Dadurch wird die angegebene Version von coffee-script installiert, auf die lokal für jedes Projekt zugegriffen werden kann.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top