Pregunta

¿Cómo uso una versión local de un módulo en node.js.Por ejemplo, en mi aplicación instalé café-script:

npm install coffee-script

Esto lo instala en ./node_modules y el comando de café está en ./node_modules/.bin/coffee.¿Hay alguna manera de ejecutar este comando cuando estoy en la carpeta principal de mi proyecto?Supongo que estoy buscando algo similar a bundle exec en paquete.Básicamente, me gustaría especificar una versión de Coffee-Script que todos los involucrados en el proyecto deberían usar.

Sé que puedo agregar el -g marcar para instalarlo globalmente para que el café funcione bien en cualquier lugar, pero ¿qué pasa si quisiera tener diferentes versiones de café por proyecto?

¿Fue útil?

Solución

ACTUALIZAR:Como señala Seyeong Jeong en su respuesta a continuación, desde npm 5.2.0 puedes usar npx [command], que es más conveniente.

RESPUESTA ANTIGUA para versiones anteriores a 5.2.0:

El problema de poner

./node_modules/.bin

en su RUTA es que solo funciona cuando su directorio de trabajo actual es la raíz de la estructura de directorios de su proyecto (es decir,la ubicación de node_modules)

Independientemente de cuál sea su directorio de trabajo, puede obtener la ruta de los archivos binarios instalados localmente con

npm bin

Para ejecutar una instalación local coffee binario independiente de dónde se encuentre en la jerarquía del directorio del proyecto, puede usar esta construcción bash

PATH=$(npm bin):$PATH coffee

Le puse un alias a npm-exec

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

Entonces ahora puedo

npm-exec coffee

para ejecutar la copia correcta de café sin importar dónde esté

$ 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

Otros consejos

Nice example

No tienes que manipular $PATH ¡ya no!

De npm@5.2.0, npm se envía con npx paquete que le permite ejecutar comandos desde un local node_modules/.bin o desde un caché central.

Simplemente ejecuta:

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

Por defecto, npx comprobará si <command> existe en $PATH, o en los binarios del proyecto local, y ejecútelo.

Vocación npx <command> cuando <command> no está ya en tu $PATH instalará automáticamente un paquete con ese nombre desde el registro de NPM y lo invocará.Cuando esté listo, el paquete instalado no estará en ninguna parte de sus valores globales, por lo que no tendrá que preocuparse por la contaminación a largo plazo.Puede evitar este comportamiento proporcionando --no-install opción.

Para npm < 5.2.0, puedes instalar npx paquete manualmente ejecutando el siguiente comando:

$ npm install -g npx

Utilizar el npm bin comando para obtener el directorio /bin de módulos de nodo de su proyecto

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

p.ej.

$ $(npm bin)/bower install

Usar npm run[-script] <script name>

Después de usar npm para instalar el paquete bin en su local ./node_modules directorio, modificar package.json agregar <script name> como esto:

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

Sería bueno si npm install tuviera una opción --add-script o algo así o si npm run funcionara sin agregar nada al bloque de scripts.

Usar npm-run.

Del archivo Léame:

ejecución npm

Busque y ejecute ejecutables locales desde node_modules

Cualquier ejecutable disponible para un script de ciclo de vida de npm está disponible para npm-run.

Uso

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

Instalación

$ npm install -g npm-run

Actualizar: Ya no recomiendo este método, tanto por las razones de seguridad mencionadas como por las más nuevas. npm bin dominio.Respuesta original a continuación:

Como habrás descubierto, todos los archivos binarios instalados localmente están en ./node_modules/.bin.Para poder ejecutar siempre archivos binarios en este directorio en lugar de archivos binarios disponibles globalmente, si están presentes, le sugiero que coloque ./node_modules/.bin primero en tu camino:

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

Si pones esto en tu ~/.profile, coffee siempre será ./node_modules/.bin/coffee si está disponible, de lo contrario /usr/local/bin/coffee (o cualquier prefijo bajo el que esté instalando módulos de nodo).

La solución PATH tiene el problema de que si se coloca $(npm bin) en su .profile/.bashrc/etc, se evalúa una vez y se establece para siempre en cualquier directorio en el que se evaluó la ruta por primera vez.Si, en cambio, modifica la ruta actual, cada vez que ejecute el script, su ruta crecerá.

Para solucionar estos problemas, creé una función y la usé.No modifica su entorno y es fácil de usar:

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

Luego, esto se puede usar así sin realizar ningún cambio en su entorno:

npm-exec r.js <args>

Si quieres mantener npm, entonces npx debe hacer lo que necesita.


Si cambiar a hilo (un reemplazo de npm por Facebook) es una opción para usted, puede llamar a:

 yarn yourCmd

Los scripts dentro del paquete.json tendrán prioridad, si no se encuentra ninguno, buscará dentro del ./node_modules/.bin/ carpeta.

