1. 云栖社区>
  2. 技术文集>
  3. 列表>
  4. 正文

RequireJS、SeaJS的区别

作者:用户 来源:互联网 时间:2016-08-03 18:43:52

jquery函数requirejsjs函数require路径模块懒加载sessionrequirejs中回调函数问题sea.js 百度地图 apijs脚本学习require加载jsrequire同步加载exports

RequireJS、SeaJS的区别 - 摘要: 本文讲的是RequireJS、SeaJS的区别, 引用自知乎(卢勃) 1. RequireJS的异步模块加载迎合了浏览器端JS程序员固有的异步思维,学习成本低 ----------------------

引用自知乎(卢勃)

1. RequireJS的异步模块加载迎合了浏览器端JS程序员固有的异步思维,学习成本低
--------------------------------
Sea.js的主页中写到:
  • Sea.js 遵循 CMD 规范,可以像 Node.js 一般书写模块代码
  • 依赖的自动加载、配置的简洁清晰,可以让我们更多地享受编码的乐趣
两年前,我看到Sea.js这样的自我描述,第一感觉是:为什么浏览器的JS编程和NodeJS相仿就是优雅呢?

那么,来讨论RequireJS和Sea.js的学习成本问题

如RequireJS中依赖模块:
require(['jquery','创建了全局变量的module'],function($,b){
	//既然我在开头明确声明依赖需求,那可以确定在执行这个回调函数时,依赖肯定是已经满足了
	//所以,放心地使用吧
})

而Sea.js中表现为:
define(function(require,exports,modules){
	var $ = require('jquery')
	$.get('http://www.zhihu.com')
	//传统JS程序员的思维:
	//“咦,好神奇,JS加载不应该是异步的么,怎么我一说要依赖,jquery就自己跳出来了?”
})

所以,是“理所应当”容易理解,还是变魔术容易理解呢?

2. RequireJS的实现方式符合JS一般执行流程
--------------------------------
当我们看到RequireJS的接口,
require(['a','b'],function(){
//Do something
})
实际做的事情是:
  1. require函数检查依赖的模块,根据配置文件,获取js文件的实际路径
  2. 根据js文件实际路径,在dom中插入script节点,并绑定onload事件来获取该模块加载完成的通知。
  3. 依赖script全部加载完成后,调用回调函数
以上步骤是容易想象的

而Sea.js在调用
define('a',function(require,exports,modules){
	var b = require('b')
})
时,
  1. 通过回调函数的Function.toString函数,使用正则表达式来捕捉内部的require字段,找到require('jquery')内部依赖的模块jquery
  2. 根据配置文件,找到jquery的js文件的实际路径
  3. 在dom中插入script标签,载入模块指定的js,绑定加载完成的事件,使得加载完成后将js文件绑定到require模块指定的id(这里就是jquery这个字符串)上
  4. 回调函数内部依赖的js全部加载(暂不调用)完后,调用回调函数
  5. 当回调函数调用require('jquery'),即执行绑定在'jquery'这个id上的js文件,即刻执行,并将返回值传给var b
这种用正则表达式捕捉require内部依赖模块的方式,使得无法利用尚未执行的回调函数中的js运行环境,导致require函数的内部只能将依赖的模块名称硬编码,就不能写下面这样的代码了
define('a',function(require,exports,modules){
    var b = require('Us'+'er')
})
而只能写成
define('a',function(require,exports,modules){
    var b = require('User')
})
而以上Sea.js最根本的原理在Sea.js的文档中居然毫无踪影!
“你变了精彩的魔术,我们会为你喝彩。但你想让我们信任你,你得主动解释魔术的奥秘。否则我会觉得自己被耍了。”

所以就引来了下一条:

3. Sea.js的文档立足高度高,未提及重点细节
--------------------------------
其实如果像上一段一样,将Sea.js的核心原理进行简单解释,有基本知识的JS程序员大概是可以“五分钟上手Sea.js”的,但在官方文档中,这些都只字不提。

Sea.js - 官方文档 中开始在讲要解决的问题和问题解决后的价值,OK,能开始有意识尝试使用Sea.js的JS程序员想必是遇到模块错综复杂的问题需要解决了。

然后给了看起来同步加载的,显得很魔术的示例代码(“哇,好厉害的赶脚!大牛,所以这是怎么做到的呢?”)
// 所有模块都通过 define 来定义
define(function(require, exports, module) {

  // 通过 require 引入依赖
  var $ = require('jquery');
  var Spinning = require('./spinning');

  // 通过 exports 对外提供接口
  exports.doSomething = ...

  // 或者通过 module.exports 提供整个接口
  module.exports = ...

});

