2015-10-13 79 views
3

我已将server.js作为我的nodejs-expressjs应用程序中的主要文件。在客户端,我使用角度js模板(不使用服务器端的JADE/EJS)。我想在服务器上模块化这个server.js文件,因为如果我的应用程序增长,它可能不太好。如何模块化nodejs + expressjs代码

var express = require('express'); 
var app = express(); 
var fs = require("fs"); 

/** 
* Session 
*/ 
var session = require('express-session'); 
app.use(session({secret: '!23',resave: false,saveUninitialized:false})); 


var bodyParser = require('body-parser'); 
var mysql  = require('mysql'); 
var async  = require('async'); 

/** 
* Connect to MySQL 
*/ 
var config = require("./config"); 
var db = config.database; 
var connection = mysql.createPool(db); 

app.use(bodyParser.json()); 

// Create application/x-www-form-urlencoded parser 
var urlencodedParser = bodyParser.urlencoded({ extended: false }); 

/** 
* Provide web directory 
*/ 
app.use(express.static('public')); 


app.post('/abc', function (req, res) { 
    //code 
}); 
    app.post('/xyz', function (req, res) { 
    //code 
}); 
app.post('/test', function (req, res) { 
    //code 
}); 
var server = app.listen(config.port); 

假设我想在单独的文件中添加以下方法让我们说test.js。我会怎么做?

app.post('/test', function (req, res) { 
     //code 
    }); 

回答

4

在你的主模块server.js: 删除:

app.post('/abc', function (req, res) { 
    //code 
}); 
    app.post('/xyz', function (req, res) { 
    //code 
}); 
app.post('/test', function (req, res) { 
    //code 
}); 

,并切换到

app.use(require("./router")); 

创建在同一目录下的文件router.js,并添加有:

var express = require('express'); 
var router = new express.Router(); 
router.post('/abc', function (req, res) { 
    //code 
}); 
router.post('/xyz', function (req, res) { 
    //code 
}); 
router.post('/test', function (req, res) { 
    //code 
}); 
module.exports = router; 
编辑1:

您可以将您的路线分成多个文件(在大型应用程序中可能有数百条路线)。有一些策略如何使它,我展示一个:

创建新的文件,你的配置更多的途径(如路由/ route1.js,路线/ route2.js): 在router.js补充:

router.use(require("./routes/route1")); 
router.use(require("./routes/route2")); 

在route1.js和route2.js创建类似的结构router.js:

var express = require('express'); 
var router = new express.Router(); 
//place for routes 
module.exports = router; 

EDIT2:OP问在评论一个问题:

but if i connect to sql and use queries in every module then why do i need to add mysql connection code in every module?

当我们将代码拆分为多个模块时,我们应尽可能少地依赖。但是,每个模块中的多个连接或其他资源匮乏的任务可能是一个糟糕的选择。

我们可以在多个模块中共享公共资源实例。如何完成这项任务有很多种方法。

我会告诉你仅仅是基本的那些(我会忽略全局污染):

让我们假设我们有对象myCommonObjectInstance,我们需要将它传递给主模块中的多个模块

1) (server.js):

app.set('someName',myCommonObjectInstance); 

现在的路线,你可以这样做:

router.post('/test', function (req, res) { 
    var myCommonObjectInstance = req.app.get('someName'); 
    //other code 
}); 

2)主模块(服务器。JS),让我们创建中间件其中添加新的属性格式来REQ或RES:

app.use(function(req,res,next){ 
    req.myCommonObjectInstance = myCommonObjectInstance; 
    next();//very important!!! 
}); 
在你的路线模块

现在:

router.post('/test', function (req, res) { 
    var myCommonObjectInstance = req.myCommonObjectInstance; 
    //other code 
}); 

3)第三流行的方法是注射模块,检查这个职位更多详细信息:https://stackoverflow.com/a/9700884/4138339
总之,您可以使用参数创建模块和导出函数。当你在主模块中导入函数时,你传递参数。

你的一个模块

module.exports = function (myCommonObjectInstance) { 
//your code and you have access to myCommonObjectInstance 
}; 

在主模块

require('./yourmodule')(myCommonObjectInstance); 
+0

当我在主server.js文件中使用app.use它抛出s TypeError:app.use()需要中间件函数 – John

+0

app.use必须具有require('yourroutemodule')作为参数,而yourroutemodule必须具有'''var express = require('express');'''var router = new express.Router();''' '''module.exports = router;'''你的错误意味着你不能将模块传递给你的app.use –

+0

是的,解决了问题谢谢,但如果我连接到SQL和在每个模块中使用查询,那么为什么我需要在每个模块中添加mysql连接代码?不能我在server.ja有共同的代码? – John

0

我通常把我的所有路由在分离的文件(例如users.js,workplaces.js等)在一个路线夹然后在我的主文件包含他们通过使用FS包,然后

/** 
* Register Routes Folder For Including New Routes 
*/ 
fs.readdir('./routes', function(err, files){ 
    files.forEach(function(fn) { 
     if(!/\.js$/.test(fn)) return; 
     require('routes/' + fn)(app, io); 
    }); 
});