How to organize large Node.js projects

What are some good ways to organize large Node.js projects?

For example, an app making use of both express.js and socket.io? This would include both application logical structure as well as filesystem.

Currently, I'm finding myself shoving a ton of code into a single master js file and placing code into a giant global object, and it feels naughty.


Solution 1:

A Beginners Example

I like the originally checked from @david-ellis and you should study it in depth to understand it as it is a good one. However, I would have liked it more simplified for the beginners wanting to see a straight forward example. Here's what I would have liked to have seen someone show me.

Let's give a typical scenario where you are using express and you have a lot of routes listed on your app.js file. Its contents would look something like this:

app.js

// ... startup code omitted above

app.get('/', function(req, res) {
  res.render('index', { title : 'home' });
});
app.get('/contactus', function(req, res) {
  res.render('contactus', { title : 'contact us' });
});
app.get('/anotherpage', function(req, res) {
  res.render('anotherpage', { title : 'another page' });
});
// and so on...

You can imagine if you have 50 routes, this file can get quite out of hand. It would be nice to remove some of this clutter out of the app.js file.

What you would do is create a "controllers" folder in your app so your structure would now look like this:

app.js
/controllers

Create a file within "/controllers" named "index.js" then put the following code.

/controllers/index.js

module.exports.set = function(app) {
   // copy your routes listed in your app.js directly into here
}

Cut and paste your route listings from your "app.js" file and place them into the "/controllers/index.js" file.

On your app.js file, remove your routes and in place of them do the following.

app.js

// remove your routes and replace with this code
var controllers = require('./controllers');
controllers.set(app);

Now if you wanted to have your "/controllers/index.js" file also be split up, let's add one more example so you can see how Node.js really acts like a Russian Doll in how its code can be organized.

Within "/controllers" add one more file "accounts.js" and place the following within it.

/controllers/account.js

module.exports.set = function(app) {
    // put more app route listings here
}

Now within your "/controllers/index.js file, put a reference to "account.js"

/controllers/index.js

var account = require('./account.js');

module.exports.set = function(app) {
   // your routes here

   // let "account.js" set other routes
   account.set(app);
}

As you can imagine, you can keep breaking things up into smaller and smaller parts and put more folders within folders and reference with "require" if you like. You can use the same concept for "/lib" or library files. "node_modules" is already doing this.

That is just one of many reasons node.js is very enjoyable to program with.

Manageable Express 4 Routing example

Here's another post I responded to about express 4 routes that relates to this.

Rest with Express.js nested router

Solution 2:

I wrote a blog post about this very subject a few days ago, and although the article is in French, I set up a GitHub repo (in English) to show a working example of the structure I use.

Obviously, there is no definitive answer to this question, but it's interesting to see what others are doing, and I am all ears for other opinions on the subject (which was also discussed here, where you can see a summary of what I suggest).

Solution 3:

Similar to the other blog post, I wrote one specifically about organizing Express applications. It's the method I've been using for about a year and a half. Basically, organize your applications around your data entities or any other core elements. Place logic for each of those elements in their own directories. I tried to borrow a lot from Python.

http://rycole.com/2013/01/28/organizing-nodejs-express.html

Solution 4:

His Articles are no longer online, but Eric Satterwhite's node series recommended a structure as listed below.

# Project 
. 
|-- packages/
|   |-- project-core
|   |   |-- lib/
|   |   |-- commands/
|   |   |-- startup/
|   |   |-- conf/
|   |   |-- test/
|   |   |-- package.json
|   |   |-- README.md
|   |   |-- events.js
|   |   |-- .npmignore
|   |   `-- index.js
|-- package.json
`-- index.js

With the packages/ folder turning into your source for modularity.