如何在node.js应用程序之间共享代码?

时间:2012-07-01 01:22:28

标签: node.js npm

我在节点中有几个应用程序,它们共享我编写的几个模块。这些模块不能通过npm获得。我希望能够在应用程序之间自由共享,但我不想复制目录,也不想依赖Git这样做。我也不是很喜欢用符号链接来做这件事。

我想安排这样的目录:

app1
 server.js
 node_modules
  (public modules from npm needed for app1)
 lib
  (my own modules specific to app1)

app2
 server.js
 node_modules
  (public modules from npm needed for app2)
 lib
  (my own modules specific to app2)

shared_lib
 (my own modules that are used in both app1 and app2)

我看到的问题是,shared_lib中的模块似乎对于在哪里找到将在其运行的任何应用程序的node_modules目录中的模块感到困惑。至少我认为这是问题所在。

那么....有什么好方法可以避免重复文件? (请注意,我不关心node_modules中的重复项,因为那些不是我的代码,我不会将它们检入Git等)

5 个答案:

答案 0 :(得分:42)

Node建议使用npm link在本地创建自己的node.js包,然后将其提供给其他应用程序。这是一个简单的四步过程。

典型的程序是首先使用以下结构创建包

  hello
  | index.js
  | package.json

这些文件的典型实现是

index.js

  exports.world = function() {
     return('Hello World');
  }

的package.json

  {
    "name": "hello",
    "version": "0.0.1",
    "private": true,
    "main": "index.js",
    "dependencies": {
    },
    "engines": {
    "node": "v0.6.x"
    }
  }

'private:true'确保npm拒绝将其发布到存储库。这是一种防止意外发布私有存储库的方法。

接下来导航到应用程序文件夹的根目录,运行npm链接以全局链接该文件,以便可以在其他包中使用。

现在在另一个应用程序中使用此程序包,请说出具有以下目录结构的hello-world

 hello-world
 | app.js

导航到hello-world文件夹并运行

 npm link hello

现在像其他任何npm包一样使用它

app.js

  var http = require('http');
  var hello = require('hello');

  var server = http.createServer(function(req, res) {
     res.writeHead(200);
     res.end(hello.world());
  });
  server.listen(8080);

答案 1 :(得分:17)

我通过在不同级别拥有 node_modules 文件夹来实现这一点 - 然后节点会自动向上遍历,直到找到模块。

请注意,您不必发布到npm以在node_modules中包含模块 - 只需使用:

"private": true

在您的私人 package.json 文件中 - 对于您的项目,我会有以下内容:

app1
 server.js
 node_modules
  (public modules from npm needed for app1)
  (private modules locally needed for app1)

app2
 server.js
 node_modules
  (public modules from npm needed for app2)
  (private modules locally needed for app2)

node_modules
  (public modules from npm needed for app1 & app2)
  (private modules locally for app1 & app2)

关键是node.js有一个处理这个的机制,它很棒。只需将它与'私人非NPM'技巧结合起来,你就可以了。

简而言之:

require('somemodule')

从应用程序A或B向上级联,直到找到该模块 - 无论它是低位还是高位。确实 - 这可以让您热插拔位置,而无需更改任何 require(...)语句。

node.js module documentation

答案 2 :(得分:4)

只需在您的需求电话中使用正确的路径

例如在server.js中:

  

var moduleName = require('../ shared_lib / moduleName / module.js');

重要的是要知道,只要您的路径前缀为'/','.. /'或'./',路径就相对于调用文件。

有关节点模块加载的更多信息,请访问: http://nodejs.org/docs/latest/api/modules.html

答案 3 :(得分:3)

是的,您可以从app1引用shared_lib,但如果您想将app1打包并部署到某些其他环境(例如AWS上的Web服务器),则会遇到问题。

在这种情况下,最好使用“npm install shared_lib / module”将shared_lib中的模块安装到app1和app2。它还将在app1和app2中安装shared_lib模块的所有依赖项,并处理冲突/重复。

看到这个: How to install a private NPM module without my own registry?

答案 4 :(得分:1)

如果您查看node.js docs,您会看到Node.js也理解package.json文件格式,至少可以轻松地理解。

基本上,如果您有一个名为foo的目录,并且该目录中的package.json文件具有键值对:"main": "myCode.js",那么如果您尝试{{1}并且它在里面找到一个require("foo")文件的目录,然后它将package.json模块用于foo/myCode.js

因此,使用您的目录结构,如果每个共享库都有自己的目录,里面有这么简单的foo文件,那么您的应用程序可以通过以下方式获取共享库:

package.json

这应该适用于这两个应用程序。