伴随前端开发者对于模块化的需求,node出现了,跟随node出现的还有commonjs,这是一种js模块化解决方案,像Node.js主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,CommonJS
加载模块是同步的,所以只有加载完成才能执行后面的操作。但是浏览器环境不同于Node,浏览器中获取一个资源必须要发送http请求,从服务器端获取,采用同步模式必然会阻塞浏览器进程出现假死现象。在这方面dojo曾经做了伟大尝试,早期dojo便是采用xhr+eval的方式,结果可想而知,阻塞现象是必然的。后来出现无阻塞加载脚本方式在开发中广泛应用,在此基础结合commonjs
规范,前端模块化迎来了两种方案:AMD、CMD
CMD
和AMD
,他们的代表分别为seajs
和requirejs
*RequireJS 和 SeaJS 都是模块加载器,倡导的是一种模块化开发理念,
核心价值是让 JavaScript 的模块化开发变得更简单自然。
- requirejs
页面的引入接口
其中 r-index.js 就是相当于分工的第二步所在的位置,在这里边儿,我们进行依赖文件的配置,
和对第一步前端页面的显示的支持
我们来看一下r-index.js是怎样写的
requirejs.config({
baseUrl: 'js/',
paths: {
hammer: 'lib/hammer.min',
jquery:'lib/jquery.min',
cookie:'lib/jquery.cookie',
template:'lib/template'
}
});
requirejs(['hammer', 'jquery', 'cookie','template','app/data'], function(a,b,c,template,service) {
service.getAll();
service.getOne();
}
对这个就是进行基础的业务的处理,
'app/data'就是具体的逻辑的处理,这些给第二步提供了所有的逻辑支持
下面我们来看一下 data.js data.js 所有第二步用到的逻辑都放在这里边进行处理
define(['jquery','cookie'],function () {
return {
/*所有数据*/
getAll:function (){
return alldata;
},
/*指定id的数据*/
getOne:function (id){
}
}
})
- seajs
首先说一下第一步,接口
然后看一下第二步的书写方式
define(function (requie, exports, module) {
//依赖可以就近书写
var hammer = require('js/lib/hammer.min');
...
var app = requie('app/data');
app.getAll();
app.getOne();
...
//软依赖
if (status) {
var b = requie('./b');
b.test();
}
});
然后看一下第三步的书写方式
module.export = {
/*所有数据*/
getAll:function (){
return alldata;
},
/*指定id的数据*/
getOne:function (id){
}
}
//需要注意的以下的写法是错误的
export = {
/*所有数据*/
getAll:function (){
return alldata;
},
/*指定id的数据*/
getOne:function (id){
}
}
RequireJS 和 SeaJS 都是很不错的模块加载器,两者区别如下:
- 两者定位有差异。RequireJS 想成为浏览器端的模块加载器,同时也想成为 Rhino /Node 等环境的模块加载器。SeaJS 则专注于 Web 浏览器端,同时通过 Node 扩展的方式可以很方便跑在 Node 服务器端
- 两者遵循的标准有差异。RequireJS 遵循的是 AMD(异步模块定义)规范,SeaJS 遵循的是 CMD (通用模块定义)规范。规范的不同,导致了两者 API 的不同。SeaJS 更简洁优雅,更贴近 CommonJS Modules/1.1 和 Node Modules 规范。
- 两者社区理念有差异。RequireJS 在尝试让第三方类库修改自身来支持 RequireJS,目前只有少数社区采纳。SeaJS 不强推,而采用自主封装的方式来“海纳百川”,目前已有较成熟的封装策略。
- 两者代码质量有差异。RequireJS 是没有明显的 bug,SeaJS 是明显没有 bug。
- 两者对调试等的支持有差异。SeaJS 通过插件,可以实现 Fiddler 中自动映射的功能,还可以实现自动 combo 等功能,非常方便便捷。RequireJS 无这方面的支持。
- 两者的插件机制有差异。RequireJS 采取的是在源码中预留接口的形式,源码中留有为插件而写的代码。SeaJS 采取的插件机制则与 Node 的方式一致:开放自身,让插件开发者可直接访问或修改,从而非常灵活,可以实现各种类型的插件。.
参考
关于 CommonJS AMD CMD UMD
让我们再聊聊浏览器资源加载优化
SeaJS与RequireJS最大的区别
YUI Modules 与 AMD/CMD,哪一种方式更好?
JavaSript模块规范 - AMD规范与CMD规范介绍