Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kevinconway/3087024 to your computer and use it in GitHub Desktop.
Save kevinconway/3087024 to your computer and use it in GitHub Desktop.
Universal JavaScript Module that supports AMD (RequireJS), Node.js, and the browser.

Universal JavaScript Module Pattern

A module pattern for nearly every occasion.

This gist is a fork of work by `millermedeiros <https://gist.github.com/1251668>`_ which is, in turn, a fork of work by `rpflorence <https://gist.github.com/1198466>`_.

What is it?

This is a module pattern for JavaScript modules that can be loaded in both Node.js and the browser. This module pattern will choose a method for loading dependencies based on the environment (require() vs window).

Example

(function (context, define) {
    "use strict";

    define.call(
        context,
        'ModuleName',
        [
            'dependency1',
            'dependency2/submodule'
        ],
        function (dependency1, dependency2) {

            // Return the module definition.
            return {};

        }
    );
}(...)

No AMD Support?

The previous versions of this pattern had direct support for AMD style modules. This, however, proved problematic because it would often require modifying the source of a module to adjust the paths for dependencies.

/*jslint node: true, indent: 4 */
(function (context, define) {
"use strict";
define.call(
context,
'module/submodule/subsubmodle',
[
'dependency1',
'dependency2'
],
function (dependency1, dependency2) {
// Return the module definition.
return {};
}
);
}(this, (function (context) {
"use strict";
// Ignoring the unused "name" in the Node.js definition function.
/*jslint unparam: true */
if (typeof require === "function" &&
module !== undefined &&
!!module.exports) {
// If this module is loaded in Node, require each of the
// dependencies and pass them along.
return function (name, deps, mod) {
var x,
dep_list = [];
for (x = 0; x < deps.length; x = x + 1) {
dep_list.push(require(deps[x]));
}
module.exports = mod.apply(context, dep_list);
};
}
/*jslint unparam: false */
if (context.window !== undefined) {
// If this module is being used in a browser environment first
// generate a list of dependencies, run the provided definition
// function with the list of dependencies, and insert the returned
// object into the global namespace using the provided module name.
return function (name, deps, mod) {
var namespaces = name.split('/'),
root = context,
dep_list = [],
current_scope,
current_dep,
i,
x;
for (i = 0; i < deps.length; i = i + 1) {
current_scope = root;
current_dep = deps[i].split('/');
for (x = 0; x < current_dep.length; x = x + 1) {
current_scope = current_scope[current_dep[x]] =
current_scope[current_dep[x]] || {};
}
dep_list.push(current_scope);
}
current_scope = root;
for (i = 1; i < namespaces.length; i = i + 1) {
current_scope = current_scope[namespaces[i - 1]] =
current_scope[namespaces[i - 1]] || {};
}
current_scope[namespaces[i - 1]] = mod.apply(context, dep_list);
};
}
throw new Error("Unrecognized environment.");
}(this))));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment