Domanda

Come posso utilizzare una versione locale di un modulo in node.js.Ad esempio, nella mia app, ho installato Coffee-Script:

npm install coffee-script
.

Questo lo installa in ./node_modules e il comando del caffè è in ./node_modules/.bin/coffee.C'è un modo per eseguire questo comando quando sono nella cartella principale del mio progetto?Immagino di cercare qualcosa di simile al bundle exec in Bundler.Fondamentalmente, vorrei specificare una versione di script di caffè che tutti i soggetti coinvolti nel progetto dovrebbero usare.

So che posso aggiungere la bandiera -g per installarlo a livello globale Quindi il caffè funziona bene ovunque, ma cosa succede se volessi avere diverse versioni di caffè per progetto?

È stato utile?

Soluzione

Aggiornamento : AS Seyeong Jeong sottolinea nella loro risposta qui sotto, dal momento che NPM 5.2.0 è possibile utilizzare npx [command], che è più conveniente.

Vecchia risposta per le versioni prima di 5.2.0

Il problema con il messo

./node_modules/.bin
.

Nel tuo percorso è che funziona solo quando la tua directory di lavoro corrente è la root della struttura della directory del progetto (I.e. La posizione di node_modules)

Indipendentemente da ciò che è la tua directory di lavoro, è possibile ottenere il percorso dei binari installati localmente con

npm bin
.

Per eseguire un binario coffee installato localmente indipendente da dove ti trovi nella gerarchia della directory del progetto è possibile utilizzare questo costrutto bash

PATH=$(npm bin):$PATH coffee
.

I alias questo a npm-exec

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

Allora, ora posso

npm-exec coffee
.

Per eseguire la corretta copia del caffè, non importa dove sono

$ 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
.

Altri suggerimenti

 Bell'esempio

Non è necessario manipolare più $PATH!

da npm@5.2.0 , npm < / Strong> Ships con pacchetto npx che consente di eseguire comandi da un node_modules/.bin locale o da una cache centrale.

È sufficiente eseguire:

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

Per impostazione predefinita, npx controllerà se esiste il <command> in $PATH o nei binari del progetto locale ed eseguirlo.

Chiamare npx <command> Quando <command> non è già in $PATH installerà automaticamente un pacchetto con quel nome dal registro NPM per te e lo invocherà. Quando è finito, il pacchetto installato non sarà ovunque nei tuoi globali, quindi non dovrai preoccuparti dell'inquinamento a lungo termine. È possibile impedire questo comportamento fornendo un'opzione --no-install.

Per npm < 5.2.0, è possibile installare manualmente il pacchetto npx eseguendo il seguente comando:

$ npm install -g npx
.

Utilizzare il comando npm bin per ottenere i moduli nodo / Directory Bin del tuo progetto

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

E.G.

$ $(npm bin)/bower install
.

Usa npm run[-script] <script name>

Dopo aver utilizzato NPM per installare il pacchetto BIN alla directory ./node_modules locale, modificare package.json per aggiungere <script name> come questo:

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

Sarebbe bello se NPM Installa ha avuto un'opzione A -Add-Script o qualcosa o se la corsa NPM funzionerebbe senza aggiungere al blocco degli script.

Usa npm-run .

Dal readme:

NPM-run

Find & Esegui gli eseguibili locali da Node_modules

Qualsiasi eseguibile disponibile per uno script di cicli di vita NPM è disponibile per npm-run.

Uso

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

Installazione

$ npm install -g npm-run
.

Aggiornamento: Non consiglio più questo metodo, sia per i motivi di sicurezza menzionati che non il minimo comando npm bin più nuovo.Risposta originale sotto:

Come si è scoperto, tutti i binari installati localmente sono in ./node_modules/.bin.Per eseguire sempre i binari in questo elenco anziché i binari disponibili a livello globale, se presente, ti suggerisco di inserire ./node_modules/.bin prima nel tuo percorso:

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

Se si inserisce questo nel ~/.profile, coffee sarà sempre ./node_modules/.bin/coffee se disponibile, altrimenti /usr/local/bin/coffee (o qualunque prefisso che stai installando moduli nodo sotto).

La soluzione Path ha il problema che se $ (bin NPM) è inserito nel tuo .profile / .bashrc / ecc. Valuta una volta ed è per sempre impostato su qualsiasi directory in cui è stato valutato il percorso in. Se invece si modifica ilPercorso corrente quindi ogni volta che esegui lo script il tuo percorso crescerà.

Per aggirare questi problemi, creo una funzione e ho usato questo.Non modifica il tuo ambiente ed è semplice da usare:

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

Questo può quindi essere usato in questo modo senza apportare modifiche al tuo ambiente:

npm-exec r.js <args>
.

Se si desidera tenere la NPM, allora NPX dovrebbe fare ciò di cui hai bisogno.


.

Se passare a filati (una sostituzione NPM da Facebook) è un'opzione per te, è possibile chiamare:

 yarn yourCmd
.

Script all'interno del pacchetto.json prenderà la precedenza, se nessuno viene trovato Guarderà all'interno della cartella ./node_modules/.bin/.

Emette anche ciò che correva:

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

Quindi non devi impostare gli script per ciascun comando nel package.json.


.

Se avevi uno script definito su .scripts all'interno del package.json:

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

yarn tsc sarebbe equivalente a yarn run tsc o npm run tsc:

 yarn tsc
 yarn tsc v0.27.5
 $ tsc
.

: se sei nel recente NPM (Versione> 5.2)

Puoi usare:

npx <command>
.

npx cerca il comando nella directory .bin se il node_modules

Vecchia risposta:

per Windows

Archiviare quanto segue in un file chiamato npm-exec.bat e aggiungilo al %PATH%

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

Uso

Allora puoi usarlo come npm-exec <command> <arg0> <arg1> ...

ad esempio

Per eseguire wdio installato nella directory locale Node_Modules, fare:

npm-exec wdio wdio.conf.js
.

I.e.Corrirà .\node_modules\.bin\wdio wdio.conf.js

I prefer to not rely on shell aliases or another package.

Adding a simple line to scripts section of your package.json, you can run local npm commands like

npm run webpack

package.json

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

If you want your PATH variable to correctly update based on your current working directory, add this to the end of your .bashrc-equivalent (or after anything that defines 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

This may add a short delay every time the bash prompt gets rendered (depending on the size of your project, most likely), so it's disabled by default.

You can enable and disable it within your terminal by running node-mode and node-mode-off, respectively.

I've always used the same approach as @guneysus to solve this problem, which is creating a script in the package.json file and use it running npm run script-name.

However, in the recent months I've been using npx and I love it.

For example, I downloaded an Angular project and I didn't want to install the Angular CLI globally. So, with npx installed, instead of using the global angular cli command (if I had installed it) like this:

ng serve

I can do this from the console:

npx ng serve

Here's an article I wrote about NPX and that goes deeper into it.

zxc is like "bundle exec" for nodejs. It is similar to using PATH=$(npm bin):$PATH:

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

Same @regular 's accepted solution, but Fish shell flavour

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

You can also use direnv and change the $PATH variable only in your working folder.

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

Add this script to your .bashrc. Then you can call coffee or anyhting locally. This is handy for your laptop, but don't use it on your 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;

note: this script makes aliase of cd command, and after each call of cd it checks node_modules/.bin and add it to your $PATH.

note2: you can change the third line to NODE_MODULES=$(npm bin);. But that would make cd command too slow.

For Windows use this:

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

I encountered the same problem and I don't particularly like using aliases (as regular's suggested), and if you don't like them too then here's another workaround that I use, you first have to create a tiny executable bash script, say 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 "$@"

and then you can then use any executables in your local /bin using this command:

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

If you're using scripts in package.json then:

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

I'd love to know if this is an insecure/bad idea, but after thinking about it a bit I don't see an issue here:

Modifying Linus's insecure solution to add it to the end, using npm bin to find the directory, and making the script only call npm bin when a package.json is present in a parent (for speed), this is what I came up with for 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
}

For bash, instead of using the precmd hook, you can use the $PROMPT_COMMAND variable (I haven't tested this but you get the idea):

__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"

I am a Windows user and this is what worked for me:

// 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

Good Luck.

In case you are using fish shell and do not want to add to $path for security reason. We can add the below function to run local node executables.

### 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

Now you can run thing like:

n coffee

or more arguments like:

n browser-sync --version

Note, if you are bash user, then @Bob9630 answers is the way to go by leveraging bash's $@, which is not available in fishshell.

Include coffee-script in package.json with the specific version required in each project, typically like this:

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

Then run npm install to install dependencies in each project. This will install the specified version of coffee-script which will be accessible locally to each project.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top