Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to modularize nodejs+expressjs code

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 
    });
like image 721
John Avatar asked Feb 08 '23 19:02

John


1 Answers

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);
like image 51
Krzysztof Sztompka Avatar answered Feb 12 '23 10:02

Krzysztof Sztompka