How to structure a express.js application?

Javascriptnode.jsModularityExpress

Javascript Problem Overview


Is there a common convention for breaking up and modularizing the app.js file in an Express.js application? Or is it common to keep everything in a single file?

Javascript Solutions


Solution 1 - Javascript

I have mine broken up as follows:

~/app
|~controllers
| |-monkey.js
| |-zoo.js
|~models
| |-monkey.js
| |-zoo.js
|~views
| |~zoos
|   |-new.jade
|   |-_form.jade
|~test
|  |~controllers
|    |-zoo.js
|  |~models
|    |-zoo.js
|-index.js

I use Exports to return what's relevant. For instance, in the models I do:

module.exports = mongoose.model('PhoneNumber', PhoneNumberSchema);

and then if I need to create a phone number, it's as simple as:

var PhoneNumber = require('../models/phoneNumber');
var phoneNumber = new PhoneNumber();

if I need to use the schema, then PhoneNumber.schema

(which assumes that we are working from the routes folder and need to go 1 level up and then down to models)


EDIT 4

The express wiki has a list of frameworks built on top of it.

Of those, I think Twitter's matador is structured pretty well. We actually used a very similar approach to how they load up parts of the app.

derby.js also looks extremely interesting. It's akin to meteor without all of the hype and actually gives credit where credit is due (notably, node and express).


EDIT 3

If you are a fan of CoffeeScript (I am not) and reeeeaaaaaally want the L&F of Rails, there is also Tower.js.


EDIT 2

If you are familiar with Rails and don't mind the bleed-over of some concepts there is Locomotive. It is a light-weight framework built on Express. It has a very similar structure as RoR and carries over some of the more rudimentary concepts (such as routing).

It's worth checking out even if you don't plan to use it.


EDIT 1

nodejs-express-mongoose-demo is very similar to how I have mine structured. Check it out.

Solution 2 - Javascript

Warning: referencing code I hacked together for node knockout, it kind of works but is far from elegant or polished.

To be more specific about splitting up app.js I have the following app.js file

var express = require('express'),
    bootstrap = require('./init/bootstrap.js'),
    app = module.exports = express.createServer();

bootstrap(app);

This basically means I place all my bootstrapping in a seperate file, then I bootstrap the server.

So what does bootstrap do?

var configure = require("./app-configure.js"),
    less = require("./watch-less.js"),
    everyauth = require("./config-everyauth.js"),
    routes = require("./start-routes.js"),
    tools = require("buffertools"),
    nko = require("nko"),
    sessionStore = new (require("express").session.MemoryStore)()

module.exports = function(app) {
    everyauth(app);
    configure(app, sessionStore);
    less();
    routes(app, sessionStore);
    nko('/9Ehs3Dwu0bSByCS');


    app.listen(process.env.PORT);
    console.log("server listening on port xxxx");
};

Well it splits all the server initialization setup in nice chunks. Specifically

  • I have a chunk that sets up all my remote OAuth authentication using everyauth.
  • I have a chunk that configures my application (basically calling app.configure)
  • I have a little bit of code that punches less so it re-compiles any of my less into css at run time.
  • I have code that sets up all my routes
  • I call this small nko module
  • Finally I start the server by listening to a port.

Just for example let's look at the routing file

var fs = require("fs"),
    parseCookie = require('connect').utils.parseCookie;

module.exports = function(app, sessionStore) {
    var modelUrl = __dirname + "/../model/",
        models = fs.readdirSync(modelUrl),
        routeUrl = __dirname + "/../route/"
        routes = fs.readdirSync(routeUrl);

Here I load all my models and routes as arrays of files.

Disclaimer: readdirSync is only ok when called before you start the http server (before .listen). Calling synchronious blocking calls at server start time just makes the code more readable (it's basically a hack)

    var io = require("socket.io").listen(app);

    io.set("authorization", function(data, accept) {
        if (data.headers.cookie) {
            data.cookie = parseCookie(data.headers.cookie);

            data.sessionId = data.cookie['express.sid'];

            sessionStore.get(data.sessionId, function(err, session) {
                
                if (err) {
                    return accept(err.message, false);
                } else if (!(session && session.auth)) {
                    return accept("not authorized", false)
                }
                data.session = session;
                accept(null, true);
            });
        } else {
            return accept('No cookie', false);
        }
    });

Here I punch socket.io to actually use authorization rather then letting any tom and jack to talk to my socket.io server

    routes.forEach(function(file) {
        var route = require(routeUrl + file),
            model = require(modelUrl + file);

        route(app, model, io);
    });
};

Here I start my routes by passing the relevant model into each route object returned from the route file.

Basically the jist is you organize everything into nice little modules and then have some bootstrapping mechanism.

My other project (my blog) has an init file with a similar structure.

Disclaimer: the blog is broken and doesn't build, I'm working on it.

Solution 3 - Javascript

For maintainable routing organisation you can check out this article about the express-routescan node module and try it. This is the best solution for me.

Solution 4 - Javascript

I have my apps build on top of the express-generator tool. You can install it by running npm install express-generator -g and run it using express <APP_NAME>.

To give you a perspective, one of my smaller application's structure looked like this:

~/
|~bin
| |-www
|
|~config
| |-config.json
|
|~database
| |-database.js
|
|~middlewares
| |-authentication.js
| |-logger.js
|
|~models
| |-Bank.js
| |-User.js
|
|~routes
| |-index.js
| |-banks.js
| |-users.js
|
|~utilities
| |-fiat-converersion.js
|
|-app.js
|-package.json
|-package-lock.json

One cool thing I like about this structure I end up adopting for any express application I develop is the way the routes are organized. I did not like having to require each route files into the app.js and app.use() each route, especially as the file gets bigger. As such, I found it helpful to group and centralize all my app.use() on a ./routes/index.js file.

In the end, my app.js will look something like this:

...
const express = require('express');
const app = express();

...
require('./routes/index')(app);

and my ./routes/index.js will look something like this:

module.exports = (app) => {
  app.use('/users', require('./users'));
  app.use('/banks', require('./banks'));
};

I am able to simply require(./users) because I wrote the users route using express.Router() which allows me to "group" multiple routes and then export them at once, with the goal of making the application more modular.

This is an example of what you would fine on my ./routers/users.js route:


const router = require('express').Router();

router.post('/signup', async (req, res) => {
    // Signup code here
});

module.exports = router;

Hopefully this helped answer your question! Best of luck!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEric the RedView Question on Stackoverflow
Solution 1 - JavascriptChanceView Answer on Stackoverflow
Solution 2 - JavascriptRaynosView Answer on Stackoverflow
Solution 3 - JavascriptAlexander BykhovView Answer on Stackoverflow
Solution 4 - JavascriptJKleinneView Answer on Stackoverflow