¿Cómo importo módulos globales en Node? Aparece el mensaje "Error: no se puede encontrar el módulo <módulo>"?

145

Estoy tratando de configurar Node en Mac OSX Lion. Todo parece funcionar bien, pero parece que no puedo importar nada de los módulos de mi carpeta global de módulos. Me sale el error

Error: Cannot find module <module>

Si ejecuto esto: node -e require.pathsla respuesta que obtengo es:

[ '/usr/local/lib/node_modules',
  '/Users/Me/.node_modules',
  '/Users/Me/.node_libraries',
  '/usr/local/Cellar/node/0.4.12/lib/node' ]

Lo cual es correcto, mis módulos están instalados en / usr / local / lib / node_modules. Sin embargo, cuando intento ejecutar un script, obtengo esto:

Error: Cannot find module 'socket.io'
    at Function._resolveFilename (module.js:326:11)
    at Function._load (module.js:271:25)
    at require (module.js:355:19)
    at Object.<anonymous> (/Users/Me/node/server.js:2:10)
    at Module._compile (module.js:411:26)
    at Object..js (module.js:417:10)
    at Module.load (module.js:343:31)
    at Function._load (module.js:302:12)
    at Array.<anonymous> (module.js:430:10)
    at EventEmitter._tickCallback (node.js:126:26)

Mi .bash_profile se ve así:

export PATH=/usr/local/mysql/bin:$PATH
export NODE_PATH=/usr/local/lib/node_modules
export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:/usr/local/mysql/lib/"

Realmente agradecería algo de ayuda, no tengo idea de por qué no puedo importar ninguna biblioteca.

Hanpan
fuente
1
Sabes que esta no es exactamente la forma preferida de hacer las cosas, ¿verdad?
thejh
1
¿Podrías dar más detalles? ¿Quiere decir que no debería instalar bibliotecas en mi carpeta global?
Hanpan el
3
@Hanpan: la forma preferida es instalar los módulos que desea utilizar a través de require () localmente.
thejh
1
Puede encontrar una respuesta mejor y más actualizada (que no depende npm link) aquí: stackoverflow.com/a/15646750/2671392
GGG
1
Soy de la vieja escuela y estoy acostumbrado a instalar bibliotecas en ubicaciones globales. Nunca he visto ninguna razón convincente para un uso intensivo de las instalaciones de la biblioteca local. La clase mongodb que estoy tomando terminará en algún lugar cerca de un centenar de pequeños proyectos para cuando hayamos terminado, cada uno con un conjunto de bibliotecas en su mayoría duplicadas: mongodb, express, consolidate, etc. El cambio a idiomas interactivos deja depósitos de bibliotecas locales por todo el lugar. Debo tener miles de bibliotecas Scala en los repositorios locales de Scala. Ídem Meteor, maravilloso y rubí.
Stephen W. Wright el

Respuestas:

116

Si está usando npm> = 1.0, puede usarlo npm link <global-package>para crear un enlace local a un paquete ya instalado globalmente. ( Advertencia: el sistema operativo debe admitir enlaces simbólicos ) .

Sin embargo, esto no viene sin sus problemas.

El enlace npm es una herramienta de desarrollo. Es increíble para administrar paquetes en su caja de desarrollo local. Pero implementar con el enlace npm es básicamente pedir problemas, ya que hace que sea muy fácil actualizar las cosas sin darse cuenta.

Como alternativa, puede instalar los paquetes tanto local como globalmente.

Para obtener información adicional, vea

Tadeusz Wójcik
fuente
69
Estoy leyendo esto y no puedo creer lo que veo. Entonces, si instalo, digamos express, y luego tengo 20 proyectos para construir sobre express, ¿necesito instalarlo 20 veces, para cada uno de ellos, en cada carpeta de proyecto, una y otra vez? No tengo mucha experiencia con los gestores de paquetes, pero esto apesta ...
treznik
25
Eso es correcto, y si lo piensas, tiene sentido. Administrar sus dependencias localmente hace que todo se mantenga autónomo y le permite especificar una versión específica de una dependencia para cualquier proyecto dado (por ejemplo, project foo requiere express 2.x, mientras que la barra de proyecto puede usar express 3 beta).
Grahamb
43
También luché por entender la lógica de esto por un tiempo, pero después de ver a mis amigos de Ruby luchar con las actualizaciones globales de paquetes, discutir sobre gemas y, a menudo, simplemente nunca actualizar, he admitido que instalar dependencias localmente es la única forma sensata de hacerlo. gestión de paquetes .
timoxley
3
Me gustaría establecer un paralelismo entre esta situación y la de las bibliotecas de enlace estático frente a las de enlace dinámico en lo que respecta a la distribución de software. Tenga en cuenta que casi todas las aplicaciones distribuidas en la tienda de aplicaciones de iOS deben vincular estáticamente dependencias no proporcionadas por el SDK de iOS. ¿Por qué se hace esto? El infierno de dependencia global es algo muy real.
Steven Lu
1
También entiendo que npmel caché (que vive en ~/.npm) hará que sea conveniente el proceso de reinstalación realizado en sus diferentes ubicaciones.
Steven Lu
85

