JavaSript模块规范--AMD规范与CMD规范

简介: 有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块;但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则岂不是乱了套;考虑到Javascript模块现在还没有官方规范,这一点就更重要了

模块的规范

有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块;但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则岂不是乱了套;考虑到Javascript模块现在还没有官方规范,这一点就更重要了

目前,通行的Javascript模块规范主要有:CommonJS/AMD/CMD;那么让我先从CommonJS讲起

CommonJS

2009年美国程序员Ryan Dahl创造了node.js项目,将javascript语言用于服务器端编程,这标志"Javascript模块化编程"正式诞生;因为老实说,在浏览器环境下,没有模块也不是特别大的问题,毕竟网页程序的复杂性有限;但是在服务器端,一定要有模块,与操作系统和其他应用程序互动,否则根本没法编程

node.js的模块系统就是参照CommonJS规范实现的;在CommonJS中,有一个全局性方法require()用于加载模块;假定有一个数学模块math.js,就可以像下面这样加载

var math = require('math');

然后就可以调用模块提供的方法:

var math = require('math');
math.add(2,3); // 5

我们在这里就需要知道:require()是用于加载模块的

浏览器环境

有了服务器端模块以后,大家就想要客户端模块;而且最好两者能够兼容,一个模块不用修改,在服务器和浏览器都可以运行;但是,由于一个重大的局限,使得CommonJS规范不适用于浏览器环境;上面的代码如果在浏览器中运行就会有一个很大的问题:第二行math.add(2, 3)在第一行require('math')之后运行,因此必须等math.js加载完成;如果加载时间很长,整个应用就会停在那里等;这对服务器端不是一个问题,因为所有的模块都存放在本地硬盘可以同步加载完成,等待时间就是硬盘的读取时间;但是对于浏览器,这却是一个大问题,因为模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于"假死"状态

因此,浏览器端的模块不能采用"同步加载"(synchronous),只能采用"异步加载"(asynchronous);这就是为什么有了AMD的诞生

AMD

AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义",是在推广require.js时对模块规范化产出;它采用异步方式加载模块,模块的加载不影响它后面语句的运行;所有依赖这个模块的语句都定义在一个回调函数中,等到加载完成之后这个回调函数才会运行;AMD也采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:

require([module], callback);

第一个参数[module]是一个数组,里面的成员就是要加载的模块;第二个参数callback则是加载成功之后的回调函数;如果将前面的代码改写成AMD形式,就是下面这样:

require(['math'],function(math){
  math.add(2,3);
})

math.add()与math模块加载不是同步的,浏览器不会发生假死;所以很显然AMD比较适合浏览器环境

目前主要有两个Javascript库实现了AMD规范:require.js和curl.js

下面来看下require.js具体的用法(具体详细配置以及使用方法请大家查看require.js官方文档):

define(['someModule1','someModule2'],function(someModule1, someModule2){ //通过数组引入依赖,回调函数通过形参传入依赖
  function foo(){
    someModule1.test();
  }
  return {foo:foo}
})

AMD规范允许输出模块兼容CommonJS规范,这时define方法如下:

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

因此我们可以得出结论:

1.Amd推崇的是依赖前置

2.Amd对加载的模块是提前读取并加载

CMD代表的sea.js

CMD是指Common Module Definition--异步的模块加载机制,是在推广sea.js时对模块规范化产出

Cmd更像是Amd和Common.js的升级版,结合了两者的优点;Common.js可以做到当需要这个模块时再读取并加载

Amd可以做到避免Common.js的 "临时读取并加载文件",它是提前读取并加载;而Cmd可以做到的是"提前读取文件,但在需要再加载",这样可以避免浏览器临时加载文件的假死,也可以避免提前加载引起的逻辑问题;所以大家叫sea.js懒加载,也就是"as lazy as possible",这也是Cmd的标志

因此我们可以总结出:

1.Cmd推崇的是就近依赖

2.Cmd对加载的模块是提前读取并不加载,而是在需要时加载

目录
相关文章
|
3月前
|
JavaScript 前端开发 开发工具
深入了解 AMD 和 CMD 规范:探索模块加载的世界(下)
深入了解 AMD 和 CMD 规范:探索模块加载的世界(下)
|
3月前
|
JavaScript 前端开发 开发者
深入了解 AMD 和 CMD 规范:探索模块加载的世界(上)
深入了解 AMD 和 CMD 规范:探索模块加载的世界(上)
|
5月前
|
JavaScript 前端开发 开发者
各种模块化方案的解释-AMD-CMD-Module
各种模块化方案的解释-AMD-CMD-Module
22 0
|
8月前
|
JavaScript 前端开发
深入了解前端开发规范的区别《Commonjs、AMD、CMD、ES6模块化》
深入了解前端开发规范的区别《Commonjs、AMD、CMD、ES6模块化》
68 0
|
8月前
|
JavaScript API
说说AMD、CMD、commonJS模块化规范的区别?
说说AMD、CMD、commonJS模块化规范的区别?
105 0
|
8月前
|
JavaScript API
AMD、CMD、commonJS模块化规范的区别
AMD、CMD、commonJS模块化规范的区别
51 0
|
9月前
|
测试技术
包图画法注意规范
包图画法注意规范
|
9月前
|
存储 IDE NoSQL
我是如何组织 Go 代码的(目录结构 依赖注入 wire)
我们在编写 Go 程序可能会直接新建 main.go,xxx.go,yyy.go……对于小型工程来说简洁明了;但对于大型工程而言,或者团队协作中,没有明确的规范,只会使得项目越来越凌乱……
68 0
|
JavaScript 前端开发
js 模块化基础和模块规范AMD、CMD、ES6模块
js 模块化基础和模块规范AMD、CMD、ES6模块
86 0
rapidio 各版本规范
rapidio 各版本规范
112 0