2012-09-25 82 views
6

故宫文档这样说:访问一个Node.js的全球模块

  • 如果你安装你想要在你的程序中使用的东西,使用 需要(“不管”),然后安装它在本地,在您的项目的根源。
  • 如果您正在安装某些要在shell中使用的东西,请在命令行或 上进行全局安装,以使其二进制文件最终位于PATH环境变量中。

我目前正在写---或者,至少,尝试写---从外壳使用节点真正的命令行程序的预期。因此,根据以上所述,我的依赖应该被安装为全局模块。

我怎么实际上使用一个全局模块安装npm在节点?当然,调用require()不起作用,因为默认情况下npm全局模块目录(/usr/local/lib/node_modules)不在路径上。我可以通过将它明确地添加到程序顶部的路径来使其工作,但这是一个非常糟糕的解决方案,因为它不是可移植的 - 它需要了解npm的全局模块目录在任何给定系统上的位置。

只是为了让生活更加恶化,我通过dpkg安装了一些全局模块。这些已被放入/usr/lib/nodejs,他们只是工作。这使我感到困惑,因为如果全局模块不应该用于普通应用程序,那么我预计不会在路上;否则我会期望他们都走在路上,并要求全球模块到处工作。有一个而不是另一个似乎很奇怪。这里发生了什么?

更新:我应该指出,这个程序只是一个脚本,顶部是#!/usr/bin/env nodejs;它不是一个正式的节点模块,对于一些相当微不足道的东西来说这太过于夸张了。由于所有Debian模块都需要这样的脚本,因此我认为npm的全局模块应该也是必需的,但我有一种感觉,那就是Debianism ...

回答

1

因此,您所使用的指令npm模块,但你正在做本地开发。这里有一些指导原则。

在你的源代码方面,你只需要2种require声明

var dep = require('somedep') 

使用此对任何核心模块(如fs)和第三方模块库中的需求,你是包括通过NPM(将它们作为依赖项列在你的package.json中)。这里指定一个非限定的包名,节点根据其搜索算法找到该模块。

var mymod = require('./lib/mymod') 

用于通过相对于当前JavaScript文件的路径来要求项目本身中的其他模块。

这就是你要做的所有事情来处理你的JavaScript依赖关系。

好吧,现在你如何安装你的依赖关系?

对于本地发展(项目源代码树中),只是cd到项目目录并运行npm install,它会读取你的package.json文件,并安装你在node_modules子目录需要的模块和一切都会好的地方发展。

如果您实际上将其作为npm模块发布,其他用户(您既可以是开发人员也可以是其他用户),如果他们想要访问项目的二进制实用程序,可以使用npm -g进行安装在他们的PATH上需要包含/usr/lib/nodejs/lib/node_modules,但在这种情况下,npm -g将一次处理您的代码和项目的依赖关系。

以下是您感到困惑的地方。

因此,根据以上所述,我的依赖关系应该被安装为全局模块。

您不需要显式安装依赖项作为全局变量,只需要您感兴趣的顶级模块,在本例中就是您的项目本身。 npm将自动处理依赖关系,这是它生命中的主要目的。您的项目依赖性不会全局安装,而是在项目的node_modules子目录中进行安装,这将在全局安装。

这里的目录和什么生活在那里:

  • ~/yourproject:地方发展的源代码
  • ~/yourproject/node_modules:在开发过程中使用的项目NPM模块。 NPM模块(这可能最终包括yourproject如果你把它发布到NPM注册表),其在全球范围内安装
  • /usr/lib/nodejs/lib/node_modules/yourproject/node_modules:在~/yourproject
  • /usr/lib/nodejs/lib/node_modules运行npm install创建/填充你的项目的依赖将在这里得到,当你做npm install -g yourproject安装

您可能还会发现my blog post on managing interpreters and the PATH有关。

+0

是的,但这只适用于重量级项目,这不是:这实际上是一个shell脚本,顶部带有'#!/ usr/bin/env nodejs'的源文件。它将被卡在'/ usr/local/bin'中以供机器上的其他用户使用。强制用户创建一个本地项目目录,以便它们可以运行这是不合理的。考虑到脚本已经可以通过'require()'获得Debian全局模块,为什么我不能使用npm? –

+0

你让开发者感到困惑。对于用户,您将模块发布到npm注册表,并且用户只需键入'npm install -g yourproject'并完成。如果你在你的package.json中将shell脚本封装器标记为二进制文件(请参阅'npm help json'),npm将把它放在正确的位置,以便用户可以运行它。 –

+0

但我没有一个模块,这是我的观点。没有package.json,也没有shell脚本包装器。我知道我不需要有一个模块来做到这一点,因为如果我试图访问Debian安装的所有节点模块都可以。这只是npm的不起作用。我开始怀疑npm不支持这个用例,并且Debian已经摆弄他们的节点设置来明确地完成这个工作。这看起来似乎合理吗? –

4

因此,根据以上所述,我的依赖关系应该被安装为全局模块。

不完全。

这意味着,你的模块可以安装作为一个全球性的,从而其binaries将可从外壳:

npm install -g your-module 
your-module-binary --option etc. 

它的依赖,另一方面,应按照第1点安装,位于您项目的node_modules目录中(通常在package.json中指定,因此npm可以管理它们)。

但是,全局模块通常不适用于require。它们不遵循Loading from node_modules folders,对于本地模块,npm遵循的NODE_PATH变量。