Node.js utiliza la variable de entorno NODE_PATHpara permitir especificar directorios adicionales para incluir en la ruta de búsqueda del módulo. Puede usarlo npmpara decirle dónde se almacenan los módulos globales con el npm root -gcomando. Entonces, al unir esos dos, puede asegurarse de que los módulos globales estén incluidos en su ruta de búsqueda con el siguiente comando (en Linux-ish)

export NODE_PATH=$(npm root --quiet -g)

Joel B
fuente
3
Gracias por la NODE_PATHsugerencia variable de entorno. Eso ayudó mucho!
rekire
77
Este debería ser el comentario principal
Adam Prax
Tuve que establecer NODE_PATHla ruta posix equivalente para hacer que npm funcione en MSYS2. Gracias.
Joyce Babu
Funciona con Windows y Git bash también. Perfecto. :-)
inf3rno
Esto hace que se .node_modulespueda buscar en su carpeta, pero para importar módulos utilizando require(), aún deben instalarse en su directorio de proyecto local (o, alternativamente, vincularse mediante npm link). Los módulos globales no se pueden importar en proyectos, solo se pueden ejecutar binarios / scripts desde allí.
Prahlad Yeri
65

Puede usar el enlace npm para crear un enlace simbólico a su paquete global en su carpeta de proyectos.

Ejemplo:

$ npm install -g express
$ cd [local path]/project
$ npm link express

Todo lo que hace es crear una carpeta local node_modules y luego crear un enlace simbólico express -> [directorio global] / node_modules / express que luego puede ser resuelto por require('express')

Nick Sotiros
fuente
¿Es compatible este sistema operativo?
UpTheCreek
Las versiones más recientes de Windows lo admiten desde esta versión: github.com/npm/npm/commit/… Para versiones anteriores de Windows, intente npmjs.com/package/npm-junction
Alex
22

Instale cualquier paquete globalmente de la siguiente manera:

$ npm install -g replace  // replace is one of the node module.

Como este módulo de reemplazo se instala globalmente, si ve la carpeta de módulos de nodo, no verá el módulo de reemplazo allí y, por lo tanto, no puede usar este paquete usando require ('replace').

porque con require solo puede usar módulos locales que están presentes en su carpeta de módulo de nodo.

Ahora, para usar el módulo global, debe vincularlo con la ruta del módulo de nodo utilizando el siguiente comando.

$ npm link replace

Ahora regrese y vea la carpeta de su módulo de nodo, ahora podrá ver el módulo de reemplazo allí y puede usarlo con require ('replace') en su aplicación, ya que está vinculado con su módulo de nodo local.

Por favor, avíseme si necesita más aclaraciones.

usuario5341372
fuente
14

Puede usar require con la ruta al directorio del módulo global como argumento.

require('/path/to/global/node_modules/the_module');

En mi Mac, uso esto:

require('/usr/local/lib/node_modules/the_module');

¿Cómo encontrar dónde están sus módulos globales? -> ¿Dónde instala npm paquetes?

abadejo
fuente
7

Establecer la variable de entorno NODE_PATH para que apunte a su node_modulescarpeta global .

En Windows 7 o superior, la ruta es similar, %AppData%\npm\node_modulesmientras que en UNIX podría ser similar, /home/sg/.npm_global/lib/node_modules/pero depende de la configuración del usuario.

El comando npm config get prefixpodría ayudar a descubrir cuál es la ruta correcta.

En sistemas UNIX puede lograrlo con el siguiente comando:

export NODE_PATH=`npm config get prefix`/lib/node_modules/
Ben Xu
fuente
0

Estoy usando Docker Estoy tratando de crear una imagen acoplable que tenga todas mis dependencias de nodo instaladas, pero puedo usar mi directorio de aplicaciones local en tiempo de ejecución del contenedor (sin contaminarlo con un directorio o enlace node_modules). Esto causa problemas en este escenario. Mi solución alternativa es requerir desde la ruta exacta donde se encuentra el módulo, por ejemplo, require ('/ usr / local / lib / node_modules / socket.io')

Darin London
fuente
-1

require.paths es obsoleto.

Ve a la carpeta de tu proyecto y escribe

npm install socket.io

eso debería instalarlo en la carpeta local ./node_modules donde el nodo lo buscará.

Mantengo mis cosas así:

cd ~/Sites/
mkdir sweetnodeproject
cd sweetnodeproject
npm install socket.io

Crear un archivo app.js

// app.js
var socket = require('socket.io')

ahora ejecuta mi aplicación

node app.js

Asegúrate de estar usando npm >= 1.0y node >= 4.0.

Jamund Ferguson
fuente
8
Él pregunta sobre el uso de paquetes npm instalados globalmente.
UpTheCreek
@Jamund. Está mostrando cómo usar el paquete instalado localmente, pero la pregunta original era sobre los globales.
Vitaliy Markitanov