Skip to content

Instantly share code, notes, and snippets.

@wilmoore
Last active February 11, 2024 22:32
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save wilmoore/3880415 to your computer and use it in GitHub Desktop.
Save wilmoore/3880415 to your computer and use it in GitHub Desktop.
UMD-inspired Module Boilerplate

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

/**
* 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;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment