聊一聊CommonJS,RequireJS,SeaJs,AMD,CMD之间需要清理的关系

在学习js和使用js的过程中一定会使用到模块化开发的思想。而提到模块化就一定会提到CommonJS、RequireJS、AMD、CMD等名词。下面我将根据自己查阅的资料梳理以下这几个名词背后的关联。

首先上个图,直观感受下这个几个名词的关系:
这里写图片描述

commonjs使用在服务器端的,模块的加载方式是同步的,如nodejs
amd,cmd是用在浏览器端,这两种规范规定的模块的加载方式是异步的,它们的对应的模块加载器分别是requirejs和seajs。其中,amd先提出,cnd是根据commonjs和amd基础上提出的。

CommonJS
CommonJS是服务器端模块的规范,Node.js采用了这个规范。

根据CommonJS规范,一个单独的文件就是一个模块。模块加载使用require方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。

例如:
//foobar.js

//私有变量
var test=123;

//公有方法
function foobar(){
this.foo=function(){
// do something…
}
this.bar=function(){
//do something
}
}

//exports对象上的方法和变量是公有的
var foobar=new foobar();
exports.foobar=foobar;

//require方法默认读取js文件,所以可以省略js后缀
var test=require(“./boobar”).foobar;

test.bar();

CommonJS加载模块是同步的,所以只有加载完成才能执行后面的操作。像Node.js主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,所以CommonJS规范比较适用。但如果是浏览器环境,要从服务器加载模块,这时就需要采用异步模式。所以就有了AMD和CMD解决方案。

AMD(Asynchromous Module Definition)

AMD是RequireJS在推广过程中对模块定义的规范化产出。

AMD是异步加载模块。它的模块支持对象 函数 构造器 JSON等各种类型的模块。

适用AMD规范适用define方法定义模块。

//通过数组引入依赖,回调函数通过形参传入依赖
define([‘someModule1’,’someModule2’],function(someModule1,someModule2){
function foo(){
//something
someModule1.test();
}
return {foo:foo};
});
AMD规范允许输出模块兼容CommonJS规范,这时define方法如下:

define(function(require,exports,module){
var reqModule=require(“./someModule”);
reqMoudle.test();
exports.asplode=function(){
//something
}

})

CMD

CMD是SeaJS在推广过程中对模块定义的规范化产出

CMD 和AMD的区别有以下几点:

1.对于依赖的模块AMD是提前执行,CMD是延迟执行。不过RequireJS从2.0开始,也改成可以延迟执行(根据写法不同,处理方式不通过)
2.CMD推崇依赖就近。AMD推崇依赖前置
//AMD
define([‘./a’,’./b’],function(a,b){
//依赖一开始就写好
a.test();
b.test();
})

//CMD
define(function(require,exports,module){
//依赖可以就近书写
var a=require(‘./a’);
a.test();

//软依赖
if(status){
var b=require(‘./b’)
b.test();
}
})

虽然AMD也支持CMD写法,但依赖前置是官方文档的默认模块定义写法。

3.AMD的api默认是一个当多个用,CMD严格的区分推崇职责单一。例如:AMD里require分全局的和局部的。CMD里面没有全局的require,提供seajs.use()来实现模块系统的加载启动。CMD里每个API都简单纯粹。

Seajs和RequireJS的主要区别在此有解释。

续:RequireJS和SeaJS与CommonJS的比较(严格意义上前两者与后者不该放在一起比较,因为前两者是规范的具体实现,而后者是一种规范)

RequireJS实现了AMD的API
CommonJS是使用exports对象来定义模块的一种方法,它定义了模块的内容。简单地实现一个CommonJS定义就像下面这样
//someModule.js
exports.doSomething=function(){return “foo”};
//otherModule.js
var someModule=reuqire(“someModule”);
exports.doSomethingElse=function(){
return someModule.doSomething()+”bar”;
}
基本上CommonJS明确了你需要一个reuqire函数来获取依赖,exports变量来输入模块的内容和一些用来获取依赖的模块标识符。CommonJS有多种实现,比如Node.js
因为CommonJS设计的时候没有考虑浏览器,所以他不适合浏览器环境所以它不适合浏览器环境(我其实对这个不明确,但是这种说法到处都有,比如RequireJS官网)。所以我们得做一些工作来实现异步加载。

相反,RequireJS实现了AMD,它被设计用来适应浏览器环境。表面上看来,AMD开始是CommonJS输出格式化的副厂品,而且最终进化出了自己的API。在AMD中出现的新东西是define函数,它允许模块加载依赖之前声明它的依赖。例如定义可能就像下面这样:
define(‘module/id/string’,[‘module’,’dependency’,’array’],function(module,factory function){
return ModuleCotents;
});
因此CommonJS和AMD是Javascript模块定义API的不同的实现,但是他们有相同的根源。AMD更适合浏览器,因为它支持异步加载模块依赖。RequireJS是AMD的一个实现,而尽量保留了CommonJS的精神(主要是模块标识符上)。更让人混乱的是,ReuqireJS是实现AMD的同事,还提供了一个CommonJS包裹,这样CommonJS模块可以几乎直接被RequireJS引入。

define(function(reuqire,exports,module){
var someModule=require(‘someModule’);
exports.doSomethingElse=function(){
return someModule.doSomething()+”bar”;
} )

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值