One thing I find myself doing a lot in javascript files for node.js, or any other CommonJS-based system is typing module.exports quite a lot, or creating these obnoxiously large and repetitive module.exports declarations at the bottom of my files.

For example in a helper library for a Titanium mobile project, I had the following code snippet:

// ... // Platform detection helpers var osname = Ti.Platform.osname; var isiPhone = function() { return ('iphone' == osname); }; var isiPad = function() { return ('ipad' == osname); }; var isiOS = function() { return (isiPhone() || isiPad() || 'ios' == osname); }; var isAndroid = function() { return ('android' == osname); }; // ... (lots of other functions) ... module.exports = { // ... isiOS: isiOS, isiPhone: isiPhone, isiPad: isiPad, isAndroid: isAndroid, // ... }

This is a small sampling, but there were many, many other helpful functions in that file. You can probably imagine the number or times I had to type out all the variable names – twice! That seems like such a waste of typing. The other problem with this approach is that there is nothing visually signaling to me what is going to be a part of the public API, and what is private and internal. Everything is just a var , and I have to recall what I want exposed when doing the module.exports call at the end.

To avoid these issues, I could just prefix everything with module.exports directly, but that’s a lot of typing too – and doing that makes it cumbersome to use a function in another place in the same module file. Since there would be no local variable assigned, I would have to type the full module.exports.functionName() every time to call another function within my own module with this approach.

A Better Solution – Namespacing

The way I have come up with to solve this in my own code is to create a single empty object literal at the top of the file named ns (for namespace). I then create functions on the ns object as I go, and export all the properties on the ns object at the end of the file.

So in my original example, var isiPhone = ... becomes ns.isiPhone: ... – shedding a few keystrokes and gaining more clarity, because I know that everything in the ns object gets automatically exported at the end of the file:

var ns = {}; // ... // Platform detection helpers var osname = Ti.Platform.osname; ns.isiPhone = function() { return ('iphone' == osname); }; ns.isiPad = function() { return ('ipad' == osname); }; ns.isiOS = function() { return (ns.isiPhone() || ns.isiPad() || 'ios' == osname); }; ns.isAndroid = function() { return ('android' == osname); }; // ... // Export all the things! *\('o')| for(prop in ns) { if(ns.hasOwnProperty(prop)) { module.exports[prop] = ns[prop]; } }

You could argue that any saved keystrokes are negated with the module.exports loop at the bottom, but the real benefit is the added clarity – I now know that var osname is just a temporary placeholder for data, and will never be in the public API, and that all the functions following it will be. I don’t have to scroll to the bottom or go anywhere else – I know this immediately by looking at them, and re-using the public functions in ns.isiOS isn’t painful. Besides, I copy and paste the for loop anyways :).

UPDATE: You may wonder “why not just assign module.exports to ns , like this: module.exports = ns; ?” The reason is that using the hasOwnProperty method ensures that only properties you have explicitly added get exported. In this case, it may not make a difference since we’re using a bare object literal, but it’s good practice to use, so I do. Feel free to save a few lines of code with the assignment if you feel differently!

Categories: Programming, Technical