To address these issues, the competing module specs AMD and CommonJS have appeared on the scene, allowing developers to write their code in an agreed-upon sandboxed and modularized way, so as not to “pollute the ecosystem”.
Asynchronous Module Definition (AMD) has gained traction on the frontend, with RequireJS being the most popular implementation.
foo with a single dependency on
1 2 3 4 5 6 7 8
And a little more complicated example with multiple dependencies and multiple exposed methods:
1 2 3 4 5 6 7 8 9 10 11 12 13
The first part of the define is an array of dependencies, while the second part is essentially the callback function which is only executed when the dependencies are available (script loaders like RequireJS take care of that part, including figuring out where the files are located).
Note that the dependency to variable order is important (ex. jquery->
Also note that we can map the dependencies to any arbitrary variables we want here. If we change
$$ in the code above, all jQuery references within our function block will be
$$ instead of
And note, most importantly, that you can’t reference the variables
_ outside of the function, because it’s sandboxed from other code. That’s the goal here!
CommonJS is a style you may be familiar with if you’re written anything in Node (which uses a slight variant). It’s also been gaining traction on the frontend with Browserify.
Using the same format as before, here’s what our
foo module looks like in CommonJS:
1 2 3 4 5 6 7 8 9 10
And our more complicate example, with multiple dependencies and multiple exposed methods:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
UMD: Universal Module Definition
Since CommonJS and AMD styles have both been equally popular, it seems there’s yet no consensus. This has brought about the push for a “universal” pattern that supports both styles, which brings us to none other than the Universal Module Definition.
The pattern is admittedly ugly, but is both AMD and CommonJS compatible, as well as supporting the old-style “global” variable definition:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
And keeping in the same pattern as the above examples, the more complicated case with multiple dependencies and multiple exposed methods:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
(Sep 2014 edit: fixed syntax for CommonJS in the last example)