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 будет искать в следующих местах по умолчанию:

  1. Путь, указанный в переменной среды NODE_PATH.

    Примечание. NODE_PATH среды NODE_PATH задается в виде списка абсолютных путей, разделенных двоеточиями.

  2. Текущая папка node_modules. (локальный)

  3. $HOME/.node_modules (глобальный)

    Примечание: $HOME - домашний каталог пользователя.

  4. $HOME/.node_libraries (глобальный)
  5. $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)
}