Skip to content

Instantly share code, notes, and snippets.

@unscriptable
Created May 12, 2011 20:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save unscriptable/969416 to your computer and use it in GitHub Desktop.
Save unscriptable/969416 to your computer and use it in GitHub Desktop.
AMD-compatible CommonJS Module/1.1 that can also be loaded in a script tag
// 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')
));
// 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')
));
// 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')
));
@jfsiii
Copy link

jfsiii commented May 12, 2011

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.

@unscriptable
Copy link
Author

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. :)

@jfsiii
Copy link

jfsiii commented May 13, 2011

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.

@unscriptable
Copy link
Author

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

@unscriptable
Copy link
Author

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

@jfsiii
Copy link

jfsiii commented May 14, 2011

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment