我在节点中有几个应用程序,它们共享我编写的几个模块。这些模块不能通过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等)
答案 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(...)语句。
答案 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
这应该适用于这两个应用程序。