NodeJS требует глобального модуля/пакета
Я пытаюсь установить глобально, а затем используйте forever
и forever-monitor
следующим образом:
npm install -g forever forever-monitor
Я вижу обычный вывод, а также операции, которые копируют файлы на глобальный путь, но затем, если я пытаюсь выполнить require("forever");
, я получаю сообщение о том, что модуль не найден.
Я использую последнюю версию как node, так и npm, и я уже знаю об изменении, которое npm сделал в глобальной или локальной установке, но я действительно не хочу устанавливать локально на каждый проект, и я работаю на платформе, которая не поддерживает link
, поэтому npm link
после того, как глобальная установка мне не подходит.
Мой вопрос: почему я не могу требовать установить глобально установленный пакет? Это функция или ошибка? Или я делаю что-то неправильно?
PS: Просто, чтобы сделать его кристально чистым: я не хочу устанавливать локально.
Ответы
Ответ 1
В Node.js require не смотрит в папку, где установлены глобальные модули.
Вы можете исправить это, установив переменную среды NODE_PATH. В Linux это будет:
export NODE_PATH=/usr/lib/node_modules
Примечание. Это зависит от того, где на самом деле установлены ваши глобальные модули.
См.: Загрузка из глобальных папок.
Ответ 2
После установки пакета по всему миру вам нужно связать локальный проект с глобальным пакетом
npm install express -g
cd ~/mynodeproject/
npm link express
Смотрите здесь
Ответ 3
Извиняюсь за некромантию, но я могу указать жестко запрограммированные пути к глобально установленным модулям:
var pg = require("/usr/local/lib/node_modules/pg");
Это не идеально, но, учитывая, что Unity3d пытается "скомпилировать" весь javascript, который включен в каталог проекта, я действительно не могу установить какие-либо пакеты.
Ответ 4
Я знаю, что это старый вопрос, но я столкнулся с этим, пытаясь выполнить некоторую проверку версий, используя semver
в preinstall
script в package.json
. Поскольку я знал, что не могу зависеть от каких-либо локальных модулей, я использовал это, чтобы потребовать semver
из глобальной папки node_modules
(поскольку npm
зависит от нее, я ее там знаю):
function requireGlobal(packageName) {
var childProcess = require('child_process');
var path = require('path');
var fs = require('fs');
var globalNodeModules = childProcess.execSync('npm root -g').toString().trim();
var packageDir = path.join(globalNodeModules, packageName);
if (!fs.existsSync(packageDir))
packageDir = path.join(globalNodeModules, 'npm/node_modules', packageName); //find package required by old npm
if (!fs.existsSync(packageDir))
throw new Error('Cannot find global module \'' + packageName + '\'');
var packageMeta = JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json')).toString());
var main = path.join(packageDir, packageMeta.main);
return require(main);
}
Мне нравится этот подход, потому что для этого не требуется установка каких-либо специальных модулей.
Я не пошел с решением NODE_PATH
, как это предлагали другие, поскольку я хотел, чтобы это работало на любой машине, без необходимости требовать дополнительной настройки/настройки перед запуском npm install
для моего проекта.
Как это закодировано, гарантируется только найти модули верхнего уровня (установленные с помощью npm install -g ...
) или модули, требуемые npm
(перечислены как dependencies
здесь: https://github.com/npm/npm/blob/master/package.json). Если вы используете более новую версию NPM, она может найти зависимости от других пакетов, установленных на глобальном уровне, так как теперь существует более плохая структура для node_modules
.
Надеюсь, что это кому-то полезно.
Ответ 5
Вы можете использовать пакет requireg
для решения этой проблемы:
var forever = require('requireg')('forever')
сделает трюк.
Кроме того, есть еще один модуль global-npm
, хотя он специфичен только для использования глобального npm
, вы можете посмотреть короткий код и посмотреть, как работает эта техника.
Ответ 6
Согласно документации, Node.js будет искать в следующих местах по умолчанию:
-
Путь, указанный в переменной среды NODE_PATH
.
Примечание. NODE_PATH
среды NODE_PATH
задается в виде списка абсолютных путей, разделенных двоеточиями.
-
Текущая папка node_modules
. (локальный)
-
$HOME/.node_modules
(глобальный)
Примечание: $HOME
- домашний каталог пользователя.
-
$HOME/.node_libraries
(глобальный) -
$PREFIX/lib/node
(global)
Примечание: $PREFIX
- это Node.js, настроенный node_prefix
.
Чтобы проверить текущее значение node_prefix
, запустите:
node -p process.config.variables.node_prefix
Примечание. Префикс соответствует параметру --prefix
во время сборки и --prefix
к process.execPath
.Не путать со значением из команды npm config get prefix
.источник
Если данный модуль не может быть найден, это означает, что он не присутствует ни в одном из указанных мест.
Расположение глобальной корневой папки, в которой установлены модули, можно распечатать: npm root -g
(по умолчанию путь вычисляется во время выполнения, если он не переопределен в файле npmrc
).
Решение
Вы можете попробовать следующие обходные пути:
-
Укажите местоположение вашего глобального модуля в переменной среды NODE_PATH
. Например
echo 'require("forever")' | NODE_PATH="$(npm root -g):$NODE_PATH" node
Чтобы проверить и распечатать значение NODE_PATH
, выполните:
echo 'console.log(process.env.NODE_PATH); require("forever")' | NODE_PATH="$(npm root -g):$NODE_PATH" node
-
Для более постоянного решения, свяжите вашу глобальную пользовательскую папку $HOME/.node_modules
чтобы указать на корневую папку, выполнив эту команду:
ln -vs "$(npm root -g)" "$HOME"/.node_modules
Затем повторно протестируйте его с помощью: echo 'require("forever")' | node
команда echo 'require("forever")' | node
.
-
Временно измените текущую папку, где расширение было установлено глобально, прежде чем вызывать скрипт. Например
npm install -g forever
cd "$(npm root -g)"
echo 'require("forever")' | node
cd -
-
Сконфигурируйте глобальное назначение установки в файле npm
userconfig (см. npm help 5 npmrc
) или с userconfig
параметра userconfig
(--prefix
).
Чтобы отобразить текущую конфигурацию, запустите: npm config list
.
Чтобы редактировать текущую конфигурацию, запустите: npm config edit
.
-
Укажите полный путь расположения узловых модулей при вызове require()
. Например
require("/path/to/sub/module")
-
Установите пакет в другое место, например
npm install forever -g --prefix "$HOME"/.node_modules
Тем не менее, установка будет идти в ~/.node_modules/lib/node_modules/
, поэтому расположение все еще нужно добавить.
Смотрите: локальный установочный пакет npm в произвольном месте
-
Создайте символическую ссылку в текущей папке из местоположения глобального пакета. Например
npm link forever
Ответ 7
Вы можете поместить эту строку в свой файл .profile
:
export NODE_PATH = "$ (префикс префикса конфигурации npm)/lib/node_modules"
Это заставит node
использовать глобальный путь.
Ответ 8
Для утилит CLI, которые зависят от больших модулей, таких как puppeteer
, мне нравится порождать npm root -g
и использовать его для npm root -g
глобального модуля.
try {
const root = require('child_process').execSync('npm root -g').toString().trim()
var puppeteer = require(root + '/puppeteer')
} catch (err) {
console.error('Install puppeteer globally first with: npm install -g puppeteer')
process.exit(1)
}