简体   繁体   English

如何使对象引用在Node模块中可用?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM