如何在Node模块中提供对象引用?

时间:2014-08-28 13:14:12

标签: javascript node.js express reference module

我有一个Express.js网络应用程序。在主app.js文件中,我require()一堆第三方依赖项。最近我开始将部分app.js代码提取到单独的模块中,例如

// in app.js
var users = require('./modules/users');

// and then e.g.
// users.add(doc);

在我的模块中,我有时需要使用我的主app.js文件中可用的对象,我想知道将这些对象的引用传递给我的模块的最佳方法是什么。

我目前的做法:

// in app.js

// pass needed object references in initialization step
users.init([db, logger]);

// in modules/users.js

var db, logger;

exports.init = function (deps) {
    db = deps[0];
    logger = deps[1];
};

这种方法有意义吗?有没有更好的方法来执行此操作?

3 个答案:

答案 0 :(得分:2)

当然,只需使用模块! :)

// db.js

// create db instance here rather than in app.js

module.exports = db;

// logger.js

// create logger instance here rather than in app.js

module.exports = logger;

然后

// app.js

var db = require('./db');

// lib/somewhere.js

var db = require('../db');

这样你就可以依赖CommonJS依赖注入系统,而不是依靠自己进行依赖注入(将引用传递给你而不是require模块)。

之所以能按预期工作,原因是模块只被解释一次,所以如果你实例化一次而不是使用工厂函数,它就可以正常工作。

答案 1 :(得分:1)

您应该能够正常require个模块:

// users.js
var db = require('./db');
exports.init = function() {
   // use db in here
};

但是,有时这是不可能的,您需要明确传入模块。 一种方法是在require模块时传递依赖关系:

// users.js
module.exports = function(db, logger) {
    return {
        init: function() { /* use db and logger in here */}
    }; 
}

// app.js
var db = ...;
var logger = ...;
var users = require('./users')(db, logger);
users.init();

这是我个人更喜欢的模式,我认为将依赖项传递给需求比使用某些init方法更简洁。

你会在ExpressJS代码中看到这一点,例如当我们将所有路由放在另一个文件中并需要传递我们的app实例时:

require('./routes')(app);

答案 2 :(得分:1)

如果您需要在app.js而不是自己的模块中专门初始化某些内容,则可以从app.js导出它们,然后需要app.js

// app.js
var db = require("db"),
    logger = require("logger");

// do your initialization with db and logger
module.exports = { db: db, logger: logger };

然后:

// users.js
var db = require("./app").db,
    logger = require("./app").logger;

// use db and logger

这是有效的,因为正如@Nico所提到的,模块被解释一次,并且每次从其他地方需要时都不会解释app.js