在前天晚上 RequireJS 发布了一个大版本,直接从 version1.0.8 升级到了 2.0。
随后的几 小时 James Burke 又迅速的将版本调整为 2.0.1,
当然其配套的打包压缩工具 r.js 也同时升级 到了 2.0.1。
此次变化较大,代码也进行了重构,层次更清晰可读。功能上主要变化如下:
1,延迟模块的执行。
这是一个很大变化, 以前模块加载后 factory 立马执行。
性能上肯定有一些损耗。 2.0 修改实现, 再没人诟病 AMD 的模块是立即执行的。现在也可以等到 require 的时候才执行。
2 , config 增 加 了 shim , map , module , enforceDefine。
shim 参数解决了使用非 AMD 方式定义的模块(如 jQuery 插件)及其载入顺序。
使用 shim 参数来取代 1.0 版本的 order 插件。
其实在 1.0 版本中就曾经有人开发过 use 和 wrap 插件来 解决此类问题。
考虑到很多开发者有此类需求(比如某些 JS 模块是较早时候其他人开发的,非 AMD 方式)
此次 2.0 版本直接将其内置其中。 下面是一个使用 jQuery 插件形式配置的参数。
我们知道 jQuery 插件本质上是将命名空间挂在 全局的 jQuery 或 jQuery.fn 上而非使用 define 定义的模块。
而 jQuery 插件都依赖于 jQuery, 即在 require 插件时得保证 jQuery 先下载下来。
可以如下配置
require.config({
shim: { 'jquery-slide': ['jquery'] }
});
require(['jquery-slide']);
这时会保证先下载 jquery.js,然后再下载 jquery-slide.js。
map 参数用来解决同一个模块的不同版本问题,
这一灵感来自于 Dojo 的 packageMap。
有这 样的场景:开发初期使用了的 jquery-1.6.4,后期升级到了 1.7.2。
但担心有些依赖 jquery-1.6.4 的代码升级到 1.7.2 后有问题。
因此保守的让这部分代码继续使用 1.6.4 版本。
这时 map 参数将派上用场。 假如 A,B 模块中使用了 jquery-1.6.4.js,C,D 模块中使用了 jquery-1.7.2.js。如下
1 requirejs.config( 2 {map: {'A': {'jquery': 'jquery-1.6.4'}, 3 'B': {'jquery': 'jquery-1.7.2'}} 4 }); 5 require(['A']); // download jquery-1.6.4.js require(['B']); // download jquery-1.7.2.js
这时 require(['A'])将会下载 jquery-1.6.4.js,require(['B'])会下载 jquery-1.7.2.js。
模 块“A”如果写成“*”则表示除了 B 模块使用 jquery-1.7.2 之外其它模块都使用 jquery-1.6.4 。
map 参数解决了模块的各个版本问题,很好的向下兼容了老代码。
config 参数用来给指定的模块传递一些有用的数据。如下
require.config({
config: {
'A': { info: {name: 'jack'}
} }
});
使用 A 的模块中可以通过 A.config().info 获取到该数据信息。如
require(['A'], function(A) {
var info = a.config().info;
console.log(info);
});
enforceDefine 用来强制模块使用 define 定义, 默认为 false。
如 underscore 不再支持 AMD 后,其代码移除了 define。此时如果仍然使用 requirejs 来载入它,它就是普通的 js 文件了。 此时如果 enforceDefine 设为 true,虽然 underscore.js 能下载但 requirejs 会报错。如
require.config({ enforceDefine: true });
require(['underscore'], function(_){
console.log(_)
});
,require 函数增加了第三个参数 errbacks。
很明显该函数指模块文件没有载入成功时的回调。 这个也是应一些开发者得要求而增加,
其中还 包括另一个著名 AMD 的实现 curl 的作者 John Hann。
require(['b'], function(){ console.log('success'); },
function(err){ console.log(err) }
);
err 会给出一些出错提示信息。
5,更强大的 paths 参数。
requirejs 1.x 版本中已经有 paths 参数,
用来映射模块别名。
requirejs2.0 更加强大,可以 配置为一个数组,顺序映射。
当前面的路径没有成功载入时可接着使用后面的路径。如下
1 requirejs.config({ 2 enforceDefine: true, 3 paths: { 4 jquery: [ 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min', 'lib/jquery' ] 5 } }); 6 require(['jquery'], function ($) { });
当 google cdn 上的 jquery.min.js 没有获取时(假如 google 宕机),可以使用本地的 lib/jquery.js。
6,在模块载入失败回调中可以使用 undef 函数移除模块 的注册。
这个灵感来自 dojo AMD loader,RequireJS 取名 undef。如下
1 require(['jquery'], function ($) { 2 //Do 3 // something 4 //with $ here 5 }, function (err) { 6 var failedId = err.requireModules && err.requireModules[0]; 7 if (failedId === 'jquery') { 8 requirejs.undef(failedId); 9 } 10 });
7,删除了 jQuery domready 相关代码。
这次没人再诟病 RequireJS 和 jQuery 耦合的太紧密。
8 , 删 除 了
priority , packagePaths ,
catchError.define。
这几个参数已经有相应的替代品。
最后需要注意的是,虽然功能增加了不少。但代码量却减少了近 60 行。主要是去掉了 jQuery ready 相关代码。另外 newContext 函数依然有 1000 多行。