接着就直接开讲API和约定了。(“谁来照顾下我的好奇心呢!说好的我今天对你爱理不理,明天你让我高攀不起呢!”)

这种感觉好像是数学老师刚刚还在讲微积分的历史沿革及其重要性,低头看了眼手机,抬起头就已经在讲三重积分了呢!(捂脸)

这也是我通篇充满了对作者的怨恨的原因。当时初闻Sea.js,发现是国人的作品耶,恩,网上评价不错,立马学习,没有理由地想从RequireJS迁移到Sea.js(RequireJS在一边问:“我做错什么了吗?做错了我改嘛”)。但看文档尝试阅读了好几次(没有看代码,骂我吧),还是觉得很魔术,觉得是雾里看花。
今天不知从哪里瞟了一眼,说是Sea.js通过正则表达式来找回调函数内容中的require来确定加载的函数,然后一看代码果然是,顿时火从心燃,不写篇文章吐槽绝不能灭火(想象抛妻弃子追寻真爱,最终发现真爱原是博爱的感觉)。

技术文档应当切中要害,节约读者时间,而不是故作深沉。将简单的复杂化怎么也不应该是程序员的作风。

“为世界和平稳定,家庭的幸福快乐”不能停留在嘴上说说,最终要落到实处。

4. Sea.js部署优化工具尚未完善
--------------------------------
好吧,这是听大家在上面说的,我没怎么用Sea.js,还没遇到这样的问题

最后想对 @李翌 的回答中,关于懒加载的部分表达下我的理解

LazyLoad的优势体现在:仅当资源需要被使用前加载资源。在RequireJS和Sea.js中表现为,在回调函数调用前加载js脚本资源。

RequireJS和Sea.js在资源加载的时间点都是一样的,所以论“懒”的程度都是一样的。差别仅仅在于加载的脚本什么时候执行。RequireJS的依赖模块在回调函数执行前执行完毕,而Sea.js的依赖模块在回调函数执行require时执行。

而回调函数希望实现的目标就好比“事务的原子性”,仅当整个回调函数结束才算完成了目标。那么既然整个回调函数的执行时间是恒定的,那么个人认为脚本加载的时间到底耗费在回调前还是回调时,并没有本质的差别。如果不认同是否本质相同,那么至少也没有谁更懒的区别。



以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有 的相关内容,欢迎继续使用右上角搜索按钮进行搜索jquery , 函数 , requirejs , js函数 , require路径 , 模块 , 懒加载session , require , js中回调函数问题 , sea.js 百度地图 api , js脚本学习 , require加载js , require同步加载 exports seajs和requirejs区别、requirejs seajs 区别、seajs requirejs、requirejs和seajs、seajs与requirejs,以便于您获取更多的相关知识。

seajs-seaJS怎么模块化非JQUERY插件

问题描述 seaJS怎么模块化非JQUERY插件 我看官网上面,seaJS只介绍了如何去模块化JQUERY插件,但是不属于JQUERY插件范畴的,应该怎样去模块化,比如datetimepicker这种,求指点,或者给个网址看...

LABjs、RequireJS、SeaJS的区别_Seajs

...,核心价值是性能优化。LABjs 是一个文件加载器。 二、RequireJS 和 SeaJS 则是模块加载器,倡导的是一种模块化开发理念,核心价值是让 JavaScript 的模块化开发变得更简单自然。模块加载器也可降级为文件加载器用,因此使用 Requi...

自己总结的web前端知识体系大全

...是维护上。icomoon.io能让我自定义选择自己的图标文件。requirejs和seajs这种模块定义系统,也一定是你系统中不可或缺的。我曾经看过一个教程,讲师就说:requirejs带来了既jquery之后的第二次前端技术变革。其他的,backbone、angular...

近几年前端技术盘点以及 2016 年技术发展方向(转)

...相互争斗,产出了 AMD、CMD、KMD 等规范,也衍生了 SeaJS、RequireJS 等模块化工具。前端在这一年很有跳跃感。 13 年,爆发式增长,百花齐放 规范和标准上有不少产出。Web Components 的出现给前端开发开辟了新思路;WebDriver 规范的...

LABjs、RequireJS、SeaJS的区别

...,核心价值是性能优化。LABjs 是一个文件加载器。 二、RequireJS 和 SeaJS 则是模块加载器,倡导的是一种模块化开发理念,核心价值是让 JavaScript 的模块化开发变得更简单自然。模块加载器也可降级为文件加载器用,因此使用 Requi...

前三篇
后三篇