5

I use server.js as the main file in my nodejs-expressjs application. On the client side, I am using Angular JS for templating (not using JADE/EJS on the server side). I want to modularise this server.js file on the server as it may not be good if my application grows.

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

Suppose I want to add the following method in a separate file let's say test.js. How would I do that?

 app.post('/test', function (req, res) {
       //code 
    });
Benji
  • 45
  • 8
John
  • 478
  • 4
  • 12
  • 25

3 Answers3

9

In your main module server.js: remove :

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

and change to

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

create file router.js in same directory and add there:

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:

You can split your routes into multiple files (in big application there may be hundreds routes). There are few strategies how to make it, I show one:

Create new files where you config more routes (e.g. routes/route1.js, routes/route2.js): In router.js add:

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

In route1.js and route2.js create similar structure to router.js:

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

Edit2: OP asked a question in comment:

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?

When we split code into multiple modules we should try to have as little dependence as possible. But multiple connections in each module or other resource hungry tasks may be a poor choice.

We can share common resource instances in multiple modules. There is a large variety of ways how to accomplish this task.

I will show you just the basic ones (I will ignore globals pollution ):

Lets assume that we have object myCommonObjectInstance, and we need to pass it to multiple modules

1) in main module (server.js):

app.set('someName',myCommonObjectInstance);

Now in routes you can do:

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

2) in main module (server.js) lets create middleware which add new propery to req or res:

app.use(function(req,res,next){
  req.myCommonObjectInstance = myCommonObjectInstance;
  next();//very important!!!
});

and now in your route modules:

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

3)Third popular method is injection to module, check this post for more details: https://stackoverflow.com/a/9700884/4138339
In short you create module and export function with arguments. When you import function in your main module you pass arguments.

one of yours modules

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

In main module

require('./yourmodule')(myCommonObjectInstance);
Community
  • 1
  • 1
Krzysztof Sztompka
  • 7,066
  • 4
  • 33
  • 48
  • When I use app.use in main server.js file it throws TypeError: app.use() requires middleware functions – John Oct 13 '15 at 14:50
  • app.use must have require('yourroutemodule') as argument and yourroutemodule must have ```var express = require('express');``` ```var router = new express.Router();``` ```module.exports = router;``` your error means that you not pass module to your app.use – Krzysztof Sztompka Oct 13 '15 at 14:54
  • yeah that solved problem thanks, 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? cant I have common code in server.ja? – John Oct 13 '15 at 17:00
  • I edit answer and add answer for your comment question in ```Edit2``` section – Krzysztof Sztompka Oct 13 '15 at 17:59
0

I usually puts all my routes in separated files (for example users.js, workplaces.js etc) in a routes folder and then in my main file includes them by using the fs package and then

/**
 * 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);
    });
});
Slowmove
  • 462
  • 3
  • 7
0

Use this to for scaffolding: https://expressjs.com/en/starter/generator.html

app.js routes everything to one routes defining file.

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

My role.js looks like this:

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

                });          
            }
        }
anothernode
  • 5,100
  • 13
  • 43
  • 62