大nodejs项目的结构 – 如何处理相互依赖关系

我有一个nodejs项目变得相当大,相当快。 由于我对模块的理解有限,而且我相信我可以做一些事情来清理代码和结构。

<app dir> -app.js - <modules> -module1.js -module2.js - <routes> -route1.js -route2.js - <utilties> -utility1.js -utility2.js - <authentication> -local.js -basic.js -index.js 

我的app.js是相当混乱的,因为我有我的文件之间的依赖关系。 IE浏览器我想通过我的模型和身份validation我的路线,实用程序可以使用一堆东西。

 var app = express(); ... // do express setup var authenticationStrategy = // get auth strategy from config var auth = require('./auth)(authenticationStrategy); var utility1 = require('./utilities/utility1.js'); var utility2 = require('./utilities/utility2.js'); var utilities = { utility1: utility1, utility2: utility2 } var Model1 = require('./models/model1')(utilities); var Model2 = require('./models/model2')(utility1); var models = { Model1: Model1, Model2: Model2 } // Dynamically import all routes fs.readdirSync('routes').forEach(function(file) { if (file[0] == '.') return; var route = file.substr(0, file.indexOf('.')); require('./routes/' + route)(app, models, utilities); }); ... etc 

我现在知道,我可以在每个文件夹中放置一个index.js来清理所有东西,但这仍然使我不得不保存公用事业之类的东西,并将其传递给其他需要的调用。

我可以把每个需求放在较低的模块中,只需要它,然后我最终爬上目录结构与我的需求也似乎凌乱,即:

model1.js:var utility1 = require('../ utilities / utility1.js');

基本上我觉得我的问题是,低级别文件夹中的模块依赖于其他文件夹中的其他模块。 我觉得我应该在app.js中的所有依赖,并将它们传递给需要它们的需要的模块。

任何build议。 我一直在试图重组这个问题几天,我只是不停地将我的头撞在墙上,因为没有任何事情可以做得更好。

最好的做法是使用诸如mongoose,快车,自定义模块之类的东西。 并展示了处理模块之间相互依赖关系的好方法。

编辑: https : //github.com/gagle/node-getmod

我也很头痛,正确地构build我的第一个真正的和大的node.js项目。 您所遇到的最大问题是require()调用中使用的相对path。 这是一个痛苦,因为这些path是相对于当前文件,所以你最终有这样的path:

 ../../../a.js ./a/b/c/a.js ../../a/b/c/a.js 

他们都指向相同的文件。 这是不人道的 很难阅读,很难维护。

你不应该把你的模块放在node_modules目录中,只需要模块的名称( require("a") ),因为这个目录被第三方模块使用。 如果您需要执行维护任务,比如执行所有模块的全面升级,删除和重新安装等,那么这些任务极其简单和安全。 如果你把你的模块放在那里,如果你没有一个好的文档,而且你在一个中等规模的团队中工作,那么你将会遇到一个很大的问题。

几个小时后,我用这种技术结束了:

用于复杂应用程序结构的NodeJS本地模块

使用mod()函数可以很好地控制模块。 在我的真实和BIG项目中,我的modfunction如下:

 "use strict"; var serverType = require ("./server-type"); global.mod = function (file){ var dir = file.substring (0, file.search (/\/|\\/)); if (!dir) dir = file; if (dir === "browser" || dir === "common" || dir === "mobile" || dir === "stream"){ //Relative from the web directory return require ("../" + file); } if (dir === "api"){ //Relative from the api directory return require ("../../" + (file === "api" || file === "api/latest" ? file : "api/" + APP.versions.api + "/" + file.substring (4))); } if (dir === "build"){ //Relative from the build directory return require ("../../" + file); } //Tries to load the module inside browser or mobile directories depending on //the cwd return require ("../" + serverType () + "/" + file); }; 

如果我打电话给mod("api")它会返回我的api模块,这是我网站的核心。

如果我调用mod("common/db")它将返回db包装。

如果我调用mod("build/...")它会返回构build静态资源所需的模块(编译css和js)

等等


现在,你误解了如何使用模块。 例:

 var utility1 = require('./utilities/utility1.js'); var utility2 = require('./utilities/utility2.js'); var utilities = { utility1: utility1, utility2: utility2 } var Model1 = require('./models/model1')(utilities); var Model2 = require('./models/model2')(utility1); var models = { Model1: Model1, Model2: Model2 } 

在这里,您将公用事业模块传递给另一个模块,这不是必需的。 您可以从model1和model2模块中获取utilities模块。

非常基本的例子:

A取决于B

 //app.js require ("./a").a (); //a.js var b = require ("./b"); module.exports = { a: function (){ bb ("I'm A"); } }; //b.js module.exports = { b: function (msg){ console.log ("B says: " + msg); } }; 

你不需要这样做:

 //app.js var b = require ("./b"); require ("./a").a (b); //a.js module.exports = { a: function (b){ bb ("I'm A"); } }; //b.js module.exports = { b: function (msg){ console.log ("B says: " + msg); } }; 

这是你想要的?

1-在项目根目录下创build一个文件,将其称为settings.js

在这个文件里面添加这个代码

 module.exports = { POST_MAX_SIZE : 40 , //MB UPLOAD_MAX_FILE_SIZE: 40, //MB PROJECT_DIR : __dirname }; 

3-里面的node_modules创build一个新的模块名称“settings”,在模块里面index.js写下这段代码:

 module.exports = require("../../settings"); 

4-和任何时候你想要你的项目目录只是使用

 var settings = require("settings"); settings.PROJECT_DIR; 

通过这种方式,您将拥有与此文件相关的所有项目目录;)