public
Last active

UMD-inspired Module Boilerplate

  • Download Gist
readme.md
Markdown

UMD-Inspired JS Module Boilerplate

This is the module format you don't know you need until you need it. Write your module once and have it work in a CJS/NodeJs, AMD, YUI (v3+), or Browser Global environment.

Best Used When...

  • You are migrating from namespaced (err, globals) code to either AMD or CJS modules or both.
  • You can't yet factor out browser globals but also need to test your code via NodeJS (e.g. Mocha).

Benefits & Trade-offs

  • A single module format allowing you to target AMD, CJS/NodeJS, and legacy browser globals like window.*.
  • Allows multiple dependencies to be defined.
  • Run unit tests via CLI/NodeJS runner (e.g. Mocha).
  • Less pain while incrementally migrating to CJS/NodeJS or AMD modules.
  • You give up the Java-like namespaces (e.g. com.company.package.module) -- meh, they are a mess anyway.
  • This (UMD) isn't a standard; to be fair, neither is AMD (it's a convention with a well-defined spec).
  • Non-trivial amount of boilerplate (and Ugly).

Inspiration

Further Reading for your edification

Loaders

umd-inspired-module.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
/**
* Creates a an "AppWidget" module that imports a "SingleDependency" constructor and exposes an "AppWidget" constructor.
*
* Allows you to access AppWidget as a CJS/AMD module (NodeJS or RequireJS):
*
* @example
* var AppWidget = require('app-widget')
*
* Allows you to access AppWidget as a YUI module:
* Inside your module, `use` (pun intended) `require` as if it is `Y` or even assign `require` to `Y`
*
* @example
* YUI().use('app-widget', function (Y) {});
*
* @todo figure out a clean way to communicate the `version` and `requires` for `YUI.add` via the definition.
*
* Allows you to access AppWidget as a legacy browser global:
*
* @example
* var AppWidget = window.AppWidget;
*/
 
!(function (name, context, definition) {
if (typeof exports == 'object') { module.exports = definition(require); } else if (typeof define == 'function' && define.amd) { define(definition); } else if (typeof YUI == "function") { YUI.add(name, definition, '@VERSION@', {requires: []}); } else { context[name] = definition(); }
}).call(this, 'AppWidget', this, function (require) {
'use strict';
 
// imports
var SingleDependency = (typeof require == 'function') ? require('./single-dependency') : window.SingleDependency;
var singleDependency = new SingleDependency();
 
function AppWidget() {}
AppWidget.prototype.start = function () {};
 
// exports
return AppWidget;
 
});

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.