支持CommonJS和AMD
有没有办法创build一个JavaScript微型库(一个没有依赖关系的库),支持以下所有模块格式:
- asynchronous模块定义
- CommonJS的
- 将库的导出作为全局名称空间对象公开(无加载器)
以下是各种交叉兼容模块格式的列表 。
我怀疑你正在寻找的是他们所说的“ commonjsStrict.js ”
是的,我对ded和他真棒模块的答案是:
(function(name, definition) { if (typeof module != 'undefined') module.exports = definition(); else if (typeof define == 'function' && typeof define.amd == 'object') define(definition); else this[name] = definition(); }('mod', function() { //This is the code you would normally have inside define() or add to module.exports return { sayHi: function(name) { console.log('Hi ' + name + '!'); } }; }));
这可以用于:
-
在AMD(例如requireJS)中:
requirejs(['mod'], function(mod) { mod.sayHi('Marc'); });
-
共同的(例如nodeJS):
var mod = require('./mod'); mod.sayHi('Marc');
-
全球(例如HTML):
<script src="mod.js"></script> <script>mod.sayHi('Marc');</script>
这个方法需要得到更多的宣传 – 如果jQuery和co。 开始使用它的生活会容易得多!
uRequire ,通用模块和资源转换器就是这样做的工具。
-
它主要将AMD和CommonJS转换为UMD / AMD / CommonJS / Plain脚本(不需要AMD加载器) 。
-
它允许模块的声明性导出,并带有一个
noConflict()
。 -
它可以在构build模块时操作模块(注入/replace/移除依赖关系或代码)。
-
它从coffeescript,cocoa,Livescript,icedCoffeescript转换,你可以添加自己的转换在一个衬里!
只是在@marc方面稍微更新一下这个答案,我也赞同ded,并更新了一下最新的更新:
(function (name, definition, context, dependencies) { if (typeof context['module'] !== 'undefined' && context['module']['exports']) { if (dependencies && context['require']) { for (var i = 0; i < dependencies.length; i++) context[dependencies[i]] = context['require'](dependencies[i]); } context['module']['exports'] = definition.apply(context); } else if (typeof context['define'] !== 'undefined' && context['define'] === 'function' && context['define']['amd']) { define(name, (dependencies || []), definition); } else { context[name] = definition(); } })('events', function () { // Insert code here return { sayHi: function(name) { console.log('Hi ' + name + '!'); } }; }, (this || {}));
最后的对象是对父对象或当前作用域的引用,可以说你有一个你正在编写的包,这只是一块饼,上下文可以是一个名称间隔的对象,这只是一个那块馅饼。
另外,如果你希望有依赖关系,那么在你的作用域支持一个数组后,最后有一个可选参数,在这种情况下,定义参数可以利用每个依赖关系作为参数。 另外,为了方便起见,在node-js平台中需要数组中列出的依赖项。
请参阅: https : //gist.github.com/Nijikokun/5192472一个真实的例子。
我已经解决了这个确切的问题,并设法轻松地支持:
- Dojo AMD(参考RequireJS规范)
- jQuery(在$ / jQuery.fn。[your_library_here]下)
- 使用香草的node.js需要('path_to.js')
- 浏览器窗口。[your_library_here]
它使用dependency injection和IIFE的组合来完成工作。
见下文:
/*global jQuery:false, window:false */ // # A method of loading a basic library in AMD, Node.JS require(), jQuery and Javascript's plain old window namespace. (function(exporterFunction) { exporterFunction('cll', function(a,b) { return a+b; } ); })( (function() { // Gets an exportFunction to normalize Node / Dojo / jQuery / window.* if ((typeof module != 'undefined') && (module.exports)) { // Node Module return function(library_name,what_was_exported) { module.exports = what_was_exported; return; }; } if (typeof define != 'undefined' && define.hasOwnProperty('amd') && define.amd) { // Dojo AMD return function(library_name,what_was_exported) { define(function() { return what_was_exported; }); }; } if (typeof jQuery === 'function') { // jQuery Plugin return function(library_name,source) { jQuery.fn[library_name] = source; return; }; } if (typeof window != 'undefined') { // Fall down to attaching to window... return function(library_name,what_was_exported) { window[library_name] = what_was_exported; }; } })(), (function() { // ## Other Parameters Here // You could add parameters to the wrapping function, to include extra // functionalilty which is dependant upon the environment... See // https://github.com/forbesmyester/me_map_reduce for ideas. return 'this_could_be_more_arguments_to_the_main_function'; })() );
这是基于Nijikokun的回答。 由于RequireJS不鼓励使用明确的模块名,所以在这个版本中已经省略了。 加载器的第二个参数描述依赖关系。 如果你不需要加载任何的话,传递[]
。
var loader = function(name, dependencies, definition) { if (typeof module === 'object' && module && module.exports) { dependencies = dependencies.map(require); module.exports = definition.apply(context, dependencies); } else if (typeof require === 'function') { define(dependencies, definition); } else { window[name] = definition(); } }; loader('app', ['jquery', 'moment'], function($, moment) { // do your thing return something; }