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

rob*_*rob 66 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)
Run Code Online (Sandbox Code Playgroud)

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

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

alm*_*pal 45

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

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

  hello
  | index.js
  | package.json
Run Code Online (Sandbox Code Playgroud)

这些文件的典型实现方式是

index.js

  exports.world = function() {
     return('Hello World');
  }
Run Code Online (Sandbox Code Playgroud)

的package.json

  {
    "name": "hello",
    "version": "0.0.1",
    "private": true,
    "main": "index.js",
    "dependencies": {
    },
    "engines": {
    "node": "v0.6.x"
    }
  }
Run Code Online (Sandbox Code Playgroud)

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

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

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

 hello-world
 | app.js
Run Code Online (Sandbox Code Playgroud)

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

 npm link hello
Run Code Online (Sandbox Code Playgroud)

现在像任何其他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);
Run Code Online (Sandbox Code Playgroud)

  • 在部署到诸如 Heroku 或 Nodejitsu 之类的 PaaS 环境时,这是如何工作的? (7认同)
  • 这就是我不明白的地方 - 如果你从 git 部署到 Heroku,你不会签入你的 node_modules。另外,这意味着你在签入之前将共享代码复制到 node_modules 文件夹中。这看起来很麻烦并且错误易于。或者我错过了什么?谢谢! (2认同)

Bin*_*los 19

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

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

"private": true
Run Code Online (Sandbox Code Playgroud)

在每个私有的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)
Run Code Online (Sandbox Code Playgroud)

重点是node.js有一个处理这个问题的机制,它很棒.只需将它与"非NPM上的私人"技巧结合起来就可以了.

简而言之:

require('somemodule')
Run Code Online (Sandbox Code Playgroud)

从应用程序A或B向上级联,直到找到该模块 - 无论它是低位还是高位.确实 - 这使您可以在不更改任何require(...)语句的情况下热交换位置.

node.js模块文档

  • 当我尝试这个时,无法解析共享模块所需的任何模块.在您的结构中,看起来最高的node_modules文件夹具有私有(已检入源控件)和公共(已安装的npm - 未签入)模块.我不会将公共模块检查到源代码控制中 - 你是如何解决这个问题的? (6认同)

Tan*_*pal 5

只需在您的require呼叫中使用正确的路径

例如在server.js中将是:

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

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

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

  • 但是,如果我这样做了,然后该模块尝试要求使用npm的模块,则会感到困惑并给出错误。 (6认同)
  • 没有答案?那是因为你试图用 Node 构建比演示更复杂的东西 (2认同)

Moh*_*ine 5

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

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

请参阅: 如何在没有自己的注册表的情况下安装私有 NPM 模块?