浅析JS模块规范:AMD和CMD

在了解 AMDCMD规范前,我们先来简单地了解下什么是模块?

简单的说,一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块。当然,模块开发需要遵循一定的规范,否则各用各的就会乱套了。

目前,常用的JS模块规范主要有两种: CMDAMD

AMD

AMD ,异步模块定义(Asynchronous Module Definition),它是依赖前置 (依赖必须一开始就写好)会先尽早地执行(依赖)模块 。换句话说,所有的 require 都被提前执行(require 可以是全局或局部 )。

AMD规范只定义了一个函数  define,它是全局变量。用法:

defind(id, dependencies, factory)

参数说明:
  • id:字符串类型,指定义中模块的名称,可选。如果没有提供该参数,模块的名称应该默认为模块加载器请求的指定脚本的名称。如果提供了该参数,模块名必须是“顶级”的和绝对的(不允许相对名称)。
  • dependencies:array类型,包含一组当前模块依赖的,已被模块定义的模块标识。
依赖参数是可选的,如果忽略此参数,它应该默认为 ["require", "exports", "module"]。然而,如果工厂方法的长度属性小于3,加载器会选择以函数的长度属性指定的参数个数调用工厂方法。
  • factory:函数(工厂方法),模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。

模块名的格式

模块名用来唯一标识定义中模块,它们同样在依赖性数组中使用:

模块名是用正斜杠分割的有意义单词的字符串  

单词须为驼峰形式,或者"."".."  

模块名不允许文件扩展名的形式,如“.js”  

模块名可以为 "相对的""顶级的"。如果首字符为“.”或“..”则为相对的模块名  

顶级的模块名从根命名空间的概念模块解析  

相对的模块名从 "require" 书写和调用的模块解析


对于 AMD ,最具代表性的就是 RequireJS ,官网: http://www.requirejs.cn/

简单实例

首先在创建一个index.html,内容如下:

<!DOCTYPE html>  

<html lang="en">  

<head>   

  <meta charset="UTF-8">   

  <title>AMD</title>  

</head>  

<body>   

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

</body>  

</html>


在上面的代码中,我们引入了require.js,然后使用 data-main属性指定入口文件为scripts/main(这里省略后缀.js)。

然后在index.html同级下创建一个文件夹scripts,跟着创建三个js文件:a.js、b.js、mian.js,代码如下:

/* 

*  a.js 

*  创建一个名为“a”的模块

*/



define('a', function(require, exports, module) {   

  exports.getTime = function() {   

    return new Date();   

  }  

});



/* 

*  b.js 

*  创建一个名为“b”的模块,同时使用依赖require、exports和名为“a”的模块:

*/

define('b', ['require', 'exports', 'a'], function(require, exports, a) {   exports.test = function() {

    return {   

      now: a.getTime()    

    };   

  }  

});



/* main.js */

require(['b'], function(b) {   

  console.log(b.test());  

});



关于Requirejs更多内容: http://www.requirejs.cn/home.html

CMD

CMD(Common Module Definition)更贴近 CommonJS Modules/1.1 和 Node Modules 规范,一个模块就是一个文件;它推崇依赖就近,想什么时候  require 就什么时候加载,实现了懒加载(延迟执行 ) ;它也没有全局 require, 每个API都简单纯粹 。

对于 CMD ,有代表性的是 SeaJS ,官网: http://seajs.org/docs/

在  CMD 规范中,一个模块就是一个文件。代码的书写格式如下:

define(factory);

factory 为函数时,表示是模块的构造方法。执行该构造方法,可以得到模块向外提供的接口。factory 方法在执行时,默认会传入三个参数: require、exports 和 module

define(function(require, exports, module) {    

  // 模块代码  

});


简单实例

创建一个index.html,内容如下:

<!DOCTYPE html>  

<html lang="en">  

<head>   

  <meta charset="UTF-8">   

  <title>CMD</title>  

</head>  

<body>     

  <script src="sea.js"></script>   

  <script>   

    /* 加载入口模块 */

    seajs.use('./scripts/main');   

  </script>  

</body>  

</html>


然后在index.html同级下创建一个scripts文件夹,跟着创建两个js文件:a.js、main.js,代码如下:

/* 

*  a.js 

*  一个文件就是一个模块

*/

define(function(require, exports, module) {   

  exports.getTime = function() {   

    return new Date();   

  }  

});



/* main.js */

define(function(require, exports, module) {  

  /* 按需加载a.js */ 

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

  console.log(a.getTime());  

});


RequireJSSea.js共同点
  • RequireJS 和 Sea.js 都是模块加载器

不同之处 (出处: 玉伯:与 RequireJS 的异同 ):
  • 定位有差异。RequireJS 想成为浏览器端的模块加载器,同时也想成为 Rhino / Node 等环境的模块加载器。Sea.js 则专注于 Web 浏览器端,同时通过 Node 扩展的方式可以很方便跑在 Node 环境中。
  • 遵循的规范不同。RequireJS 遵循 AMD(异步模块定义)规范,Sea.js 遵循 CMD (通用模块定义)规范。规范的不同,导致了两者 API 不同。Sea.js 更贴近 CommonJS Modules/1.1 和 Node Modules 规范。
  • 推广理念有差异。RequireJS 在尝试让第三方类库修改自身来支持 RequireJS,目前只有少数社区采纳。Sea.js 不强推,采用自主封装的方式来“海纳百川”,目前已有较成熟的封装策略。
  • 对开发调试的支持有差异。Sea.js 非常关注代码的开发调试,有 nocache、debug 等用于调试的插件。RequireJS 无这方面的明显支持。
  • 插件机制不同。RequireJS 采取的是在源码中预留接口的形式,插件类型比较单一。Sea.js 采取的是通用事件机制,插件类型更丰富。

AMD与CMD的比较

  • AMD:依赖前置,预执行(异步加载:依赖先执行)。CMD:依赖就近,懒(延迟)执行(运行到需加载,根据顺序执行)

// CMD
define(function(require, exports, module) {  

  var a = require('./a')  

  a.doSomething();  

  // 省略1万行 

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

  b.doSomething();

})

// AMD 默认推荐的是
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好  

  a.doSomething();  

  // 省略1万行  

  b.doSomething();

}) 

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
原文:  http://ghmagical.com/article/page/id/N7VY7Hg4TlgW  ©  ghmagical.com
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值