转载自http://blog.csdn.net/kevinwon1985/article/details/8155267javascript
RequireJS 把每个依赖项当作一个script标签,使用 head.appendChild()来加载。html
RequireJS 会计算好依赖关系,按照正确的顺序依次加载全部依赖项。而后才调用模块的构造函数。 java
在能同步加载模块的服务端JS中使用 RequireJS 也很容易,只须要重定义require.load()。能够用构建系统来作这个,服务端的 require.load 方法在build/jslib/requirePatch.js 中。jquery
将来,这个代码可能会被看成一个可选的模块放到 require/ 目录中。这样你就能够在基于主机环境来使用正确的加载模式。git
当咱们在顶层页面(或者没有定义一个模块的顶层脚本文件)中使用 require() ,可使用配置对象来进行配置:github
而且,你能够在require.js加载前定义一个全局的require对象,它会在require.js加载后自动应用于配置。下面的例子定义了一些依赖项,一旦require()方法调用,他们就会加载:api
注意: 最好这样写 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特性。