在前天晚上 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 多行。

 

posted on 2018-01-04 13:35  Sharpest  阅读(117)  评论(0编辑  收藏  举报