CommonJS Adaptor

The following is a lighweight self-contained (infrastructure-free) pattern for writing files that can be

  • used as ES3R, ES5, ES5/strict, or SES browser-side scripts, or
  • losslessly concatenated together into larger scripts.

In file example/foo.js:

  (function(require, exports) {
    "use strict";
    // ...
    exports.x = 21;
 
  }).apply({}, typeof require === 'function' ? [require, exports] :
                 [function(g){return function(id){return g['/'+id];};}(this),
                  this['/example/foo'] = {}]);

In file example/bar.js:

  (function(require, exports) {
    "use strict";
    var foo = require("example/foo");
    // ...
    exports.y = foo.x * 2;
 
  }).apply({}, typeof require === 'function' ? [require, exports] :
                 [function(g){return function(id){return g['/'+id];};}(this),
                  this['/example/bar'] = {}]);

In a CommonJS environment, require and exports would be defined and require would be a function, so the first branches of the ?:s above would be taken. In a browser-side environment, the above pattern assumes require wouldn’t be defined, so the second branches would be taken. In a CommonJS environment, loading example/bar.js would cause the loading of example/foo.js. In a browser-side environment, the page would still have to manually include these scripts in bottom-up order as usual – first foo and then bar. This works whether example/foo.js and example/bar.js are included as separate scripts or whether they are appended together. Fancier adapters like http://requirejs.org/ do more but need more setup. When the simple pattern above is adequate, it works without any prelude or infrastructure.

Everything above should work on old ES3 browsers. On ES5 browsers, each individual module is strict, without the strictness leaking when module sources are appended.

The main limitation for browser-side use is that the concatenation of “/” and a module id becomes a global variable name, and so potentially conflicts with other global variable names beginning with “/”.

Acks

The above pattern is MarkM’s adaptation of a pattern by Isaac Schlueter and Kris Kowal, based on yet earlier patterns proposed by Peter Michaux. (And others? Let me know and I’ll add.)

See

CommonJS modules (1.0)

Following CommonJS Secure Modules recommendations should result in compatibility with SES.

CommonJS ScriptModules More complete conventions for modules that can be run as browser-side scripts, but assuming some setup infrastructure.

http://requirejs.org/ Yet more complete support for browser-side use of CommonJS modules, requiring yet more setup.

es-discuss #011801 first posting of approximately this proposal.

 
conventions/commonjs_adaptor.txt · Last modified: 2010/09/15 21:02 by markm
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki