Javascript Node.js多个express对象

Javascript Node.js多个express对象,javascript,node.js,express,global,router,Javascript,Node.js,Express,Global,Router,我一直在试图理解expressjsframeworkfornode.js是如何处理多个文件中的路由的。我的main index.js与此类似: var express = require('express'); var app = express(); app.use('/route', require('./api/route')); app.set('important_var', global_var); 在最后一行中,我为我的应用程序设置了一个全局变量,这是所有其他路由所需要的 在第二

我一直在试图理解expressjsframeworkfornode.js是如何处理多个文件中的路由的。我的main index.js与此类似:

var express = require('express');
var app = express();
app.use('/route', require('./api/route'));
app.set('important_var', global_var);
在最后一行中,我为我的应用程序设置了一个全局变量,这是所有其他路由所需要的

在第二个JS文件“./api/route.JS”中,我做了类似的事情:

var express = require('express');
var router = app.Router(); 
router.get('/path1', () => {...});

在第二个文件中,我需要在index.js的应用程序级别设置一个重要的_变量。我如何访问它?是否允许我使用express()创建新的(如果认为是新的)对象?index.js中的变量app是否被视为单例且不会重新创建?我应该如何处理此类情况?

要访问使用
app.set()
设置的值,您需要能够调用
app.get()
,并且它必须与调用
app.set()
时使用的
app
对象相同。每个
app
都是一个Express对象,它保持自己的状态

使用路由器创建路由处理程序时,您可以通过
req.app
访问与给定路由关联的
app
对象。因此,如果路由器中有代码,您可以访问
应用程序
对象上的内容,如下所示:

router.get('/path1', () => {
    let data = req.app.get('important_var');
    // rest of route handler here
});

更常见的做法是使用中间件并在
req
对象上设置自己的属性,然后所有路由处理程序都可以访问该属性:

const express = require('express');
const app = express();
// custom middleware
app.use(function(req, res, next) {
    req.myImportantVar = someCalculation(important_var);
    next();
});

app.use('/route', require('./api/route'));
然后,在路由器中,您可以执行以下操作:

const router = require('express').Router();
router.get('/path1', () => {
     console.log(req.myImportantVar);
     // rest of route handler here
});

如果我正确理解了您的问题,那么以下是您试图满足的要求:

  • 配置服务器的主文件
  • 主文件设置“全局”值,这些值可由应用程序内的各种路由访问
  • 可以访问全局值的子路由器文件
如果这些要求是正确的,那么以下是一种快速满足这些要求的方法

用于存储应用程序全局变量可能会导致问题,因为它用于分配应用程序设置值。相反,appglobals可以安全地存储到专门用于此用例的存储库中

因此,在主文件(
/index.js
)中:

然后,要访问子路由器文件(
/api/route.js
)中的应用程序全局,您需要使用对象,该对象是对
应用程序局部设置的引用:

const express = require('express');
const router = express.Router();

module.exports = router;

router.get('/path1', (req, res) => {
  console.log(req.app.locals.important_var);
  // ...
});

我不建议使用
req.set
,因为它可能与服务器设置冲突。正如我在回答中所指出的,使用
app.locals
更安全,并且是预期的用例,它通过请求对象被
req.app.locals
引用。还应将直接修改请求对象视为反模式,因为它可能与现有属性冲突。如果需要在中间件之间存储特定于请求的变量,这就是
req.locals
对象的用途。此外,在每个请求上设置一个常量是不必要的,因为您可以在启动时设置一个应用程序变量。@JasonCust-两者都可以工作
app.locals
也是一个很好的解决方案。
app.set()
的Express文档说:“您可以存储任何您想要的值”。当然,您不需要创建命名冲突。我只是在符号前面加上
,没有冲突。OP询问了
app.set()
app.get()
,因此我回答了他们如何使用它。我在另一个回答中写的评论与此相同。我是否可以在全局范围内访问它,也就是在路由器方法的回调函数之外?@SrdjanRistanovic-是的,如果您将
app
对象共享到模块中,那么您可以在模块中的任何位置调用
app.get()
,也可以直接共享变量。您可以在加载模块时通过创建模块构造函数将其传递到模块中,您可以在其中进行初始化。这与您将任何变量从父模块共享到父模块正在加载的模块的方式相同。我正在考虑在路由器文件的全局范围内使用该
important\u var
。我知道它在路由器中工作。get/post/put/。。。回调函数。但是有没有一种方法可以从这个范围之外访问全局变量?@SrdjanRistanovic不是一个Express应用程序全局,而是一个节点,它通常是JavaScript的反模式。在各种文件中使用常量的一种替代方法是使用充当常量对象的模块。它可以是一个普通的JSON文件:
const config=require('./constants')或显式为
const constants=require('./constants.json')和节点将自动为您解析它。
const express = require('express');
const router = express.Router();

module.exports = router;

router.get('/path1', (req, res) => {
  console.log(req.app.locals.important_var);
  // ...
});