我正在尝试创建映射其自己的路线的 Node 模块。我在下面提供了一个简化的示例(删除了返回的对象中映射的所有其他函数以及任何代码以简化示例)。
我最初的尝试是这样做:
文件:web-core.js
function initRoutes(app) {
var express = require('express');
var router = express.Router();
router.get("/basic", function(request, response) {
response.json({ success: true, path: '/auth/basic' });
});
router.get("/oauth2", function(request, response) {
response.json({ success: false, path: '/auth/oauth2' });
});
router.get("/openid", function(request, response) {
response.json({ success: false, path: '/auth/openid' });
});
app.use('/auth', router); // mount the module
}
function init(app) {
initRoutes(app); //-- This does work (but don't like it)
//initRoutes(require('express')()); //-- This does NOT work!
}
module.exports = (function() {
return {
init : init
};
}());
从我的 Node 入口点:
var express = require('express');
var app = express();
app.use(express.static('public'));
var webAuth = require("./web-auth.js");
webAuth.init(app); //-- Wish I didn't have to call this!
var listener = app.listen(process.env.PORT, function () {
console.log('Your app is listening on port ' + listener.address().port);
});
现在,我的主要目标是不必调用 webAuth.init(app)
(并间接使用 initRoutes(require('express')());
反而)。我希望模块不依赖于显式或外部初始化。
但由于某种原因,当我使用 initRoutes(require('express')());
时,它不起作用。它似乎只有在我调用 webAuth.init(app)
并传入 app
对象时才有效。
我不确定我在这里错过了什么。有人告诉我,Node 将缓存 require('express')
返回的所有实例,因此从技术上讲,两种方法应该是相同的并且工作方式相同。
我在网上看到的所有 express.Router()
示例都提供了简单的用例,而不是像我试图做的那样“模块化”。
有人知道为什么它不起作用吗?
更新:2018年2月04日18:27
为了让任何人都能理解,我创建了一个包含示例代码的 Glitch 项目,可以在 here 找到该项目。 .
似乎总是存在这样那样的问题。要么缺乏文档,要么一些神秘的“东西”不起作用。
因此,根据提供的答案,我决定从外部初始化,例如:
var webAuth = require("./web-auth.js");
webAuth.init(app, router);
在我的模块中,我现在有:
function init(app, router) {
console.log("### Initializing '" + MODULE_NAME + "' module for '" + BASE_PATH + "'");
initFilters(router);
initRoutes(app, router);
}
这个效果很好。当我调用 GET/auth/basic
时,我的过滤器和 /auth/*
路由均按预期工作。
但是现在,我开始创建第二个特定于域的模块,因此我们会说 API 应该映射到 /domain/*
。显然,第二个模块现在应该使用 express()
和 express.Router()
的新实例,不是吗?否则重复使用相同的就没有任何意义。
所以当我这样称呼时:
app = express();
router = express.Router();
var webDOMAIN= require("./web-domain.js");
webDOMAIN.init(app, router);
您希望该模块也可以在 /domain/*
路径上工作...但事实并非如此!该死,使用 NodeJS 和 ExpressJS 真是令人沮丧。在我 30 多年的经验中,我对这两种技术的体验似乎比其他任何技术都更令人沮丧。
更新:2018年2月06日10:59
好吧,我终于明白了!!!我不会将所有内容都发布在这里,而是对我自己的问题写一个广泛的答案。
最佳答案
可能同时有多个 Express 应用。因此,您需要找到合适的应用程序来分配路线。由于应用程序无法进行猜测,因此您需要告诉函数使用哪一个。
如@yue you提到,调用 require("express")()
创建一个新的express 实例。这意味着,您必须在某个时间点传递正确的实例。
我的建议是删除该初始化函数,因为它实际上不是构造函数。您可以将初始化部分移至导出函数中,以便代码的工作方式就像快速初始化程序一样。这样,您还可以归档您想要的模块化。
web-auth.js
function init(app) {
initRoutes(app);
}
module.exports = function(app) {
return init(app);
};
然后在您的代码中使用它,如下所示:
require("./web-auth.js")(app);
关于node.js - 除非作为参数传入,否则无法添加快速路线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48612351/