在Node应用程序之间共享代码

时间:2014-01-30 16:04:38

标签: node.js git version-control npm

我们的应用程序包含两个组件:API和客户端。两者都是独立的Node应用程序虽然除了文档之外,API并没有真正的前端组件,但它们仍然共享一些常见文件,如Jade组件,规范化CSS,实用程序模块以及最重要的Mongoose架构& MongoDB交互的模型定义。我真的不想习惯我首先对API进行更改的工作流程,然后将更改的文件复制到客户端,反之亦然,因此找到一个可行的解决方案会很棒。

跨节点应用分享杂项代码的最佳方法是什么?

在浏览网页时,我遇到了几个解决方案,但在这种情况下,它们都没有真正起作用。

一种解决方案是从公共文件中创建一个节点模块,并使用NPM在应用程序之间保持同步,但这意味着我(以及可能的未来开发者)必须知道哪些文件是公共模块的一部分,并要求他们使用require('node_modules/mongo/schemas/example.js')代替require('mongo/schemas/example.js')。由于假设可能存在数百个常见文件,因此无法记住文件是否通用,特别是对于新开发人员。

另一种解决方案是制作公共模块的git子模块。这将是完美的,如果我只能包含Node的require路径的子模块路径,那么如果它没有在预期的位置找到所需的文件(比如mongo/schemas/example.js),它将在公共子模块中查找(common/mongo/schemas/example.js)。这将是非常棒的,因为它允许用“本地”版本覆盖公共文件。这有点像Magento的作品。这里的问题是Node不允许编辑require路径(至少在Node 0.5之前就已经可以了),所以这很糟糕。

第三种解决方案是将公共存储库的内容粗暴地合并到应用程序的根目录中。在这个解决方案中没有真正无法解决的问题,但我觉得这是一个不好的做法。毕竟,它将无法通过应用程序编辑公共文件,因为没有办法有选择地将公共文件推送到公共git存储库。因此,基本上这个解决方案只会使工作流更加繁琐:对公共文件的所有修改都必须手动复制到公共代码库,推送到git远程,然后复制到其他应用程序。因此,这个解决方案绝对不会为我削减它。

似乎第二种解决方案是我唯一的(也是最好的)选择,除非你们想出一个更好的选择(我真的希望:D)。如果有人知道改变节点需求路径的方法,我将非常感激。

3 个答案:

答案 0 :(得分:3)

  

一种解决方案是从公共文件中创建节点模块,并使用NPM在应用程序之间保持同步

这是唯一一个很好的解决方案。如果您有共享代码,那么 应该是一个模块。

  

但这意味着我(以及可能的未来开发者)必须知道哪些文件是公共模块的一部分,并且需要使用require('node_modules / mongo / schemas / example.js')而不是require('mongo) /schemas/example.js')例如

没有。它是require('mongo/schemas/example.js')而不是require('./mongo/schemas/example.js')。或者更好,require('mongo').Schemas.example,虽然它需要一些工作。

您必须将代码库拆分为逻辑模块。我猜你有那种噩梦可以证明使用NODE_PATH,但我真的建议重构那个......

答案 1 :(得分:2)

我试图为您完全相同的问题找到解决方案并完成了我指出的所有事情in your other question。一切正常,但我知道我的工作流程可以改进。

尝试1:将远程依赖项添加到package.json并加载为npm依赖项

没有用,因为当Heroku在部署时安装依赖项时,它没有从github获取的ssh密钥,并且基本auth(暴露的用户名和密码)不是一个选项。

尝试2: git子模块进行救援

这带来了your other question已经讨论过的一系列问题。


我终于得到了一个(深思熟虑的)有一切的项目

我用旗帜运行我的应用程序:

node app --module api

node app --module manager

并相应地加载依赖项。

它可能不适合每个项目,但如果你有应用程序共享模型,视图,模板,常量和更多业务逻辑,那么前端和其他方面的权衡是相当不错的。 我不认为存储现在是一个问题所以安装一些更多的依赖和未使用的模块可能不是一个问题(再次,它取决于项目的大小和依赖的数量,在我的情况下,它不是一个问题)。

然后,您可以使用grunt定位每项服务的应用特定任务:

grunt deploy:APIgrunt deploy:managergrunt:build:manager等......

答案 2 :(得分:0)

很棒的问题。

  

“但这意味着我(以及可能的未来开发者)必须知道哪些文件是公共模块的一部分,并且需要它们与require('node_modules / mongo / schemas / example.js')”

实际上并非如此,因为require会根据 Loading from node_modules Folders 文档在项目目录树中搜索node_modules文件夹。

所以你使用npm的第一个选择是非常好的。我实际上也在npm制作了一个模块。设置package.json后,您可以使用npm versionnpm publish发布到npmjs.org。然后,您可以将所需的包放入其他项目package.json中,并使用npm install从npm下载所需的版本。

一个问题是你必须在npmjs.org上开源你的代码,所以如果你不想这样做,你需要 create your own private npm repo

干杯。

相关问题