Как импортировать глобальные модули в Node? Я получаю сообщение «Ошибка: не удается найти модуль <module>»?

145

Я пытаюсь настроить узел на Mac OSX Lion. Кажется, все работает нормально, но я не могу импортировать какие-либо модули из моей глобальной папки модулей. Я получаю ошибку,

Error: Cannot find module <module>

Если я запускаю это:, node -e require.pathsя получаю ответ:

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

Что верно, мои модули действительно установлены в / usr / local / lib / node_modules. Когда я пытаюсь запустить скрипт, я получаю следующее:

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)

Мой .bash_profile выглядит так:

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

Был бы очень признателен за помощь, я понятия не имею, почему я не могу импортировать какие-либо библиотеки.

Hanpan
источник
1
Вы знаете, что это не совсем предпочтительный способ делать вещи, верно?
thejh
1
Не могли бы вы уточнить? Вы имеете в виду, что я не должен устанавливать библиотеки в мою глобальную папку?
Hanpan
3
@Hanpan: Предпочтительный способ - установить модули, которые вы хотите использовать, через require () локально.
thejh
1
Более качественный и обновленный ответ (на который нельзя положиться npm link) можно найти здесь: stackoverflow.com/a/15646750/2671392
GGG
1
Я старая школа и привык устанавливать библиотеки в разных местах. Я никогда не видел убедительной причины для интенсивного использования локальной библиотеки. Класс mongodb, который я беру, закончится примерно с сотней небольших проектов к тому времени, когда мы закончим, каждый из которых будет содержать в основном дублированный набор библиотек - mongodb, express, консолидировать и т. Д. Переход на интерактивные языки оставляет депозиты местных библиотек повсюду. У меня должно быть тысячи Scala-библиотек в местных хранилищах Scala. То же самое Метеор, заводной и рубиновый.
Стивен В. Райт

Ответы:

116

Если вы используете npm> = 1.0, вы можете использовать npm link <global-package>для создания локальной ссылки на пакет, уже установленный глобально. ( Предостережение: ОС должна поддерживать символические ссылки. )

Однако это не без проблем.

npm link - это инструмент разработки. Это здорово для управления пакетами в вашей локальной коробке разработки. Но развертывание с помощью ссылки на npm в основном вызывает проблемы, поскольку позволяет очень просто обновлять вещи, не осознавая этого.

В качестве альтернативы вы можете установить пакеты как локально, так и глобально.

Для получения дополнительной информации см.

Тадеуш Войчик
источник
69
Я читаю это и не могу поверить своим глазам. Так что, если я установлю, скажем, экспресс, и затем у меня будет 20 проектов для сборки поверх экспресса, мне нужно будет установить его 20 раз, для каждого из них, в каждой папке проекта, снова и снова? У меня нет большого опыта работы с менеджерами пакетов, но это отстой ...
treznik
25
Это правильно, и если вы думаете об этом, это имеет смысл. Локальное управление вашими зависимостями делает все автономным и позволяет вам указать конкретную версию зависимости для любого данного проекта (например, для проекта foo требуется экспресс 2.x, в то время как панель проекта может использовать экспресс 3 бета).
grahamb
43
Я тоже некоторое время пытался понять логику этого, но после того, как мои друзья из Ruby боролись за глобальные обновления пакетов, спорили о наборе гемов и часто просто никогда не обновлялись, я признал, что локальная установка зависимостей - абсолютно единственный разумный способ сделать это. управление пакетами .
Тимоксли
3
Я хотел бы провести параллель между этой ситуацией и ситуацией со статическими ссылками и динамическими библиотеками, поскольку это относится к распространению программного обеспечения. Учтите, что почти все приложения, распространяемые в магазине приложений iOS, должны статически связывать зависимости, не предоставляемые iOS SDK. Почему это сделано? Глобальная адская зависимость - очень реальная вещь.
Стивен Лу
1
Я также понимаю, что npmкэш (который находится в ~/.npm) сделает целесообразным процесс переустановки, выполняемый в разных местах.
Стивен Лу,
85

