199

我正在尝试全局安装,然后foreverforever-monitor这样使用:

npm install -g forever forever-monitor

我看到了通常的输出以及将文件复制到全局路径的操作,但是如果我尝试这样做,require("forever");我会收到一条错误消息,指出找不到模块。

我正在使用 node 和 npm 的最新版本,并且我已经知道 npm 在全局与本地安装中所做的更改,但我真的不想在每个项目上都安装本地化,我正在使用的平台没有'不支持link所以npm link在全局安装后对我来说是不可能的。

我的问题是:为什么我不能要求全局安装包?这是一个功能还是一个错误?还是我做错了什么?

PS:只是说清楚:我不想在本地安装。

4

9 回答 9

256

在 Node.js 中,require 不会查看安装全局模块的文件夹。

您可以通过设置 NODE_PATH 环境变量来解决此问题。在 Linux 中,这将是:

export NODE_PATH=/usr/lib/node_modules

注意:这取决于您的全局模块的实际安装位​​置。

请参阅:从全局文件夹加载

于 2013-03-26T20:28:19.417 回答
115

全局安装包后,您必须将本地项目与全局包链接

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

这里

于 2013-03-26T14:04:44.473 回答
34

为死灵致歉,但我可以指定全局安装模块的硬编码路径:

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

这并不完美,但考虑到 Unity3d 尝试“编译”项目目录中包含的所有 javascript,我真的无法安装任何包。

于 2014-03-07T22:45:20.077 回答
23

根据文档,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构建过程中的参数,它是相对于process.execPath. 不要与npm config get prefix命令中的值混淆。资源

如果找不到给定的模块,则意味着它不存在于上述位置之一。

安装模块的全局根文件夹的位置可以通过以下方式打印:(npm root -g默认情况下,路径是在运行时计算的,除非在npmrcfile中覆盖)。

解决方案

您可以尝试以下解决方法:

  • 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 npmrcuserconfig参数( )中配置全局安装目标--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
    
于 2018-01-07T18:48:18.543 回答
20

我知道这是一个老问题,但是当我尝试semver在. 因为我知道我不能依赖安装的任何本地模块,所以我用它来要求全局文件夹(取决于它我知道它在那里):preinstallpackage.jsonsemvernode_modulesnpm

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列出: https ://github.com/npm/npm/blob/master/package.json )。如果您使用的是较新版本的 NPM,它可能会找到其他全局安装包的依赖项,因为现在文件夹结构更加扁平。dependenciesnode_modules

希望这对某人有用。

于 2016-07-22T20:58:14.080 回答
15

您可以使用该软件包requireg来解决此问题:

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

会成功的。

此外,还有另一个模块 ,global-npm虽然特定于使用 global npm,但您可以查看短代码并了解该技术是如何工作的。

于 2016-01-14T14:52:49.590 回答
10

对于依赖于大​​模块的 CLI 实用程序,例如puppeteer,我喜欢生成 anpm root -g并使用它来 require 全局模块。

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)
}
于 2018-12-20T06:07:01.097 回答
5

您可以将此行放入.profile文件中:

export NODE_PATH="$(npm config 获取前缀)/lib/node_modules"

这将node使用全局路径。

于 2018-02-11T14:37:36.580 回答
0

我尝试遵循其他答案,但对我有用的是

      node_path = "C:\\Users\\{usename}\\AppData\\Roaming\\npm\\node_modules"
      const *modulename* = require(node_path + "\\" +'*modulename*');

于 2020-12-25T23:13:56.837 回答