岁月如歌

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

SeaJS 和 RequireJS 的异同

with 26 comments

相同点是:要解决的问题相同,都是浏览器端的模块化开发,目标一致。

不同点有不少:

1. 遵循的规范不同

RequireJS 遵循的是 Modules/AMD 规范。

SeaJS 遵循的是 Mdoules/Wrappings 规范的 define 形式。

AMD 规范在 CommonJS 社区争议很大,规范里太多 RequireJS 的影子。社区里不少人反感 RequireJS 打着 CommonJS 的口号,甚至建议 AMD 自立门户,比如最近的这篇讨论:Split off AMD?

从这两个规范本身来说,Modules/Wrappings 规范更简洁优雅,不信的话,你读读它们各自的描述就清楚。

2. factory 的执行时机不同

在 RequireJS 里,模块有多种书写格式,推荐的是:

define(["./a", "./b"], function(a, b) {
  a.doSomething();
  b.doSomething();
});

在 SeaJS 里,模块只有一种书写格式:

define(function(require, exports, module) {
  require("./a").doSomething();
  require("./b").doSomething();
});

SeaJS 的模块书写格式,RequireJS 也支持。为了便于讨论,我们称呼 define 方法中的 function 参数为模块的 factory. 无论是在 RequireJS 还是 SeaJS 里,在执行 factory 之前,都会确保依赖的模块已经下载好:

/* a.js */
define(factory);

/* b.js */
define(factory);

/* c.js */
define(['./a', './b'], factory);

每个模块都有自己的 factory. 在 AMD 的书写格式下,上面例子中,模块 c 的 factory 在执行时,会接收 a 和 b 两个参数。这意味着,c 依赖的所有模块,都是在一开始就得执行好,即便有可能不需要执行,比如:

define(function(require) {
   // BEGIN
  if(some_condition) {
    require('./a').doSomething();
  } else {
    require('./b').soSomething();
  }
  // END
});

在 AMD 规范里,在 BEGIN 处,a 和 b 的 factory 都已经执行好。在 Wrappings 规范里,在 BEGIN 处,a 和 b 的 factory 还没未执行,在 END 处时,根据条件,只会执行其中一个。

可以看出,Wrappings 规范更“懒”,更节省 CPU. 更符合 nodejs 等环境下的使用习惯。

AMD 规范只所以采用提前执行,可以参考作者的说明:Standards and proposals for JavaScript Modules and jQuery, 提到了两点理由,但并不被社区认可。我个人觉得这是一种权衡,但是是一种糟糕的权衡,破坏了与 Modules/1.0 规范的和谐性。有兴趣的可以搜索 Google Groups, 有相当多的讨论。

Wrappings 规范则尽可能的保留了 Modules/1.0 规范中的习惯。权衡点在于,对于条件语句中 require:

  if(true) {
    require('./a').doSomething();
  } else {
    require('./b').soSomething();
  }

在 node 等环境中,能直接同步读取文件,可以做到只加载和执行模块 a, 不加载模块 b. 但在浏览器端,要实现这点,很困难(可以通过类似 Jscex 的方式来实现,但复杂度急增)。面对现实,目前基本所有浏览器端的 loader, 都是把依赖的模块都下载下来。从打包部署的角度考虑,这样做并不会对性能造成影响,反而能让不同条件分支,共享同一缓存。Wrappings 规范的提前下载和延迟执行,是一种合理的权衡。

3. 设计理念不同

如果你用过 RequireJS, 会知道:require 方法极其灵活,比如下面这些:

require('a')  -- gets exports of module a
require(['a']) -- fetch module a according to module name scheme
require(['a.js'])  -- fetch a.js directly relative to current page
require({...})  -- set loader config

稍微有点变化,做的事情就不一样,个人很不喜欢,社区里也有不少人讨厌这种风格。

在 SeaJS 里,API 的设计理念是:

  • 保持简单,职责单一。
  • 遵守规范,但不拘泥。
  • 适度灵活。

SeaJS 的公共 API 只有 8 个:速查手册, 职责很清晰,简单明了。

不拘泥规范,大家可以看到,SeaJS 里并没有采用 Modules/Wrappings 规范里的 module.declare. 这是因为:

module.declare(function(require, exports, module) {
  module.id // 这是参数 module
});

module.declare(function(require, exports) {
  module.id // 这是全局 module
});

显然,module.declare 导致 module 变量和 this 一样,随着环境的变化而变化。对于新手来说,这会带来迷惑。不如直接引入 define 来得简洁明了。随着 RequireJS 的推广,大家对 define 的接受程度也更高,更容易被理解。还有一个好处:使得 SeaJS 的模块,理论上讲,可以直接运行于 RequireJS 上。

适度灵活,举个例子:

seajs.use("./a"); // 加载一个模块
seajs.use(["./a", "./b"]); // 加载多个模块

4. 聚焦点有差异

SeaJS 从一开始,到现在,都是 focus on web, 努力成为浏览器端的模块加载器。sea.js 源码里,只有和浏览器相关的代码,不像 requirejs 一样,牵三挂四,有为了能在 Rhino 和 node 下运行的代码,甚至还有为了与 jQuery 集成的代码。聚焦的好处之一是,能减少文件大小:

SeaJS 目前的大小是:3.2K (gzip)
RequireJS 的大小是:5.4K (gzip)

seajs 的源码,目前是分多个文件开发的,每个文件都很聚焦,有完善的测试用例。requirejs 目前依旧是一个大文件,不利于维护。

5. 最后,还是理念不一样

RequireJS 有一系列插件,功能很强大,但破坏了模块加载器的纯粹性,个人觉得不妥。

