转载自http://blog.csdn.net/kevinwon1985/article/details/8155267
RequireJS 把每一个依赖项当做一个script标签,使用 head.appendChild()来加载。
RequireJS 会计算好依赖关系,按照正确的顺序依次加载所有依赖项。然后才调用模块的构造函数。
在能同步加载模块的服务端JS中使用 RequireJS 也很容易,只需要重定义require.load()。可以用构建系统来做这个,服务端的 require.load 方法在build/jslib/requirePatch.js 中。
未来,这个代码可能会被当作一个可选的模块放到 require/ 目录中。这样你就可以在基于主机环境来使用正确的加载模式。
当我们在顶层页面(或者没有定义一个模块的顶层脚本文件)中使用 require() ,可以使用配置对象来进行配置:
并且,你可以在require.js加载前定义一个全局的require对象,它会在require.js加载后自动应用于配置。下面的例子定义了一些依赖项,一旦require()方法调用,他们就会加载:
注意: 最好这样写 var require = {}
而不要这样写 window.require = {}
, 因为后者在IE下运行不正确。
支持的配置项:
baseUrl: 查找所有模块的根路径。所以,在上面第一个例子中,"my/module"的 script 标签 src="/another/path/my/module.js"。加载普通.js文件的时候, baseUrl 将不会起作用,script的src会直接使用 那些字符串,所以 a.js 和 b.js 会从HTML页面的同级目录中加载。
如果没有明确的配置 baseUrl ,它的默认值是会是加载require.js的HTML页面所在目录。如果使用 了data-main ,那么baseUrl会被设置成data-main指定的脚本所在目录。
baseUrl 可以与加载 RequireJS 的页面是不同域。 RequireJS 是可以加载跨域脚本的。 唯一的例外是,使用text! 插件加载的文本模块:这些路径必须与页面是在同一个域下,至少在开发的时候是这样的。当使用了 优化工具 后,跨域的文本模块会被打包进来,这时就加载跨域的文本模块了。
paths: 映射到不能直接在baseUrl下找到的模块名。 通常, path 设置的路径是相对于 baseUrl 的,除非 以 "/" 开头或包含URL协议 (例如" http:")。例如上例中,"some/module" 模块的最终生成的script标签的src="/another/path/some/v1.0/module.js"。 path的设置不要加.js后缀,因为path也可能是映射到一个目录。 如果path映射的是一个模块,RequireJS会自动加上.js后缀。
shim: 为那些没有使用 define() 声明依赖项、没有设置模块值、老的、传统的"浏览器全局"脚本配置依赖项和exports。例如 (RequireJS 2.1.0+):
requirejs.config({ shim: { 'backbone': { //These script dependencies should be loaded before loading //backbone.js deps: ['underscore', 'jquery'], //Once loaded, use the global 'Backbone' as the //module value. exports: 'Backbone' }, 'foo': { deps: ['bar'], exports: 'Foo', init: function (bar) { //Using a function allows you to call noConflict for //libraries that support it, and do other cleanup. //However, plugins for those libraries may still want //a global. "this" for the function will be the global //object. The dependencies will be passed in as //function arguments. If this function returns a value, //then that value is used as the module export value //instead of the object found via the 'exports' string. return this.Foo.noConflict(); } } } }); //Then, later in a separate file, call it 'MyModel.js', a module is //defined, specifying 'backbone' as a dependency. RequireJS will use //the shim config to properly load 'backbone' and give a local //reference to this module. The global Backbone will still exist on //the page too. define(['backbone'], function (Backbone) { return Backbone.Model.extend({}); });
在RequireJS 2.0.* 中, shim 中的"exports" 属性也可以配置成一个函数。这种情况, 它的功能和上面的 "init" 属性一样。 "init" 属性用于RequireJS 2.1.0+ 中,如此, exports配置的字符串值可用于 enforceDefine,也可用于类库加载后的一些功能性工作。
像 jQuery 或者 Backbone 插件这种不需要导出一个模块值的模块,可以用 shim 只配置一个表示依赖项的数组:
requirejs.config({
shim: {
'jquery.colorize': ['jquery'],
'jquery.scroll': ['jquery'],
'backbone.layoutmanager': ['backbone']
}
});
然而如果你想要在IE中检测404并执行fallbacks 或者errbacks,那么就必须配置 exports ,这样加载器才能检测脚本是否加载成功:
requirejs.config({ shim: { 'jquery.colorize': { deps: ['jquery'], exports: 'jQuery.fn.colorize' }, 'jquery.scroll': { deps: ['jquery'], exports: 'jQuery.fn.scroll' }, 'backbone.layoutmanager': { deps: ['backbone'] exports: 'Backbone.LayoutManager' } } });
关于"shim"配置项的重要注意事项:
优化工具配置中的 "shim" 的重要注意事项:
toplevel
为 true,或者在用命令行的时候不要使用参数-mt。
这些方法会破坏shim需要使用的全局变量名。map: 对于给定的相同的模块名,加载不同的模块,而不是加载相同的模块。
这种特性在某些大型项目是非常有用的。例如那种有两套不同的模块依赖两个不同版本的'foo'模块,并且这两套模块需要相互协作。
这时 使用context配置来支持多版本模块加载 是不行的。这种情况下, paths config 只能设置模块的根路径,而不是映射一个模块到另一个。
map 的例子:
requirejs.config({
map: {
'some/newmodule': {
'foo': 'foo1.2'
},
'some/oldmodule': {
'foo': 'foo1.0'
}
}
});
如果模块在硬盘上的结构是这样:
在'some/newmodule' 模块中 `require('foo')` 时,加载的是 foo1.2.js ,当 'some/oldmodule' 模块中 `require('foo')` 时,加载的是 foo1.0.js。
这个特性只在使用 define()包装的AMD模块时才有效,并且必须是匿名模块。
map的值也可以是"*",表示全匹配,即所有模块遵循这一设置。如果还有其他匹配项,将会比"*"的配置优先级高。例如:
requirejs.config({
map: {
'*': {
'foo': 'foo1.2'
},
'some/oldmodule': {
'foo': 'foo1.0'
}
}
});
在`require('foo')` 时,除了"some/oldmodule" 中会加载 "foo1.0", 其他模块都加载"foo1.2" 。
config: 传递一个配置信息到模块中是一个常见的需求。这个配置信息通常是应用的一部分,我们需要把它传递到模块中。 在 RequireJS 中,requirejs.config()中的config 配置项 就是为了解决这个需求。 模块中可以通过内置依赖模块"module" ,通过调用module.config()方法来获取传递进来的配置信息。例如:
requirejs.config({ config: { 'bar': { size: 'large' }, 'baz': { color: 'blue' } } }); //bar.js, which uses simplified CJS wrapping: //http://requirejs.org/docs/whyamd.html#sugar define(function (require, exports, module) { //Will be the value 'large' var size = module.config().size; }); //baz.js which uses a dependency array, //it asks for the special module ID, 'module': //https://github.com/jrburke/requirejs/wiki/Differences-between-the-simplified-CommonJS-wrapper-and-standard-AMD-define#wiki-magic define(['module'], function (module) { //Will be the value 'blue' var color = module.config().color; });
packages: 配置从CommonJS 包来加载模块。详见 packages topic。
waitSeconds: 放弃加载脚本前的等待的秒数。 设置为 0 则禁用此功能。默认是 7 秒。
context: 加载上下文配置(require.config的对象)的名字。 只要顶级 require调用指定一个唯一context字符串,require.js就可以在一个页面中加载多个版本的模块。要正确的使用它,参考 Multiversion Support 。
deps: 需要加载的依赖项的数组。当在require.js加载前使用全局 require对象来定义配置的时候很有用,也可以在require()一定义后就马上加载指定依赖项的时候用。
callback: 所有依赖项加载后执行的回调函数。 当在require.js加载前使用全局 require对象来定义配置的时候很有用,也可以用在require.config中。
enforceDefine: 如果设置为true, 当加载的脚本是没用define()包装过,且在shim配置中没有配置exports值时会抛错。 详见 Catching load failures in IE 。
xhtml: 如果设置为 true,requireJS 将使用document.createElementNS() 来创建script标签。
urlArgs:RequireJS 用来匹配资源的额外的 URL的查询参数 。通常的用法是在浏览器或者服务器配置不对的时候禁用缓存。例如:
urlArgs: "bust=" + (new Date()).getTime()
这在开发的时候很有用,但是在部署的时候最好删除它。
scriptType: 设置 RequireJS生成的 script 标签的 type属性值。默认是"text/javascript"。 可设置为"text/javascript;version=1.8" 来使用Firefox's JavaScript 1.8特性。