首页 文章

NodeJS需要全局模块/包

提问于
浏览
113

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

npm install -g forever forever-monitor

我看到通常的输出以及将文件复制到全局路径的操作,但是如果我尝试 require("forever"); ,我会收到错误,说明找不到该模块 .

我正在使用node和npm的最新版本,我已经知道npm在全局和本地安装中所做的更改,但是我在每个项目上都安装了localy,而且'm working on a platform that doesn' t支持 link 所以 npm link 在全局安装后没有'对我来说可能 .

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

PS:只是为了说清楚:我不想在本地安装 .

7 回答

  • 14

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

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

    export NODE_PATH=/usr/lib/node_modules
    

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

    见:Loading from the global folders .

  • 17

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

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

    here

  • 79

    为死灵法术道歉,但我能够为全局安装的模块指定硬编码路径:

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

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

  • 165

    我知道这是一个老问题,但是我试图在 package.jsonpreinstall 脚本中使用 semver 进行一些版本检查时遇到了这个问题 . 因为我知道我不能依赖安装的任何本地模块,所以我用它来从全局 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 所需的模块(在此处列为 dependencieshttps://github.com/npm/npm/blob/master/package.json) . 如果您使用的是较新版本的NPM,它可能会找到其他全局安装包的依赖关系,因为现在 node_modules 文件夹的结构更平坦 .

    希望这对某人有用 .

  • 10

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

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

    会做的伎俩 .

    另外,还有另一个模块global-npm,虽然仅使用全局 npm ,但您可以查看short code并查看该技术的工作原理 .

  • 1

    根据documentation,Node.js默认搜索以下位置:

    • Path specified in the NODE_PATH environment variable .

    注意:NODE_PATH环境变量设置为以冒号分隔的绝对路径列表 .

    • Current node_modules folder. (当地)

    • $HOME/.node_modules (全球)

    注意:$ HOME是用户的主目录 .

    • $HOME/.node_libraries (全球)

    • $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 command.source的值

    如果找不到给定的模块,则表示它不存在于上述位置之一中 .

    安装模块的全局根文件夹的位置可以通过以下方式打印: 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 file(请参阅: npm help 5 npmrc )或 userconfig param( --prefix )中配置全局安装目标 .

    要显示当前配置,请运行: npm config list .

    要编辑当前配置,请运行: npm config edit .

    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
    
  • 22

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

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

    这将使 node 使用全局路径 .

相关问题