岁月如歌

用开放的心态,打造专业的人生。

SeaJS 中的 exports 和模块加载

with 2 comments

Honk Tang 和 army8735 的疑惑,写篇博客解释下。

exports

首先是 exports 的几种形式,我们可以:

define(function(require, exports, module) {
  exports.a = 'a';
  exports.fn = function() {};
});

也可以:

define(function(require, exports, module) {
  module.exports = {
    a: 'a',
    fn: function() {}
  };
});

这两者有什么区别呢?

  1. 就最终的效果而言,这两种形式没什么区别:都是使得该模块对外提供 xx 和 fn 两个公共成员。
  2. 就代码组织形式而言,exports.xx = ... 是分散赋值,中间可以穿插其他代码,很灵活。module.exports = { ... } 则是集中式赋值,便于管理。两种形式各有优劣,采用何种方式,很大程度上取决于个人喜好。
  3. 就内部实现而言,在传入参数时,exports = module.exports = {}, 很明显,第一种方式复用了 {} 初始值,第二种则给 module.exports 重新赋了一个新对象。由于 require('module-id') 返回的是 module.exports, 因此最终的效果两种形式是一致的。
  4. 更直观的一种形式是 exports = { ... }, 但由于 JavaScript 里只能传值,不能传引用,直接给 exports 赋值,外面无法获取到 exports 的新值,因此才有了退而求其次的 module.exports = { ... } 形式。

模块书写格式与模块加载器

在 seajs 里,“加载”一个模块可以有:

seajs.use('a', callback);
require('a');
module.load('a', callback);

首先,seajs.use 仅用来在页面中加载起始入口模块,这就如我们在 nodejs 里,运行模块的入口是:

node filename.js

seajs.use('a', callback) 就相当于 node filename.js, 仅起到 bootstrap 的作用。

在标准模块里,推荐永远不要出现 seajs. 就如 nodeJS 的模块里,不会出现 node 一样。标准模块的书写形式为:

define(function(require, exports, module) {
  // module code
});

这样做的好处,可以使得模块和具体加载器无关。比如 SeaJS 能加载的模块,理论上用 RequireJS 也可以跑起来,因为遵循的模块书写规范有很大交集。CommonJS 社区的一个目标就是使得各种环境下,都遵循统一的模块书写格式。这样,SeaJS, RequireJS, nodeJS 等都只是模块加载器,只要遵循的模块书写规范一致,模块就可以通用。

动态加载

define(function(require, exports, module) {
  var a = require('a');
  // ...
  module.load('b', function(b) {
    // ...
  });
  // ...
});

上面的代码,require('a') 对应的 a.js 模块在 require 执行前就已下载好,require('a') 仅执行 a.js 模块里 define 的 function 参数,以获取模块 a 的 exports. 这种方式是预先加载、按需执行。

module.load('b', callback) 是执行到此处时,才开始下载 b.js 模块。下载好后,回调 callback 函数。这种方式是动态延迟加载。

一般来说,require('a') 这种形式用于强依赖,缺了模块 a, 该模块功能就不全了。module.load 则用于加载可选模块,比如在某些特定条件下才需要的功能。

这两种方式各自的使用场景不同,得具体问题具体分析。

有心人可以发现:module.loadseajs.use 是很类似的。内部实现上也的确是公用一套逻辑,唯一不同的是,module.load('path/to/module') 是相对当前模块来定位,seajs.use 是相对当前页面。

总结

目前的 API 设计,已尽量简化,尽量简明易懂。大家有什么好的想法和改进建议,非常欢迎反馈。(建议通过邮件或博客回复给我反馈,文档下面的 DISQUS 很慢,经常漏掉,不可靠。)

Advertisements

Written by lifesinger

May 26, 2011 at 21:04

Posted in Articles

2 Responses

Subscribe to comments with RSS.

  1. 嗯,理顺了!
    thx 🙂

    honk

    May 27, 2011 at 11:10

  2. 好的,发现bug 马上反馈

    张扬扬

    May 27, 2011 at 13:09


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s