如何模块化nodejs + expressjs代码

时间:2015-10-13 07:06:45

标签: node.js express

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

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 
    });

3 个答案:

答案 0 :(得分:7)

在主模块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;
EDIT1:

您可以将路由拆分为多个文件(在大型应用程序中可能有数百条路径)。如何制作它的策略很少,我展示了一个:

创建配置更多路线的新文件(例如routes / route1.js,routes / 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在评论中提出了一个问题:

  

但如果我连接到sql并在每个模块中使用查询,那么为什么我   需要在每个模块中添加mysql连接代码吗?

当我们将代码分成多个模块时,我们应该尝试尽可能少的依赖。但是每个模块中的多个连接或其他资源饥饿的任务可能是一个糟糕的选择。

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

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

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

1)在主模块中( server.js ):

app.set('someName',myCommonObjectInstance);

现在你可以做的路线:

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

2)在主模块( server.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);

答案 1 :(得分: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);
    });
});

答案 2 :(得分:0)

用于脚手架:https://expressjs.com/en/starter/generator.html

app.js将所有内容路由到一个定义文件的路径。

app.use('/api',require('./routes/api/allRoutes'));

allRoutes.js has all route definitions with controllers definitions

var roleCtrl=require('../master/role');
router.route('/role').post(roleCtrl.create);
router.route('/role/:roleId?').get(roleCtrl.retrieve);

我的role.js看起来像这样:

    const {ObjectId} = require('mongodb');

    module.exports =roleObj=
        {       
            collection: require(__basedir+'/config/config').clientName +'role',

            create: function (req, res) {

                var db = req.app.db;

                var role =
                    {
                        roleName: req.body.roleName,
                        documentStatus:req.body.documentStatus||null,          
                        auditTrail :[ {timeStamp:null , userID:null, userName:null , change:null } ]

                    };        
                db.collection(roleObj.collection).insertOne(role).then(function(result)
                {
                    var response={_id:result.insertedId, message:"inserted", success:true};
                    res.send(response);
                });

            },

            retrieve: function (req, res) {

                var db = req.app.db;

                var input = {};

                if (req.params.roleId != undefined)
                   input['_id'] = ObjectId(req.params.roleId);

                db.collection(roleObj.collection).find(input).toArray(function (err, result) 
                {

                    if (result.length != 0) res.send(result);

                    else res.send("empty");

                });          
            }
        }