SeaJS 则努力保持简单,追求简洁之美。除非必要,勿增实体。在功能上,SeaJS 有个优势是,支持 CSS 模块的加载。RequireJS 因为技术原因,目前版本尚未实现。

最后的最后

根据实际需求选择就好,关键是要养成模块化开发的好习惯。

Advertisements

Written by lifesinger

May 17, 2011 at 23:57

Posted in Articles

26 Responses

Subscribe to comments with RSS.

  1. 那SeaJS和豆瓣的Do框架相比呢?

    Andre

    June 1, 2011 at 14:17

  2. […] Comments Feed 来自岁月如歌的SeaJS 和 RequireJS 的异同 […]

  3. 唉 感觉很烦,还不是干那点事情,说来说去,都是很基础的东西

    sss98

    July 13, 2011 at 14:41

  4. […] 。想深入了解推荐玉伯的文章《SeaJS和RequireJS异同》 […]

    模块加载器 | 梦阳屋

    October 27, 2011 at 21:30

  5. […] 理念上无对错。对于 SeaJS 来说,选择的是延迟执行,尽量与 CommonJS 以及 NodeJS 的模型保持一致。有兴趣的可以阅读我之前的博文:SeaJS 和 RequireJS 的异同 […]

  6. “AMD 规范只所以采用提前执行”应该是“之所以”

    yushengjun

    February 6, 2012 at 18:26

  7. 实际的用了SeaJS,很简洁,而且API很优雅,很快就上手了,部署起来也不困难。

    感觉对于前端来讲,用RequireJS好像有点拿着菜刀去削苹果,个人不是很喜欢。

    还是爱SeaJS,希望Sea能越来越好~

    smallsmallwolf

    May 7, 2012 at 16:29

  8. […] SeaJS 和 RequireJS 的异同 […]

  9. 这个比较有明显的个人感情色彩啊. 强烈建议写成英文版的给amd社区的人看看,或许他们会蜂拥而来

    chuck911

    October 31, 2012 at 18:42

  10. seajs和nodejs的风格太像了,看上去seajs的语法更简洁,关键是还有spm工具。seajs更加标准化,也更强大。

    qiufangiufangzhou

    November 25, 2012 at 17:08

  11. Thanks to my father who informed me about this weblog, this web site is actually awesome.

    porn

    March 8, 2016 at 14:35

  12. This is the perfect blog for everyone who wishes to find out about this topic.
    You understand a whole lot its almost hard to argue
    with you (not that I really would want to…HaHa). You certainly put a fresh
    spin on a subject that’s been discussed for a long time. Great stuff, just
    excellent!

    xxx

    March 31, 2016 at 11:20

  13. Prettʏ! This has been an incredibly wonderful post.

    Thanks for supplying this info.

    xxx

    April 15, 2016 at 15:31

  14. After looking into a number of the bⅼog articles on your site, I reɑlly appreciate your
    way of blogging. I Ƅook-marked it to my bookmark
    website lіst and will be checking Ьack soon. Please visit
    my web site as weⅼl and let me know your opinion.

    movie

    May 22, 2016 at 09:13

  15. I’m curious to find out ԝhat blog syѕtem you have been usіng?
    I’m having some small seсurity issues with my latest site and I’d like to find something
    more risk-free. Do you have any solutions?

    free porn

    May 29, 2016 at 14:43

  16. Keep this gⲟing ⲣleasᥱ, great job!

    free porn

    May 29, 2016 at 14:47

  17. І always used to studү piece of writing in news papᥱrs
    ƅut now as I am a useг of net so fгom now I am սsing
    net for content, thanks to web.

  18. Someοne essentially assist to make significantly articles I’d state.
    This is the ᴠery first time I frequenteԀ your ᴡeb page and up to now?

    I amɑzed with the analysis yоu made to make this partіcular put up amazing.
    Great process!

    sex

    June 4, 2016 at 23:56

  19. Hі to aⅼl, the contents existing at this site are
    genuinely amaᴢing for people knowledɡe, well, keep uρ thᥱ good
    work fеllows.

    porn

    June 4, 2016 at 23:57

  20. Great ɑrticle.

    xxx

    June 5, 2016 at 17:34

  21. Hi it’s me, I am alѕo visiting this website daіly, this website
    is truly рleasant and the users are actually sharing
    good thoսghts.

  22. you’гe truly a excellent wеbmaster. The site loading
    velocitү is amazing. It seems that you’rᥱ doing any uniգue
    trick. In addition, The contents are masterwork.
    you have performeⅾ a fantastic ρrocess in tһis topic!

    porn

    June 8, 2016 at 12:18

  23. […] Seajs和RequireJS的异同 […]

  24. Heʏ tһere just ԝanted to give you a quick heads up.
    The words in youг article seem to be running off the screen in ᖴirefox.
    I’m not sure if this іs a formatting іssue or something to do with browser compatibiⅼity but
    I figured I’d poѕt to let you қnow. The layout look gгeat thoᥙgh!
    Hope you get the issue solved soon. Сheeгs

    free porn

    June 21, 2016 at 18:51

  25. Its like you read my mind! You seem to knoա so much about this, ⅼike you wrote the book
    in it or somethіng. I tɦink that you can do with a few pics to drivе the message home
    a bit, but instead of that, this is wondeгful ƅlog.
    A great rеad. І wiⅼl definitely be back.

    porn videos

    June 23, 2016 at 20:58

  26. It’s really very ϲomplicated in this busy life to ⅼisten neԝs on Teleᴠision,
    thus I simply use world wide weЬ for that reason, and obtain the most recent news.

    sex videos

    June 30, 2016 at 12:58


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