快递:如何将应用程序实例传递给来自不同文件的路线?

我想将我的路线分成不同的文件,其中一个文件包含所有路线,另一个文件包含相应的操作。 我目前有一个解决scheme来实现这一点,但是我需要使应用程序实例全局能够访问它的行动。 我目前的设置是这样的:

app.js:

var express = require('express'); var app = express.createServer(); var routes = require('./routes'); var controllers = require('./controllers'); routes.setup(app, controllers); app.listen(3000, function() { console.log('Application is listening on port 3000'); }); 

routes.js:

 exports.setup = function(app, controllers) { app.get('/', controllers.index); app.get('/posts', controllers.posts.index); app.get('/posts/:post', controllers.posts.show); // etc. }; 

控制器/ index.js:

 exports.posts = require('./posts'); exports.index = function(req, res) { // code }; 

控制器/ posts.js:

 exports.index = function(req, res) { // code }; exports.show = function(req, res) { // code }; 

但是,这个设置有一个大问题:我有一个数据库和一个应用程序实例,我需要传递给操作(controllers / *。js)。 我能想到的唯一select是将两个variables全局化,这不是一个真正的解决scheme。 我想从行动中分开路线,因为我有很多路线,并希望他们在一个中心位置。

将variables传递给动作的最好方法是什么,而将动作与路由分开?

Node.js支持循环依赖。
利用循环依赖而不是require('./ routes')(app)清理了很多代码,并且使得每个模块相对于它的加载文件更less相互依赖:


app.js

 var app = module.exports = express(); //now app.js can be required to bring app into any file //some app/middleware 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'); 

—– 04/2014更新—–
Express 4.0通过添加express.router()方法修复了用于定义路由的用例!
文档 – http://expressjs.com/4x/api.html#router

他们的新发电机的例子:
写下路线:
expressjs/generator/blob/master/templates/js/routes/index.html
添加/命名空间到应用程序: https : //github.com/expressjs/generator/blob/master/templates/js/app.js#L24

还有一些用于从其他资源访问应用程序的用例,所以循环依赖仍然是一个有效的解决scheme。

使用req.appreq.app.get('somekey')

通过调用express()创build的应用程序variables设置在请求和响应对象上。

参见: https : //github.com/visionmedia/express/blob/76147c78a15904d4e4e469095a29d1bec9775ab6/lib/express.js#L34-L35

就像我在评论中所说的,你可以使用一个函数作为module.exports。 函数也是一个对象,所以你不必改变你的语法。

app.js

 var controllers = require('./controllers')({app: app}); 

controllers.js

 module.exports = function(params) { return require('controllers/index')(params); } 

控制器/ index.js

 function controllers(params) { var app = params.app; controllers.posts = require('./posts'); controllers.index = function(req, res) { // code }; } module.exports = controllers; 

或者只是这样做:

 var app = req.app 

在您正在使用这些路线的中间件内部。 像那样:

 router.use( (req,res,next) => { app = req.app; next(); }); 

对于数据库分离的数据访问服务,将做所有的数据库工作与简单的API,并避免共享状态。

分离routes.setup看起来像开销。 我宁愿放置一个基于configuration的路由。 并用.json或注释configuration路由。

假设您有一个名为“contollers”的文件夹。

在你的app.js你可以把这个代码:

 console.log("Loading controllers...."); var controllers = {}; var controllers_path = process.cwd() + '/controllers' fs.readdirSync(controllers_path).forEach(function (file) { if (file.indexOf('.js') != -1) { controllers[file.split('.')[0]] = require(controllers_path + '/' + file) } }); console.log("Controllers loaded..............[ok]"); 

…和…

 router.get('/ping', controllers.ping.pinging); 

在你的控制器forlder你将有这个代码文件“ping.js”:

 exports.pinging = function(req, res, next){ console.log("ping ..."); } 

这就是它….