7

我有一个 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 我想将我的模型和身份验证传递给我的路由,实用程序可以被很多东西使用。

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 来清理内容,但这仍然让我不得不保存诸如实用程序之类的内容并将其传递给其他 require 调用。

我可以将每个要求仅放在需要的较低模块中,但最终我会用我的要求爬升目录结构,这看起来也很混乱,即:

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

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

任何建议。几天来,我一直在尝试对其进行重组,但我只是不停地把头撞在墙上,因为我所做的任何事情都没有真正让它变得更好。

最好是一个很好的节点项目布局,它使用像猫鼬、快递、带自定义模块的东西。并展示了一种处理模块之间相互依赖关系的好方法。

4

2 回答 2

2

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

我也很头疼如何正确构建我的第一个真正的大型 node.js 项目。您遇到的最大问题是require()调用中使用的相对路径。这很痛苦,因为这些路径是相对于当前文件的,所以你通常有这样的路径:

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

它们都指向同一个文件。这是不人道的。难以阅读,难以维护。

您不应该将您的模块放在 node_modules 目录中,而只需按模块名称 ( require("a")) 要求模块,因为该目录被第三方模块使用。如果您需要执行维护任务,例如执行所有模块的完整升级、删除它们并重新安装它们等,它们非常容易和安全。如果你把你的模块放在那里,如果你没有一个好的文档并且你在一个中型团队中工作,那么你将遇到一个大问题。

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

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

使用该mod()功能,您可以很好地控制您的模块。在我的真实和大项目中,我的 mod 功能如下:

"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/...")它返回构建静态资产所需的模块(编译 css 和 js)

ETC


现在,您误解了必须如何使用模块。例子:

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 模块中获取实用程序模块。

非常基本的例子:

A 取决于 B

//app.js
require ("./a").a ();

//a.js
var b = require ("./b");
module.exports = {
  a: function (){
    b.b ("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){
    b.b ("I'm A");
  }
};

//b.js
module.exports = {
  b: function (msg){
    console.log ("B says: " + msg);
  }
};

这是你想要的?

于 2013-06-22T17:08:42.923 回答
1

1-在项目根目录中创建一个文件,命名为settings.js

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

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

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

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

4-任何时候你想要你的项目目录就可以使用

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

这样,您将拥有与该文件相关的所有项目目录;)

于 2013-11-22T20:44:01.423 回答