我有一个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];
};
这种方法有意义吗?有没有更好的方法来执行此操作?
答案 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
。