Node.js использует переменную окружения, NODE_PATHчтобы указать дополнительные каталоги для включения в путь поиска модуля. Вы можете использовать npmсебя, чтобы сообщить вам, где глобальные модули хранятся с помощью npm root -gкоманды. Соединяя эти два элемента, вы можете убедиться, что глобальные модули включены в ваш путь поиска с помощью следующей команды (в Linux-ish)

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

Джоэл Б
источник
3
Спасибо за NODE_PATHподсказку переменной окружения. Это очень помогло!
rekire
7
Это должен быть главный комментарий
Адам
Я должен был установить NODE_PATHэквивалентный путь posix, чтобы заставить npm работать на MSYS2. Спасибо.
Джойс Бабу
Работает с Windows и Git Bash тоже. Отлично. :-)
inf3rno
Это делает вашу .node_modulesпапку доступной для поиска, но для того, чтобы импортировать модули с помощью require(), они все равно должны быть установлены в вашем локальном каталоге проекта (или, наоборот, связаны с использованием npm link). Глобальные модули не могут быть импортированы в проекты, оттуда могут быть запущены только двоичные файлы / сценарии.
Прахлад Ери
65

Вы можете использовать ссылку npm для создания символической ссылки на ваш глобальный пакет в папке ваших проектов.

Пример:

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

Все, что он делает, это создает локальную папку node_modules, а затем создает символическую ссылку -> [глобальный каталог] / node_modules / express, которая затем может быть решена с помощью require('express')

Ник Сотирос
источник
Это кросс-ОС совместимо?
UpTheCreek,
Более новые версии Windows поддерживают его начиная с этой версии: github.com/npm/npm/commit/… Для более старых версий Windows попробуйте npmjs.com/package/npm-junction
Alex
22

Установите любой пакет глобально, как показано ниже:

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

Поскольку этот модуль замены установлен глобально, поэтому, если вы видите папку модулей вашего узла, вы не увидите там замену модуля, и поэтому вы не можете использовать этот пакет, используя require ('replace').

потому что с require вы можете использовать только локальные модули, которые присутствуют в папке вашего модуля узла.

Теперь, чтобы использовать глобальный модуль, вы должны связать его с путем к модулю узла, используя команду ниже.

$ npm link replace

Теперь вернитесь и посмотрите папку вашего модуля узла, теперь вы можете видеть там замену модуля и можете использовать его с требованием («заменить») в вашем приложении, так как он связан с вашим модулем локального узла.

Пожалуйста, дайте мне знать, если какие-либо дополнительные разъяснения необходимы.

user5341372
источник
14

В качестве аргумента вы можете использовать require с путем к каталогу глобального модуля.

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

На моем Mac я использую это:

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

Как найти ваши глобальные модули? -> Где npm устанавливает пакеты?

вереск
источник
7

Установка переменной среды NODE_PATH, чтобы она указывала на вашу глобальную node_modulesпапку.

В Windows 7 или выше путь похож на %AppData%\npm\node_modulesто, что в UNIX может быть, /home/sg/.npm_global/lib/node_modules/но зависит от конфигурации пользователя.

Команда npm config get prefixможет помочь определить правильный путь.

В системах UNIX вы можете выполнить это с помощью следующей команды:

export NODE_PATH=`npm config get prefix`/lib/node_modules/
Бен Сюй
источник
0

Я использую Docker. Я пытаюсь создать образ Docker, в котором установлены все мои зависимости узлов, но я могу использовать мой локальный каталог приложений во время выполнения контейнера (без загрязнения его каталогом node_modules или ссылкой). Это вызывает проблемы в этом сценарии. Мой обходной путь должен требовать от точного пути, где модуль, например, требуют ('/ usr / local / lib / node_modules / socket.io')

Дарин Лондон
источник
-1

require.paths устарела.

Перейдите в папку вашего проекта и введите

npm install socket.io

он должен установить его в локальной папке ./node_modules, где его будет искать узел.

Я держу свои вещи так:

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

Создайте файл app.js

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

Теперь запустите мое приложение

node app.js

Убедитесь, что вы используете npm >= 1.0и node >= 4.0.

Джамунд Фергюсон
источник
8
Он спрашивает об использовании глобально установленных пакетов npm.
UpTheCreek,
@Jamund. Вы показываете, как использовать локально установленный пакет, но оригинальный вопрос был о глобальных.
Виталий Маркитанов