龙空技术网

CommonJS, AMD, CMD是什么及区别

郭大全 101

前言:

现时看官们对“ascmd”大约比较关怀,兄弟们都需要了解一些“ascmd”的相关资讯。那么小编同时在网络上收集了一些关于“ascmd””的相关文章,希望朋友们能喜欢,我们快快来学习一下吧!

CommonJS, AMD, CMD都是JS模块化的规范

CommonJS是服务器端js模块化的规范,NodeJS是这种规范的实现。

AMD(异步模块定义)和CMD(通用模块定义)都是浏览器端js模块化的规范。RequireJS 遵循的是 AMD,SeaJS 遵循的是 CMD。

1、CommonJS

根据CommonJS规范,一个单独的文件就是一个模块。加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。所以,定义一个模块就是写一个新的js文件,但是最后要将文件的内容exports出来。接下来我们看一下如何定义模块和加载模块。

//定义一个module.js文件

var A = function() {

console.log('我是定义的模块');

}

//导出这个模块

//1.第一种返回方式 module.exports = A;

//2.第二种返回方式 module.exports.test = A

//3.第三种返回方式 exports.test = A;

exports.test = A;

//再写一个test.js文件,去调用刚才定义好的模块,这两个文件在同一个目录下

var module = require("./module"); //加载这个模块

//调用这个模块,不同的返回方式用不同的方式调用

//1.第一种调用方式 module();

//2.第二种调用方式 module.test();

//3.第三种调用方式 module.test();

module.test();

//接下来我们去执行这个文件,前提是你本地要安装node.js,不多说了,自己百度安装。

//首先打开cmd, cd到这两个文件所在的目录下,执行: node test.js

node test.js

//输出结果:我是定义的模块

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

CommonJS是主要为了JS在后端的表现制定的,他是不适合前端的,为什么这么说呢?

这需要分析一下浏览器端的js和服务器端js都主要做了哪些事,有什么不同了:

------------------------服务器端JS | 浏览器端JS-------------------------------------------

----------相同的代码需要多次执行 | 代码需要从一个服务器端分发到多个客户端执行

------------CPU和内存资源是瓶颈 | 带宽是瓶颈

--------------加载时从磁盘中加载 | 加载时需要通过网络加载

-------------------------------------------------------------------------------------------------

2、AMD(异步模块定义)

AMD规范通过define方法去定义模块,通过require方法去加载模块。RequireJS实现了这种规范

AMD只有一个接口:define(id?,dependencies?,factory); 它要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中。

要是没什么依赖,就定义简单的模块(或者叫独立的模块)

difine接收factory参数,factory可以是一个函数,也可以是一个对象或字符串(简写函数return的对象或者字符串) 下面看代码:

//编写一个module1.js文件

//定义独立的模块

define({

methodA: function() {

console.log('我是module1的methodA');

},

methodB: function() {

console.log('我是module1的methodB');

}

});

//编写一个module2.js文件

//另一种定义独立模块的方式

define(function () {

return {

methodA: function() {

console.log('我是module2的methodA');

},

methodB: function() {

console.log('我是module2的methodB');

}

};

});

//编写一个module3.js文件

//定义非独立的模块(这个模块依赖其他模块)

define(['module1', 'module2'], function(m1, m2) {

return {

methodC: function() {

m1.methodA();

m2.methodB();

}

};

});

//再定义一个main.js,去加载这些个模块

require(['module3'], function(m3){

m3.methodC();

});

//我们在一个html文件中去通过RequireJS加载这个main.js

//等号右边的main指的main.js

<script data-main="main" src="require.js"></script>

//浏览器控制台输出结果

我是module1的methodA

我是module2的methodB

3、CMD(通用模块定义)

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

AMD和CMD的区别:

1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible(尽可能的懒加载,也称为延迟加载,即在需要的时候才加载)。

2. CMD 推崇依赖就近,AMD 推崇依赖前置。

虽然 AMD 也支持 CMD 的写法,同时还支持将 require 作为依赖项传递,但 RequireJS 的作者默认是最喜欢上面的写法,也是官方文档里默认的模块定义写法。看代码:

// CMD

define(function(require, exports, module) {

var a = require('./a');

a.doSomething();

// 此处略去 100 行

var b = require('./b'); // 依赖可以就近书写

b.doSomething();

// ...

})

// AMD 默认推荐的是

define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好

a.doSomething();

// 此处略去 100 行

b.doSomething();

//...

})

如有侵权请联系删除

标签: #ascmd