RequireJS是一个JavaScript文件和模块加载器。RequireJS包含三个重要的函数:require,define和requirejs。其中require和requirejs其实是同一个函数。
在RequireJS中有一个Map变量contexts,每一个context相当于命名空间或者包结构。定义的模块就保存在这些context中,这样就可以防止相同的模块名起冲突。
每一个context都有一个名字(contextName),RequireJS内置了一个默认的context,它的名字是"_",如果调用define之前没有配置contextName,那就是使用这个默认的context。
define( module_id /* optional */ , ["foo", "bar"] /* dependencies,optional */, function (foo, bar) {} )["foo","bar"]是module依赖的其他模块,当这两个模块加载之后,被传给function作为传入参数。function必须返回一个对象,否则不能作为module,因为module一定是一个拥有特殊功能,并且久经考验的对象。
require( ["foo", "bar"] , function(foo,bar) { foo.doSomething(); } )
require一般用来加载模块执行模块的功能。
模块被加载后,不是直接存储在window对象上,而是在require,requreJS等方法对象上的某个属性中,比如defined, registry等。
IE 6+ ..........compatible ✔
Firefox2+ ..... compatible ✔
Safari3.2+ .... compatible ✔
Chrome3+ ...... compatible ✔
Opera10+ ...... compatible ✔
module_id就是JavaScript文件的名字,通过baseUrl判断模块的位置之后,在head中创建script元素,修改src ,从而实现js模块的加载。
因为是新创建的script元素,浏览器并不会停止HTML页面渲染,因此,页面上的script比通过这种方式加载的JS代码先执行。
使用require之前,为了防止命名冲突,通常会有一个全局的命名空间,因此,模块文件的格式经常是:
namespace.module= (function(){return module;})();
使用require之后,模块文件的格式就变成类似下面的结构:
define("module_id", [depended modules], (function(depended modules){return module;})(); // 或者下面这种,下面这一种比较普遍,前一种一般只适合在具体项目中使用。如果属于比较公用的模块,应该使用这种方式: (function(root){return module;})(this);
也就是脱离了特定的命名空间的限制,模块真正的做到了独立。这样,不论是在哪个项目中,只要使用了requireJS就可以加载module,并随意命名。