可以在路由中访问app.js中的全局variables?
如何在app.js
设置一个variables,并使其在所有路由中都可用,至less在位于路由中的index.js
文件中。 使用express框架和node.js
要创build一个全局variables,只需声明它没有var
关键字。 (一般来说,这不是最佳实践,但在某些情况下,它可能是有用的 – 只要小心,因为它会使variables在任何地方都可用。)
这里是来自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
文件path/ 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'); }); //...
实际上使用expression对象上的“set”和“get”方法很容易。
示例如下,假设你有一个名为config的variables,你的configuration相关的东西,你想在其他地方可用:
在app.js中:
var config = require('./config'); app.configure(function() { ... app.set('config', config); ... }
在routes / index.js中
exports.index = function(req, res){ var config = req.app.get('config'); // config is now available ... }
要声明一个全局variables,你需要使用全局对象。 像global.yourVariableName。 但这不是一个真正的方法。 要共享模块之间的variables尝试使用注入样式
someModule.js:
module.exports = function(injectedVariable) { return { somePublicMethod: function() { }, anotherPublicMethod: function() { }, }; };
app.js
var someModule = require('./someModule')(someSharedVariable);
或者你可以使用代理对象来做到这一点。 像中心一样。
someModule.js:
var hub = require('hub'); module.somePublicMethod = function() { // We can use hub.db here }; module.anotherPublicMethod = function() { };
app.js
var hub = require('hub'); hub.db = dbConnection; var someModule = require('./someModule');
一个简单的方法是使用app.locals
提供的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; }
这里解释得很好,简而言之:
http://www.hacksparrow.com/global-variables-in-node-js.html
所以你正在使用一组Node模块,也许像Express.js这样的框架,并且突然觉得需要在全局中做一些variables。 你如何使variables在Node.js全局?
最常见的build议是“声明不带var关键字的variables”或“将variables添加到全局对象”或“将variables添加到GLOBAL对象”。 你用哪一个?
首先,我们来分析一下全局对象。 打开一个terminal,启动一个节点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
我的首选方法是使用循环依赖*,哪个节点支持
- 在app.js中定义
var app = module.exports = express();
作为您的第一个业务秩序 - 现在任何需要的模块都可以
var app = require('./app')
来访问它
app.js
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
路线/ index.js
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实例是在所有请求之间共享的,所以尽pipe全局共享某个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
,你的消息将是“Welcome to foo!”。 这是一个愚蠢的例子,但是它可以说明问题的关键。
为什么不同的node.js会话共享variables? 。
John Gordon的回答是我尝试的数十个半解释/logging答案中的第一个,来自许多许多网站,实际上它们都有效。 谢谢戈登先生。 对不起,我没有要点你的答案。
对于node-route-file-splitting的其他新手,我想补充一点,那就是“index”的匿名函数的使用是人们经常看到的,所以以John的main.js为例,通常会发现的等效代码是:
app.get('/',(req, res) { res.render('index', { title: 'Express' }); });
我用app.all
app.all()方法对于映射特定path前缀或任意匹配的“全局”逻辑非常有用。
就我而言,我使用confit进行configurationpipe理,
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');
我解决了同样的问题,但我不得不编写更多的代码。 我创build了一个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 }
在另一个模块中,使用这个文件来创build一个路由。
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 }
在主文件中,bootstrap都是。
app.js require('./server').startServer(7000) require('./web/help').registerHelp()