CommonJS modules instead of globals

By | April 24, 2015

When you need a value or method to be available in various places in your app, the temptation to use a global variable can be hard to resist. You should resist! Besides, there is a good, and easy, alternative.

CommonJS modules are a standardized way to create an easily reusable object. These modules can provide factory (creator) functions or provide libraries of related functions. In this post, I will concentrate on their use as an alternative to global variables.

Quickly, the basics are:

  • CommonJS modules are JavaScript files, typically placed in the app/lib folder, that follow a simple set of rules.
  • They offer a separate namespace, so chances of variable naming collisions are reduced.
  • You use them in your app with a simple var foo = require('bar'); syntax.
  • Specifically in the Titanium environment, modules are cached. This mean that there’s minimal overhead in re-requiring them throughout your app.

See Appcelerator’s docs, or the many other references you’ll find in a quick Google search for further info about creating and using CommonJS modules.

Here’s a simple CommonJS module that provides persistent storage across instances:

var counter = 0; // our persistent value
exports.getCounter = function() {
 return counter;
};
exports.increment = function() {
 counter++;
}
exports.reset = function() {
 counter = 0;
}

Now, let’s use it. In one of your controllers, you’d add:

var count = require('counter');
console.log(count.getCounter()); // 0
count.increment();
console.log(count.getCounter()); // 1

No big deal there. But check this out. Let’s say you have the following in a different controller:

var cnt = require('counter');
// if the first controller has run, the value 
// of the following will be 1 not 0
console.log(cnt.getCounter());

There you go, no global variables and value preservation across controllers. I’ve used this technique to:

  • Create a singleton timer with methods to add functions to a stack that get run periodically. (The stack is the preserved value in this example.)
  • Store common style values in non-Alloy apps.
  • Create a messaging bus that can be used in place of app-level events for passing messages and data throughout the app.