public
Last active

AMD-compatible CommonJS Module/1.1 that can also be loaded in a script tag

  • Download Gist
another-way.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
// This boilerplate would allow a module to run in node.js or an
// AMD-enabled browser environment. On node.js, the syntax is:
// var Color = require("./Color").Color,
// color = new Color("#BADA55");
// In the browser, the syntax is:
// var color = new Color("#BADA55"); // window.Color is implied
 
(function (define) {
 
define(function () {
 
function Color(){}
 
return Color;
 
});
 
}(
// if define is not available, assume we're running in node.js
this.define || (function (exports, moduleId) {
return function (defFunc) {
exports[moduleId] = defFunc();
}
})(this, 'Color')
));
dual.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
// This boilerplate would allow a module to run in node.js or an
// AMD-enabled browser environment. On node.js, the syntax is:
// var Color = require("./Color").Color,
// color = new Color("#BADA55");
// In the browser, the syntax is:
// var color = new Color("#BADA55"); // window.Color is implied
 
(function (define) {
 
define(["exports"], function (exports) {
 
exports.Color = function () {};
 
});
 
}(
// provide define if it's not available
this.define || (function (exports, moduleId) {
return function (ignoreMe, defFunc) {
defFunc(exports);
}
})(exports, 'myGlobalModule')
));
yet-another-way.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
// This boilerplate would allow a module to run in node.js or an
// AMD-enabled browser environment. On node.js, the syntax is:
// var Color = new require("./Color")("#BADA55");
// In the browser, the syntax is:
// var color = new Color("#BADA55"); // window.Color is implied
 
(function (define) {
 
define(function () {
 
function Color(){}
 
return Color;
 
});
 
}(
// if define is not available, assume we're running in node.js
this.define || (function (module, moduleId) {
return function (defFunc) {
module.exports = defFunc();
}
})(module, 'Color')
));

I realize this was a quick, off-the-cuff, gist, (and that I know little of modules) but must myGlobalModule be an object? My module returns a constructor (a function).

My preferred call signature is

// node
var Constructor = require('myGlobalModule');
var instance = new Constructor('args', 'go', 'here');

// browser
var instance = new myGlobalModule('args', 'go', 'here'); // since myGlobalModule is in the global namespace

I realize I could do exports.Constructor = TheConstructorFunction but that would mean calling it like new myGlobalModule.Constructor or something similarly long-winded.

Let me know if the desire isn't clear and I'll fork the gist to demonstrate.

AFAIK, until CommonJS Modules/2.0 (in draft, not implemented in node.js), an exports object must be an Object and not a function/constructor.

AMD supports any return type, but that doesn't help you, I know. :)

I doubt it's right, but I ended up going with https://gist.github.com/969908 which allows

// node
var Color = require('./module').Color;
var color = new Color('#BADA55');

// browser
var color = new Color('burlywood');

Which is Good Enough for now.

I'm looking into other modules to see how they are structured. I think I'd need to fake support for module.exports, right?

In any event, the above change will allow me to release the code and have people use it in the browser and the server.

Thanks for the help.

Now that I think I understand the goal, I updated my gist and added your version, which is a bit simpler (aka better).

According to this document, the exports free variable is also a property of the module free variable. So I added yet another way to do it. Note: I have not tested it. I just got this off of http://visionmedia.github.com/masteringnode/book.html

All of the above examples had some issue for me. Either I had to settle for the differing server/browser construction or I got ReferenceErrors (for exports) or something else.

However, I found https://github.com/kof/expose.js, included it at the top of my IIFE before my module definition and just added expose('ModuleName', ModuleDefinition); and everything works as I wanted.

I cannot verify that it is AMD compliant but as a developer who had a working "module" and wanted it to work the same way in the server and the browser, ideally without dictating any API design choices, this is ideal.

I've updated https://gist.github.com/969908 to include expose.js.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.