可以在路由中访问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全局共享某个configrouter对象可能是非常实用的,但全局存储运行时数据将在请求和用户之间可用 。 考虑这个非常简单的例子:

 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()