-
-
Save millermedeiros/1251668 to your computer and use it in GitHub Desktop.
(function(def){ | |
def('myModule', ['someDependency', 'somethingElse'], function(someDependency, somethingElse){ | |
//return the module's API | |
return {}; | |
}); | |
}( | |
// wrapper to run code everywhere | |
typeof define === 'function' && define.amd? | |
//AMD | |
function(name, deps, factory){ | |
define(deps, factory); //registering as an unnamed module, more flexible and match CommonJS | |
} : | |
(typeof require === 'function' && typeof module !== 'undefined' && module.exports ? | |
//CommonJS | |
function(deps, factory){ | |
module.exports = factory.apply(this, deps.map(require)); | |
} : | |
//Browser (regular script tag) | |
function(name, deps, factory){ | |
var d, i = 0, global = this, old = global[name], mod; | |
while(d = deps[i]){ | |
deps[i++] = this[d]; | |
} | |
global[name] = mod = factory.apply(global, deps); | |
mod.noConflict = function(){ | |
global[name] = old; | |
return mod; | |
}; | |
} | |
) | |
)); |
// AMD | |
require(['myModule'], function (myModule){ | |
// use myModule here | |
}); | |
// Node.js | |
var myModule = require('myModule'); | |
// Global | |
myModule | |
// if myModule is already defined, `noConflict` gives it back | |
var myNonConflictingModule = myModule.noConflict(); |
I've been using a simplified version of this pattern: https://github.com/millermedeiros/crossroads.js/blob/master/dev/src/wrapper.js - specially since I don't think that noConflict()
is that important (unless you use a very common name like $
- which is a very bad idea BTW..) and also because I don't "trust" the automatic dependency conversion for globals..
line 10 should be typeof define === 'undefined'
no? Actually, typeof define == 'function' && define.amd
is the only way to truly detect AMD. require
is not standardized (nor should it be, imho).
I'm with you: "embrace AMD and be happy", but ppl can embrace CommonJS and be happy, too. :)
line 10 should be typeof define === 'undefined' && typeof require === 'undefined'
(AMD have define
and CommonJS have require
).. in fact the logic should be the opposite check for define first (and use AMD), than check for require
and module.exports
than fallback to browser..
the code above makes a lot of assumptions like checking for require
when it is only using define
for AMD, check for exports
when it uses module.exports
... I was only worried about making it work with RequireJS/Node.js and being concise.. even checking for module.exports
we can't be sure that it is really what we expect it to be, define.amd
is a "safe" check, will start using it from now on..
I only recommend using a wrapper like this if it is a library that you are going to distribute and have no idea how people may want to use it, I like this simple wrapper way better:
(function(def){
def(['someDependency', 'foo/bar/somethingElse'], function(someDependency, somethingElse){
//return the module's API
return {};
});
}(
typeof define === 'function' && define.amd?
//AMD
function(name, deps, factory){
define(deps, factory);
} :
//CommonJS
function(deps, factory){
module.exports = factory.apply(this, deps.map(require));
}
));
who uses globals anyways? :P
I like how your boilerplate is on the bottom and the module definition at the top.
imho even define && define.amd
is safe enough. Doesn't hurt to do the additional check though.
in case someone reaches this gist, I just published a new post explaining why AMD rocks: http://blog.millermedeiros.com/2011/09/amd-is-better-for-the-web-than-commonjs-modules/
if the dependencies are on the "same level" (not on a nested path) it is easy to map names to globals, if not it would need some code to convert the path names into global dependencies, a naive example:
the same thing would happen to register a global module that is on a nested path, like:
If the dependency is on a relative path it would be even harder..
If you really need the code to run on all environments and it has dependencies I suggest doing the dependency management for globals manually, so you can control the name of the modules and how they should map, if a module depends on jQuery for instance the AMD convention is to use
jquery
as the dependency name, while the global is calledjQuery
...don't use globals anymore, embrace AMD and be happy :D