También genera lo que ejecutó:

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

Por lo tanto, no es necesario configurar scripts para cada comando en su package.json.


Si tuviera un script definido en .scripts dentro de tu package.json:

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

yarn tsc sería equivalente a yarn run tsc o npm run tsc:

 yarn tsc
 yarn tsc v0.27.5
 $ tsc

actualizar:Si estás en el npm reciente (versión >5.2)

Puedes usar:

npx <command>

npx busca comando en .bin directorio si su node_modules

antigua respuesta:

Para ventanas

Almacene lo siguiente en un archivo llamado npm-exec.bat y agrégalo a tu %PATH%

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

Uso

Entonces puedes usarlo comonpm-exec <command> <arg0> <arg1> ...

Por ejemplo

Ejecutar wdio instalado en el directorio local node_modules, haga:

npm-exec wdio wdio.conf.js

es decir.correrá .\node_modules\.bin\wdio wdio.conf.js

Prefiero no depender de alias de shell u otro paquete.

Agregar una línea simple a scripts sección de tu package.json, puede ejecutar comandos npm locales como

npm run webpack

paquete.json

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

Si desea que su variable PATH se actualice correctamente según su directorio de trabajo actual, agregue esto al final de su .bashrc-equivalente (o después de cualquier cosa que defina 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

Esto puede agregar un breve retraso cada vez que se procesa el mensaje de bash (lo más probable es que dependa del tamaño de su proyecto), por lo que está deshabilitado de forma predeterminada.

Puede habilitarlo y deshabilitarlo dentro de su terminal ejecutando node-mode y node-mode-off, respectivamente.

Siempre he usado el mismo enfoque que @guneysus para resolver este problema, que consiste en crear un script en el archivo package.json y usarlo ejecutando npm run script-name.

Sin embargo, en los últimos meses he estado usando npx y me encanta.

Por ejemplo, descargué un proyecto de Angular y no quería instalar Angular CLI globalmente.Entonces, con npx instalado, en lugar de usar el comando global angular cli (si lo hubiera instalado) de esta manera:

ng serve

Puedo hacer esto desde la consola:

npx ng serve

Aquí hay un artículo Escribí sobre NPX y eso profundiza en ello.

zxc es como "paquete ejecutivo" para nodejs.Es similar al uso PATH=$(npm bin):$PATH:

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

La misma solución aceptada por @regular, pero con sabor a cáscara de pescado

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

También puedes usar direnv y cambiar la variable $PATH solo en tu carpeta de trabajo.

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

Añade este script a tu .bashrc.Entonces puedes llamar coffee o cualquier cosa localmente.Esto es útil para su computadora portátil, pero no lo use en su servidor.

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;

nota:este script crea un alias de cd comando, y después de cada llamada de cd comprueba node_modules/.bin y agrégalo a tu $PATH.

nota 2:puedes cambiar la tercera línea a NODE_MODULES=$(npm bin);.Pero eso haría cd comando demasiado lento.

Para Windows usa esto:

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

Encontré el mismo problema y no me gusta particularmente usar alias (como regularse sugiere), y si a usted tampoco le gustan, aquí hay otra solución alternativa que uso: primero debe crear un pequeño script bash ejecutable, por ejemplo 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 "$@"

y luego puedes usar cualquier ejecutable en tu local /bin usando este comando:

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

Si estas usando scripts en paquete.json entonces:

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

Me encantaría saber si esta es una idea insegura/mala, pero después de pensarlo un poco no veo ningún problema aquí:

Modificando la solución insegura de Linus para agregarla al final, usando npm bin para encontrar el directorio y hacer que el script solo llame npm bin cuando un package.json está presente en un padre (para mayor velocidad), esto es lo que se me ocurrió 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
}

Para bash, en lugar de utilizar el precmd gancho, puedes usar el $PROMPT_COMMAND variable (no he probado esto pero ya entiendes la 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"

soy un Windows usuario y esto es lo que funcionó para mí:

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

Buena suerte.

En caso de que estés usando fish shell y no quiero agregar a $path por razones de seguridad.Podemos agregar la siguiente función para ejecutar ejecutables del nodo local.

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

Ahora puedes ejecutar cosas como:

n coffee

o más argumentos como:

n browser-sync --version

Tenga en cuenta, si usted es bash usuario, entonces @Bob9630 responde es el camino a seguir aprovechando las funciones de bash $@, que no está disponible en fishshell.

Incluya coffee-script en package.json con la versión específica requerida en cada proyecto, normalmente así:

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

Luego ejecute npm install para instalar dependencias en cada proyecto.Esto instalará la versión especificada de Coffee-Script a la que se podrá acceder localmente para cada proyecto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top