Introduction

Javascript has evolved over the past 18 years from a little scripting language designed to add simple interactivity to web pages - to a full blown language capable of powering web servers, desktop applications, online games, and even running parallel “pseudo-thread’s” via workers.

As javascript evolved so did the complexities of serving and maintaining the ever growing number of dependencies, frameworks and libraries used to power our modern javascript applications. Luckily for us there were some early pioneers and trailblazers that helped to pave the road ahead and come up with design patterns and best practices for us. There are many design patterns used in Javascript and I would recommend taking a look at Javascript Patterns by Stoyan Stefanov for a full introduction to the most widely used patterns. Of the design patterns available, the Module pattern has gotten the most recognition in the past few years thanks in part to the maturation of the module pattern via commonjs as well as the wild success of node.js.

The Module Pattern

In a nutshell the module pattern allows you to create code that can expose a public API while safe guarding private variables and methods behind a pseudo blackbox.

Let’s look at an example taken from the world of 2d video games.

var SpriteFactory = (function () { "use strict"; var index = 0, sprites = {}, Sprite = function (config) { return { index: index++, x: config.x || 0, y: config.y || 0, width: config.width || 0, height: config.height || 0, background: config.background || '#fff' }; }; return { generateSprite: function (config) { config = config || {}; var s = new Sprite(config); sprites['sprite_' + s.index] = s; }, deleteSprite: function (index) { var sprite = this.getSprite(index); if (sprite) { sprite = null; } }, getSprite: function (index) { if (sprites.hasOwnProperty('sprite_' + index)) { return sprites['sprite_' + index]; } } }; }()); SpriteFactory.generateSprite({}); SpriteFactory.generateSprite({ x: 90, y: 20 }); theSprite = SpriteFactory.getSprite(1);

Code Breakdown

The SpriteFactory example is interesting because it showcases some of javascript’s more powerful features. For those of you not familiar with Javascript variables and functions, here is the down and dirty. Javascript variables are either global or local depending on the scope from which they were defined. If a function defines variables within it (like index and sprites above) then those variables have local scope within that function and within all top-level functions returned from that function (see the return block in SpriteFactory). When a function returns a function or an Object Literal defining functions, then those functions have private knowledge of any variables declared within the local scope of their wrapping function - which is known as a Javascript Closure.

In the SpriteFactory example we take full advantage of the power of closures to enable our module to define a private class for Sprite that only has scope from within SpriteFactory. We also keep track of a single counting variable so we can track Sprite instances within the SpriteFactory.

The power of modules in Javascript

Javascript modules enable you, as the developer, to build large javascript applications that can be easily broken down and distilled into individual de-coupled components. This is not only useful for you as an individual, but this approach also makes it easier for large teams to work together.

Module evolution with Asynchronous Module Definition* (AMD)

The main goal of AMD is to define a javascript module and handle its dependency coordination and resolution.(http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition). This is the logical next step to what we looked at above because it enables us to break up our code using the Single Responsibility Principle (http://en.wikipedia.org/wiki/Single_responsibility_principle) which states that every class should only have one responsibility.

On the Browser, javascript files are loaded via script tags (either added to the payload of the html, or dynamically added on the client-side). The AMD spec describes the define, require and exports methods If you’ve worked with (http://nodejs.org/)[Node.js] before then these verbs should already be familiar to you. But for those of you who have no idea what I’m talking about, here is an example that extends our earlier SpriteFactory.

// sprite.js define(["sprite"], function (sprite) { exports.Sprite = function (config, id) { return { index: id, x: config.x || 0, y: config.y || 0, width: config.width || 0, height: config.height || 0, background: config.background || '#fff' }; }; });

// sprite-factory.js define("sprite-factory", ["require", "exports", "sprite"], function (require, exports, sprite) { var index = 0, sprites = {}; exports.SpriteFactory = { generateSprite: function (config) { config = config || {}; var s = new sprite(config, index+=1); sprites['sprite_' + s.index] = s; }, deleteSprite: function (index) {}, getSprite: function (index) {} }; });

Now we have broken out the Sprite class into it’s own module, and we now include sprite as a dependency of SpriteFactory. This makes it easier to improve the functionality of the SpriteFactory over time.

I can’t talk about AMD without mentioning Require.js (http://requirejs.org). Require.js has made a name for itself as one of the defacto standards for doing client side AMD. I would recommend reading through their “Why AMD” (http://requirejs.org/docs/whyamd.html).

The Future of Javascript Modules

One of the issues with Commonjs modules is that the concepts employed to generate these module are more of a javascript hack than an actual javascript standard. Now that we are on the advent of ECMAscript 6, there is finally a real proposal for adding modules to the javascript standard (http://wiki.ecmascript.org/doku.php?id=harmony:modules). I am actually a big fan of the ECMAscript proposal for javascript modules because it actually defines keywords to use in the javascript language for writing modules. Additionally, you can also define your modules inline or import them using the new import declaration.

// sprite.js inline module "sprite" { export default function(config, id) { return { index: id, x: config.x || 0, y: config.y || 0, width: config.width || 0, height: config.height || 0, background: config.background || '#fff' }; }

What I like about this definition is that it reads nicely when you look at the code. In my experience the easier it is to read and follow code, the easier it is to maintain that code, and with the new module capabilities in ECMAscript 6 we can reduce the overhead of making javascript modules.

Importing those modules

I want to cover another fantastic addition to the ECMAscript 6 module proposal, and that is the use of import If you are familiar with the python syntax for importing modules eg. “*from math import sqrt* then this will be really neat. We will piggyback and reuse the inline sprite module (let’s just pretend it was available as an external resource).

import "sprite"; // fetches "sprite" at compile time let Sprite = System.get("sprite"); // evaluates Sprite at runtime

You can also statically link a module. This means that you can link an imported module directly to a global variable in the javascript vm.

import sprite from "sprite"

I am not going to cover the new module loader API in this post but it is worth taking a read through the specification (http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders) since importing modules and defining modules go hand in hand with loading them into the Javascript runtime.

The future looks bright

We’ve looked at the basic Module pattern and seen how to use it to create some really powerful Javascript. We then took a look at how AMD works and how we could easily change our code to build our modules following the Commonjs specification for asynchronous modules, lastly we took a look at the bleeding edge harmony modules specification. I find that it is easy to see the beauty of where ECMAscript 6 is heading, with respect to modules, when you take a look back at where we’ve already been and how we’ve evolved up to this point.

References

http://www.yuiblog.com/blog/2007/06/12/module-pattern/

http://briancray.com/posts/javascript-module-pattern

http://www.codeproject.com/Articles/625262/Getting-Started-with-the-RequireJS-Library

http://requirejs.org/docs/whyamd.html#amd

Future of Javascript Modules with ECMA Script 6

http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders

http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html

http://dailyjs.com/2010/10/18/modules/

http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition