使用node.js模块,在什么情况下模块会被执行两次



我有一个模块,它封装了我的应用程序正在使用的Socket.io功能,看起来像这样:

// realtime.js
var io = require('socket.io'),
    sio;
exports.init = function(expressServer) {
    sio = io.listen(expressServer);
}
...

主app.js文件看起来像

// app.js
var rt = require('./realtime.js'),
    other = require('./other.js');
...
rt.init(expressServer);

另一个模块也使用rt.js

// other.js
var rt = require('./realtime.js');
...

我的问题是,other.js和app.js会有相同的rt.js实例吗?

与redis有关的SO的答案让我相信上述说法是正确的,但在这里的文件中,它说

多次调用require('fo')可能不会导致模块代码执行多次。这是一个重要的特点。有了它,可以返回"部分完成"对象,从而允许传递即使依赖关系会导致循环,也要加载它们。

这似乎意味着不能保证会是这样?

最后,这个问题似乎表明它取决于文件名,并且由于rt.js只有一个实例,所以不应该执行多次。如果是这种情况,它是只取决于rt.js是同一个文件,还是取决于require指定的路径。基本上,如果rt.js和other.js在lib/中,而app.js比other.js中的需求低一级,那么app.js会从不同的文件指向rt.js,这有关系吗?

如果有人能帮我澄清这个困惑,我将不胜感激!

模块目前只评估一次,但您不应该依赖于此。在模块中有任何状态都被认为是不好的做法。是什么阻止您将对sio的引用传递给其他.js?

//realtime
var io = require('socket.io'),
exports.init = function(expressServer) {
    return io.listen(expressServer);
}
// app.js
var rt = require('./realtime.js'),
    other = require('./other.js');
...
var sio = rt.init(expressServer);
// now ask other.js to use same sio instance
other.use_sio(sio);

请确保不要在多个地方安装socket.io。如果您在不同的模块中需要socket.io,其中每个模块都在从不同的路径搜索包,那么每个模块都将加载包的单独实例。

应用程序目录布局:

-module1
--/npm_modules //has socket.io
---/socket.io
--/module1.js //requires socket.io from module1/npm_modules
-module2
--/npm_modules //has another socket.io installation
---/socket.io
--/module2.js //requires socket.io from module2/npm_modules (Does not create a reference to what was required in module1.)

希望这能有所帮助。

最新更新