node.js - 除非作为参数传入,否则无法添加快速路线

标签 node.js express

我正在尝试创建映射其自己的路线的 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/

相关文章:

javascript - TypeScript 是否为 NodeJS 模块访问提供了明确的公共(public) API?

javascript - 一次发送多个嵌入内容

node.js - 如何用 Jest 模拟函数 .save() sequelize

node.js - 我们可以同时使用 NGINX 和 PM2 进行 node.js 生产部署吗?

node.js - Firebase 函数 : Upload Error: HTTP Error: 400, 未知错误

javascript - 如何访问这个 Javascript mysql 错误对象 (Nodejs)?

node.js - 如何从嵌套的 promise 中返回值?

node.js - 在更新中执行 $set 和 $rename

node.js - 如何在 Node-Express/Vue Web 应用程序中管理 OAuth?

javascript - Express4 在 POST 请求中返回错误