从Node.js模块中调用app.js的函数?

4

假设我有以下的app.js文件(显然是非常简化的):

var express = require('express'),
    app = express.createServer();

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

// some random function
var foo = function() {
    return 'bar';
};

// another random function
var foo2 = function() {
    return 'bar2';
};

然后我有路由模块:

module.exports = function(app){
    app.get('/some/route', function(req, res){
        var fooBar = foo(),
            fooBar2 = foo2();

        res.end(fooBar + fooBar2);
    });
};

显然这样做是不行的,因为foo和foo2在模块内部没有定义。有没有什么方法可以让这个工作,或者至少有不同的模式可以更好地完成这个任务?

1个回答

7

你可以将这两个函数放在一个对象中,并在routes.js的初始化中传递它们。

var express = require('express'),
    app = express.createServer();

// some random function
var foo = function() {
    return 'bar';
};

// another random function
var foo2 = function() {
    return 'bar2';
};

var fns = {foo : foo, foo2: foo2}

// include routes
require('./lib/routes')(app, fns);

在路由中:

module.exports = function(app, fns){
    app.get('/some/route', function(req, res){
        var fooBar = fns.foo(),
            fooBar2 = fns.foo2();

        res.end(fooBar + fooBar2);
    });
};

这是我会做的方式。你也可以将它们包含在应用程序对象中。除了在init函数中传递它们之外,你还可以导出这两个函数并在routes.js中要求它们。

var express = require('express'),
    app = express.createServer();

// some random function
var foo = function() {
    return 'bar';
};

// another random function
var foo2 = function() {
    return 'bar2';
};

module.exports = {foo : foo, foo2: foo2}

// include routes
require('./lib/routes')(app, fns);

在路由中:

module.exports = function(app){
    var fns = require('../app.js');
    app.get('/some/route', function(req, res){
        var fooBar = fns.foo(),
            fooBar2 = fns.foo2();

        res.end(fooBar + fooBar2);
    });
};

我不喜欢这个想法,因为它会导致循环依赖。对此没有好感。

2
原始问题和这个被接受的答案都暗示了module.exports是一个被调用的函数,但实际上它是一个包含函数的对象。此外,问题和答案都在定义的闭合括号后面加了一个")"。例如:module.exports = function(app){..}) - 首先,这样永远不会执行。其次,应该像这样写:module.exports.myfunc = function(args) {...} 或者 module.exports = { myfunc1 : function(){...}, myfunc2: function(){...} }。好吧,这是一个老问题,但为了新手的缘故,需要澄清一下。 - unsynchronized
闭合括号是一个错误。module.exports 可以设置为一个函数。它被非正式地称为 substack 模式。看一下。 - Farid Nouri Neshat
我意识到它可以被设置为任何你喜欢的东西,包括一个随机数。这完全取决于你是否想遵循标准,或者只是胡乱尝试,不在乎是否有人想使用你的代码。你甚至可以完全不使用模块。整个重点是要遵循一种约定。如果你打算这样做,一个可接受的方法是导出一个名为substack的对象或函数,它可以执行任何你想要的操作。 - unsynchronized
1
作为一个实验,尝试一下这个命令:"console.log(module);" 看看它输出了什么。它的exports是一个空的{},这是标准的做法。你可以继续往里面添加内容,而不是用函数/数字/字符串/日期对象来替换它。如果你需要导出其他东西,把它们放在exports对象里面即可。这就是它被设计成如何使用的。 - unsynchronized
实际上,当您只想导出一个函数时,就会使用这种方法。在某些情况下,我看到人们将属性添加到函数中(function main() {...};main.minorThing = function () {...}; module.exports = main)。这是一种非常常见的模式。Node.js assert 模块也像我上面描述的那样导出了一个主函数。查看 npm 注册表的第一页,在顶部模块中,request、express、socket.io 和 mkdirp 都使用了这种模式。 - Farid Nouri Neshat
我明白了。这似乎是一种奇怪的定义标准的方式,然后又打破了它。 - unsynchronized

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接