[英]Global Variable in app.js accessible in routes?
我如何在app.js
中设置变量并使其在所有路由中可用,至少在位于路由中的index.js
文件中可用。 使用 express 框架和node.js
使用 express 对象上可用的“set”和“get”方法实际上很容易做到这一点。
示例如下,假设您有一个名为 config 的变量,其中包含您希望在其他地方可用的配置相关内容:
在 app.js 中:
var config = require('./config');
app.configure(function() {
...
app.set('config', config);
...
}
在路由/index.js
exports.index = function(req, res){
var config = req.app.get('config');
// config is now available
...
}
要创建一个全局变量,只需在没有var
关键字的情况下声明它。 (一般来说,这不是最佳实践,但在某些情况下它可能很有用 - 请小心,因为它会使变量随处可用。)
这是来自visionmedia/screenshot-app的示例
文件app.js :
/**
* Module dependencies.
*/
var express = require('express')
, stylus = require('stylus')
, redis = require('redis')
, http = require('http');
app = express();
//... require() route files
文件路由/main.js
//we can now access 'app' without redeclaring it or passing it in...
/*
* GET home page.
*/
app.get('/', function(req, res, next){
res.render('index');
});
//...
一个巧妙的方法是使用 Express 本身提供的app.locals
。 这是文档。
// In app.js:
app.locals.variable_you_need = 42;
// In index.js
exports.route = function(req, res){
var variable_i_needed = req.app.locals.variable_you_need;
}
要声明一个全局变量,您需要使用全局对象。 像 global.yourVariableName。 但这不是真正的方法。 要在模块之间共享变量,请尝试使用注入样式,例如
someModule.js:
module.exports = function(injectedVariable) {
return {
somePublicMethod: function() {
},
anotherPublicMethod: function() {
},
};
};
应用程序.js
var someModule = require('./someModule')(someSharedVariable);
或者您可以使用代理对象来做到这一点。 像集线器。
someModule.js:
var hub = require('hub');
module.somePublicMethod = function() {
// We can use hub.db here
};
module.anotherPublicMethod = function() {
};
应用程序.js
var hub = require('hub');
hub.db = dbConnection;
var someModule = require('./someModule');
最简单的方法是尽早在 app.js 中声明一个全局变量:
global.mySpecialVariable = "something"
然后在任何路线中你都可以得到它:
console.log(mySpecialVariable)
这里有很好的解释,简而言之:
http://www.hacksparrow.com/global-variables-in-node-js.html
所以你正在使用一组 Node 模块,可能是一个像 Express.js 这样的框架,突然觉得需要让一些变量成为全局变量。 你如何在 Node.js 中使变量成为全局变量?
对此最常见的建议是“声明变量而不使用 var 关键字”或“将变量添加到全局对象”或“将变量添加到全局对象”。 你用哪一种?
首先,让我们分析一下全局对象。 打开终端,启动 Node REPL(提示)。
> global.name
undefined
> global.name = 'El Capitan'
> global.name
'El Capitan'
> GLOBAL.name
'El Capitan'
> delete global.name
true
> GLOBAL.name
undefined
> name = 'El Capitan'
'El Capitan'
> global.name
'El Capitan'
> GLOBAL.name
'El Capitan'
> var name = 'Sparrow'
undefined
> global.name
'Sparrow'
这是一个有用的问题,但通过提供实际的代码示例可能会更有用。 即使链接的文章实际上也没有显示实现。 因此,我谦虚地提出:
在app.js
文件中,文件顶部:
var express = require('express')
, http = require('http')
, path = require('path');
app = express(); //IMPORTANT! define the global app variable prior to requiring routes!
var routes = require('./routes');
app.js 不会有任何对app.get()
方法的引用。 将这些保留在各个路由文件中定义。
routes/index.js
:
require('./main');
require('./users');
最后,一个实际的路由文件, routes/main.js
:
function index (request, response) {
response.render('index', { title: 'Express' });
}
app.get('/',index); // <-- define the routes here now, thanks to the global app variable
我的首选方法是使用循环依赖*,该节点支持
var app = module.exports = express();
作为您的第一笔生意var app = require('./app')
来访问它 var express = require('express'); var app = module.exports = express(); //now app.js can be required to bring app into any file //some app/middleware, config, setup, etc, including app.use(app.router) require('./routes'); //module.exports must be defined before this line
var app = require('./app'); app.get('/', function(req, res, next) { res.render('index'); }); //require in some other route files...each of which requires app independently require('./user'); require('./blog');
正如其他人已经分享的那样, app.set('config', config)
非常适合这个。 我只是想添加一些我在现有答案中没有看到的非常重要的东西。 Node.js 实例在所有请求之间共享,因此虽然全局共享一些config
或router
对象可能非常实用,但全局存储运行时数据将在请求和用户之间可用。 考虑这个非常简单的例子:
var express = require('express');
var app = express();
app.get('/foo', function(req, res) {
app.set('message', "Welcome to foo!");
res.send(app.get('message'));
});
app.get('/bar', function(req, res) {
app.set('message', "Welcome to bar!");
// some long running async function
var foo = function() {
res.send(app.get('message'));
};
setTimeout(foo, 1000);
});
app.listen(3000);
如果您访问/bar
并且另一个请求命中/foo
,您的消息将是“欢迎使用 foo!”。 这是一个愚蠢的例子,但它明白了这一点。
这是很容易的事情,但人们的答案同时令人困惑和复杂。
让我向您展示如何在express
应用程序中设置全局变量。 因此,您可以根据需要从任何路线访问它。
假设您想从主/
路由中设置一个全局变量
router.get('/', (req, res, next) => {
req.app.locals.somethingNew = "Hi setting new global var";
});
所以你会从所有的路由中得到 req.app。 然后你必须使用locals
来设置全局数据。 如上所示,您已准备就绪。 现在我将向您展示如何使用这些数据
router.get('/register', (req, res, next) => {
console.log(req.app.locals.somethingNew);
});
像上面一样,您正在访问的register
路由中的数据已经设置得更早。
这就是你可以让这个东西工作的方法!
const app = require('express')();
app.set('globalvar', "xyz");
app.get('globalvar');
我使用了app.all
app.all() 方法可用于为特定路径前缀或任意匹配映射“全局”逻辑。
就我而言,我使用confit进行配置管理,
app.all('*', function (req, res, next) {
confit(basedir).create(function (err, config) {
if (err) {
throw new Error('Failed to load configuration ', err);
}
app.set('config', config);
next();
});
});
在路由中,您只需执行req.app.get('config').get('cookie');
我解决了同样的问题,但我不得不写更多的代码。 我创建了一个server.js
文件,它使用 express 来注册路由。 它公开了一个函数register
,其他模块可以使用它来注册自己的路由。 它还公开了一个函数startServer
,用于开始侦听端口
server.js
const express = require('express');
const app = express();
const register = (path,method,callback) => methodCalled(path, method, callback)
const methodCalled = (path, method, cb) => {
switch (method) {
case 'get':
app.get(path, (req, res) => cb(req, res))
break;
...
...
default:
console.log("there has been an error");
}
}
const startServer = (port) => app.listen(port, () => {console.log(`successfully started at ${port}`)})
module.exports = {
register,
startServer
}
在另一个模块中,使用此文件创建路由。
help.js
const app = require('../server');
const registerHelp = () => {
app.register('/help','get',(req, res) => {
res.send("This is the help section")
}),
app.register('/help','post',(req, res) => {
res.send("This is the help section")
})}
module.exports = {
registerHelp
}
在主文件中,引导两者。
app.js
require('./server').startServer(7000)
require('./web/help').registerHelp()
约翰戈登的答案是我尝试过的许多解释/记录在案的答案中的第一个,这些答案来自许多许多网站,但确实有效。 谢谢戈登先生。 抱歉,我没有足够的分数来为您的答案打勾。
我想补充一点,对于节点路由文件拆分的其他新手,将匿名函数用于“索引”是人们更经常看到的,因此使用约翰的 main.js 示例,功能上-通常会找到的等效代码是:
app.get('/',(req, res) {
res.render('index', { title: 'Express' });
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.