快递:如何将应用程序实例传递给来自不同文件的路线?
我想将我的路线分成不同的文件,其中一个文件包含所有路线,另一个文件包含相应的操作。 我目前有一个解决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.app
, req.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 ..."); }
这就是它….