[英]How to make object references available in Node modules?
I have an Express.js web app. 我有一个Express.js网络应用程序。 In the main
app.js
file, I require()
a bunch of third party dependencies. 在主
app.js
文件中,我require()
一堆第三方依赖项。 Recently I've started extracting parts of my app.js
code into separate modules, eg 最近,我开始将
app.js
代码的一部分提取到单独的模块中,例如
// in app.js
var users = require('./modules/users');
// and then e.g.
// users.add(doc);
Inside my modules, I sometimes need to use objects that are available in my main app.js
file and I'm wondering what's the best way to pass references to those object to my modules. 在模块内部,有时我需要使用主
app.js
文件中可用的对象,并且我想知道将对这些对象的引用传递给模块的最佳方法是什么。
My current approach: 我目前的做法:
// in app.js
// pass needed object references in initialization step
users.init([db, logger]);
and 和
// in modules/users.js
var db, logger;
exports.init = function (deps) {
db = deps[0];
logger = deps[1];
};
Does this approach make sense? 这种方法有意义吗? Is there a better way to perform this?
有更好的方法来执行此操作吗?
Sure, just use modules! 当然,只需使用模块! :)
:)
// db.js
// create db instance here rather than in app.js
module.exports = db;
And 和
// logger.js
// create logger instance here rather than in app.js
module.exports = logger;
Then 然后
// app.js
var db = require('./db');
And 和
// lib/somewhere.js
var db = require('../db');
This way you're able to rely on the CommonJS dependency injection system rather than on doing the dependency injection all by yourself (passing references around instead of require
ing a module into yours). 这样,您就可以依靠CommonJS依赖项注入系统,而不是一个人自己进行依赖项注入(传递引用而不是
require
在您的模块中require
传递)。
The reason why this works as expected is that modules are only interpreted once, so if you instantiate everything once as opposed to using a factory function, it just works. 之所以能够按预期工作,是因为模块仅被解释一次,因此,如果您实例化所有内容一次而不是使用工厂函数,那么它就可以工作。
You should just be able to require
modules as normal: 你应该只能够
require
模块正常:
// users.js
var db = require('./db');
exports.init = function() {
// use db in here
};
However, sometimes this isn't possible and you will need to explicitly pass in the module. 但是,有时这是不可能的,您将需要显式传递模块。 One way to do it is to pass in dependencies when you
require
the module: 一种方法是在
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();
This is the pattern that I personally prefer, I think it's cleaner to pass dependencies into the require than into some init method like you have in your example. 这是我个人更喜欢的模式,我认为将依赖项传递到require中比将示例中的init方法传递给它更干净。
You'll see this done in ExpressJS code quite a lot, for example when we have all our routes in another file and need to pass our app
instance around: 您会在ExpressJS代码中看到很多这样的事情,例如,当我们将所有路由都放在另一个文件中并且需要传递我们的
app
实例时:
require('./routes')(app);
If you need something to be initialized specifically in app.js
rather than their own module you can export them from app.js
and then require app.js
: 如果您需要在
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 };
and then: 接着:
// users.js
var db = require("./app").db,
logger = require("./app").logger;
// use db and logger
This works because as @Nico mentioned, modules are interpreted once and app.js
will not be interpreted each time it is required from elsewhere. 之所以起作用,是因为正如@Nico所提到的,模块只被解释一次,而
app.js
不会在每次其他地方都需要时被解释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.