web-dev-qa-db-ja.com

NodeJSにはグローバルモジュール/パッケージが必要です

私はグローバルにインストールして、次のようにforeverforever-monitorを使用しようとしています:

npm install -g forever forever-monitor

通常の出力と、ファイルをグローバルパスにコピーする操作も表示されますが、require("forever");を実行しようとすると、モジュールが見つからなかったというエラーが表示されます。

私はノードとnpmの両方の最新バージョンを使用しており、npmがグローバルインストールとローカルインストールで行った変更についてはすでに知っていますが、私は本当にしたくないすべてのプロジェクトにlocalyをインストールし、 m linkをサポートしていないプラットフォームで作業しているので、グローバルインストール後はnpm linkは使用できません。

私の質問は、なぜグローバルにインストールされたパッケージを要求できないのですか?それは機能またはバグですか?それとも私は何か間違ったことをしていますか?

PS:明確にするために、ローカルにインストールしたくありません。

128
alexandernst

Node.jsでは、requireはグローバルモジュールがインストールされているフォルダーを検索しません。

これを修正するには、NODE_PATH環境変数を設定します。 Linuxでは、これは次のようになります。

export NODE_PATH=/usr/lib/node_modules

注:これは、グローバルモジュールが実際にインストールされている場所によって異なります。

参照: グローバルフォルダーからの読み込み

185
Daniel Uzunu

パッケージをグローバルにインストールした後、ローカルプロジェクトをグローバルパッケージにリンクする必要があります

npm install express -g
cd ~/mynodeproject/
npm link express  

こちら をご覧ください

89
user568109

ネクロマンシーをおologiesびしますが、グローバルにインストールされたモジュールへのハードコーディングされたパスを指定できます。

var pg = require("/usr/local/lib/node_modules/pg");

これは完全ではありませんが、Unity3dがプロジェクトディレクトリに含まれるすべてのjavascriptを「コンパイル」しようとすることを考えると、実際にはパッケージをインストールできません。

23
Thomas Ingham

これは古い質問ですが、package.jsonsemverスクリプトでpreinstallを使用してバージョンチェックを実行しようとしたときに、これに遭遇しました。インストールされているローカルモジュールに依存できないことがわかっているため、グローバルnode_modulesフォルダーからsemverを要求するためにこれを使用しました(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フォルダーのフラットな構造があるため、他のグローバルにインストールされたパッケージの依存関係が見つかる場合があります。

これが誰かに役立つことを願っています。

18
Joe Skeen

この問題を解決するには、パッケージ requireg を使用できます。

var forever = require('requireg')('forever')

トリックを行います。

また、別のモジュール global-npm があります。グローバルnpmの使用に固有のモジュールですが、 短いコード を見て、この手法がどのように機能するかを確認できます。

15
JP Richardson

ドキュメント に従って、Node.jsはデフォルトで次の場所を検索します。

  1. NODE_PATH環境変数で指定されたパス

    注:NODE_PATH環境変数は、コロンで区切られた絶対パスのリストに設定されます。

  2. 現在のnode_modulesフォルダー(ローカル)

  3. $HOME/.node_modules(グローバル)

    注:$HOMEは、ユーザーのホームディレクトリです。

  4. $HOME/.node_libraries(グローバル)
  5. $PREFIX/lib/node(グローバル)

    注:$PREFIXはNode.jsで構成されたnode_prefixです。

    node_prefixの現在の値を確認するには、次を実行します。

    node -p process.config.variables.node_prefix
    

    注:プレフィックスは、ビルド中の--prefix paramに対応し、process.execPathに相対的です。 npm config get prefixコマンドの値と混同しないでください。ソース

指定されたモジュールが見つからない場合、それは上記の場所のいずれにも存在しないことを意味します。

モジュールがインストールされているグローバルルートフォルダの場所は、npm root -g(デフォルトでは npmrc file でオーバーライドされない限り、実行時にパスが計算されます)で印刷できます。

解決

次の回避策を試すことができます。

  • 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コマンドで再テストします。

  • スクリプトを呼び出す前に、現在のフォルダーを拡張機能がグローバルにインストールされている場所に一時的に変更します。例えば。

    npm install -g forever
    cd "$(npm root -g)"
    echo 'require("forever")' | node
    cd -
    
  • npm userconfigファイルnpm help 5 npmrcを参照)またはuserconfig param(--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 local install package to custom location

  • シンボリックリンクの作成 グローバルパッケージの場所から現在のフォルダーに。例えば。

    npm link forever
    
14
kenorb

puppeteerのような大きなモジュールに依存するCLIユーティリティの場合、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)
}
2

次の行を.profileファイルに配置できます。

export NODE_PATH = "$(npm config get prefix)/ lib/node_modules"

これにより、nodeがグローバルパスを使用するようになります。

0
Luis Paulo