DailyJS

Programming Styles in the Node Community

Alex R. Young

Subscribe

@dailyjs

Facebook

Google+

language style node

Programming Styles in the Node Community

Posted by Alex R. Young on .
Featured

language style node

Programming Styles in the Node Community

Posted by Alex R. Young on .

Programming style is where opinion and reason collide, often leading to endless arguments with no clear winner. The real secret to style is to be consistent, and respect other people: if you're working on a project by another author, then follow their style. Some companies and open source projects may have their own in-house style guide, but it's generally fairly easy to pick up the style of a project after browsing the source for long enough.

Why do I bring this up? Well, the Node community has several dominant styles, each with their own advantages. If you're starting your own Node projects then you might like to use the style of a well-known developer for guidance of inspiration.

TJ Holowaychuk

TJ Holowaychuk, author of Express, Jade, Stylus, and Mocha, has an extremely consistent style. TJ uses two spaces for indentation, semicolons to end lines, and formats commas at the start of a new line:

var connect = require('connect')  
  , Router = require('./router')
  , methods = Router.methods.concat('del', 'all')
  , middleware = require('./middleware')
  , View = require('./view');

This practice is becoming more common in JavaScript, and the arguments for and against it vary. Isaac Z. Schlueter created a gist on the subject at gist.github.com/357981 which grew into a heated debate that currently has 64 comments (since April 2010). It's worth noting that TJ also carries this over to his JSON formatting, and generally only uses one var statement at the top of each new scope.

One of TJ's more subtle stylistic habits is to remove the space before the opening brace of a method:

exports.parseQuality = function(str){  
  // ...
};

When writing a function, however, he'll usually retain the space:

function quality(str) {  
  var parts = str.split(/ *; */)
    , val = parts[0];

  var q = parts[1]
    ? parseFloat(parts[1].split(/ *= */)[1])
    : 1;

  return { value: val, quality: q };
}

Notice that the ternary operator is split across new lines as well, which can make longer expressions more readable.

TJ also uses double quotes sparingly as well. Most strings are written using single quotes.

TJ's Luna project isn't related to JavaScript, but during development he made an interesting point: he likes the "machine-like" look of JavaScript's operators. Some languages provide and instead (or as well as) &&, but TJ prefers the way operators like && read:

Personally I'm not a fan of "wordy" operators, aka or and for || &&, etc, though again they can look ok within reason, but I find the "machine-like" look of operators provide a nice visual separation.

I think the "visual separation" comment is interesting, because I find semicolons in JavaScript also provide visual separation, although other people may find this noisy.

 Isaac Z. Schlueter

Isaac Z. Schlueter, author of npm (where would we be without it?) is outspoken about style and language "magic". I enjoyed reading his post Experts, Idiots, and Taste, and JavaScript is Not Web Assembly is related to this. Isaac doesn't like language "magic". He's pragmatic and keeps things simple. Let's take a look at his coding style.

Like TJ, Isaac uses leading commas and two space indentation, and usually groups variables under one var. Functions are spaced out like this: function help (args, cb) {.

The biggest difference between TJ and Isaac is semicolons. Isaac doesn't use them to end lines unless necessary:

function checkGit (folder, cb) {  
  // if it's a git repo then don't touch it!
  fs.lstat(folder, function (er, s) {
    if (er || !s.isDirectory()) return cb()
    else checkGit_(folder, cb)
  })
}

Isaac has written a detailed explanation of this decision in An Open Letter to JavaScript Leaders Regarding Semicolons. He makes good points as to why semicolons can be left out, although admits that this style may only be slightly superior.

Ryan Dahl

Ryan Dahl, creator of Node, has a slightly different style yet again. Like TJ and Isaac, he uses two spaces for indentation. Conversely, he'll use multiple var statements per-line:

var express = require('express');  
var socketio = require('socket.io');  
var bench = require('./bench');  

This is from d3bench, a small benchmarking app. He writes functions and methods with a single space: io.sockets.on('connection', function(socket) {. He doesn't line up colons in object literals:

var r = bench.run({  
  url: "http://localhost:8000/buffer/12345",
  concurrency: 10,
  requests: 50000
});

Deeper Style Choices

Indentation, semicolons, and other formatting topics are one side to coding style. Another is the choice of language features. Both TJ and Isaac use exceptions sparingly. Isaac is outspoken about exceptions:

I have settled in the last few years on the sentiment that try/catch is a mistake, and an anti-pattern.

This is from try/catch/throw on the Node Google Group.

TJ sometimes organises code into folders, with an index.js file, so a group of modules can be loaded with one require. Router in Express is an example of this. This technique removes a barrier from splitting up code into multiple files. Both authors also make heavy use of other Node modules, rather than reinventing their own solutions to common problems. The npm package.json is a good example of this.

Conclusion

Before starting a new project, it's worth researching the programming styles used in the community of your chosen language and framework. Encourage the rest of your team to be consistent, even if they're freelancers or contractors who have their own styles. The best comment I've read on how important it is to respect a project's style is by Isaac:

In your own house, you get to decide the styles and customs. But be aware that it might have an effect on who feels comfortable at your parties.

Yes, it's all FUD, in reply to Actual drawbacks to omitting semi-colons?.

References: