浅析AMD CMD CommonJS规范--javascript模块化加载学习心得总结


Posted in Javascript onMarch 16, 2016

这是一篇关于javascript模块化AMD,CMD,CommonJS的学习总结,作为记录也给同样对三种方式有疑问的童鞋们,有不对或者偏差之处,望各位大神指出,不胜感激。

本篇默认读者大概知道require,seajs的用法(AMD,CMD用法),所以没有加入使用语法。

1、为何而生:

 这三个规范都是为javascript模块化加载而生的,都是在用到或者预计要用到某些模块时候加载该模块,使得大量的系统巨大的庞杂的代码得以很好的组织和管理。模块化使得我们在使用和管理代码的时候不那么混乱,而且也方便了多人的合作。

2、那些规范们:

(1)、CommonJS 是一个有志于构建 JavaScript 生态圈的组织。整个社区致力于提高 JavaScript 程序的可移植性和可交换性,无论是在服务端还是浏览器端。

a group with a goal of building up the JavaScript ecosystem for web servers, desktop and command line apps and in the browser.

一个有目标的构建JavaScript生态系统Web服务器组,在浏览器和命令行应用程序和桌面。(他自己wiki上这么说的)

这个组织呢制定了一些规范 (可以去他们网站看看 http://www.commonjs.org/)包括CommonJS Modules/1.0 规范,我们平时所说的commonjs规范,说的就是这个了。

 “The CommonJS API will fill that gap by defining APIs that handle many common application needs, ultimately providing a standard library as rich as those of Python, Ruby and Java. ”--(出自 http://www.commonjs.org/)

所以说Commonjs是一个更偏向于服务器端的规范。Node.js采用了这个规范。 根据CommonJS规范,一个单独的文件就是一个模块。加载模块使用require方法,该方法读 取一个文件并执行,最后返回文件内部的exports对象。

他又说了,可以用在下面这些场景  ,所以他更明显的偏向服务器端。当然你也可以把它用在浏览器里边(他们自己说可以)。

•Server-side JavaScript applications
•Command line tools
•Desktop GUI-based applications
•Hybrid applications (Titanium, Adobe AIR)

(2)、AMD规范

Commonjs解决了模块化的问题,并且可以用在浏览器中,但是Commonjs是同步加载模块,当要用到该模块了,现加载现用,这种同步机制到了浏览器里边就有问题了,加载速度啊啥的(览器同步加载模块会导致性能、可用性、调试和跨域访问等问题)。

鉴于浏览器的特殊情况,又出现了一个规范,这个规范呢可以实现异步加载依赖模块,并且会提前加载那就是AMD规范。AMD可以作为CommonJS模块一个中转的版本只要CommonJS没有被用来同步的require调用。使用同步require调用的CommonJS代码可以被转换为使用回调风格的AMD模块加载器(https://github.com/amdjs/amdjs-api/wiki/AMD-(%E4%B8%AD%E6%96%87%E7%89%88)  (它说的)。

下面是一个使用了简单CommonJS转换的模块定义(它是amd规范的一种用法):

   define(function (require, exports, module) {

     var a = require('a'),

         b = require('b');
     exports.action = function () {};

   });

所以说AMD和Commonjs是兼容的,只要稍稍调换一下调用方法就实现了同步加载(我很怀疑amd也是在commonjs基础上加了个壳,然后并没有找到其他的神马说明和支持的文字,找到了一定加到这)。

看一下AMD规范你会发现,AMD基本都是提前说明依赖模块,然后预加载这些模块,实际上这就要求你提前想好这些依赖,提前写好,不然写代码过程中要回到开头继续添加依赖。

 
(3)、CMD

不知道是不是针对这个问题,淘宝的玉伯大牛搞了个seajs出来,并声称这个规范是遵循CMD规范的,然后给出了这个规范的一个连接(打开会发现draft字样)。关于这个规范呢玉伯在知乎是这么说的

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

CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
类似的还有 CommonJS Modules/2.0 规范,是 BravoJS 在推广过程中对模块定义的规范化产出。
还有不少⋯⋯

所以这个规范实际上是为了Seajs的推广然后搞出来的。那么看看SeaJS是怎么回事儿吧,基本就是知道这个规范了。

同样Seajs也是预加载依赖js跟AMD的规范在预加载这一点上是相同的,明显不同的地方是调用,和声明依赖的地方。AMD和CMD都是用difine和require,但是CMD标准倾向于在使用过程中提出依赖,就是不管代码写到哪突然发现需要依赖另一个模块,那就在当前代码用require引入就可以了,规范会帮你搞定预加载,你随便写就可以了。但是AMD标准让你必须提前在头部依赖参数部分写好(没有写好? 倒回去写好咯)。这就是最明显的区别。

3、共生共处

由于CommonJS是服务器端的规范,更另外两个标准实际不冲突。

AMD在国外用的更多,当然国内也是不少的,jQuery1,7版本开始使用,Dojo在1.6版本开始用,这已经能够证明它足够牛x了。

CMD当然也有很多人在用,但是基本都集中在国内,Seajs官网就展示了一大堆牛逼的公司在用(包括爱奇艺,腾讯微博,支付宝,淘宝等一大堆,去这看看http://seajs.org/docs/),估计小的不出名的也不计其数了,毕竟很多公司招聘都要求会seajs嘛。

所以三个规范目前都挺好(其实也主要是因为js么有自己的模块加载机制,es6出来之后不知道会怎样)。

当我们写一个文件需要兼容不同的加载规范的时候怎么办呢,看看下面的代码。

(function (root, factory) { 
 
  if (typeof define === 'function' && define.amd) { 
 
    // AMD 
 
    define(['jquery', 'underscore'], factory); 
 
  } else if (typeof exports === 'object') { 
 
    // Node, CommonJS之类的 
 
    module.exports = factory(require('jquery'), require('underscore')); 
 
  } else { 
 
    // 浏览器全局变量(root 即 window) 
 
    root.returnExports = factory(root.jQuery, root._); 
 
  } 
 
}(this, function ($, _) { 
 
  // 方法 
 
  function a(){}; // 私有方法,因为它没被返回 (见下面) 
 
  function b(){}; // 公共方法,因为被返回了 
 
  function c(){}; // 公共方法,因为被返回了 
 
    
 
  // 暴露公共方法 
 
  return { 
 
    b: b, 
 
    c: c 
 
  } 
 
}));

这个代码可以兼容各种加载规范了。

4、AMD和CMD的区别

下面这几点是玉伯在知乎上说的。

1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.
2. CMD 推崇依赖就近,AMD 推崇依赖前置。

3. AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每个 API 都简单纯粹。
 
4. 还有一些细节差异,具体看这个规范的定义就好,就不多说了。
     ( 好吧~第四点是不多说了。。。。。。。。。)

5、AMD和CMD的一些相同

都有difine和require,而且调用方式实际都可以添加依赖参数,也就是说都可以用提供依赖参数的方式来实现预加载依赖模块(但是不推荐因为  注意:带 id 和 deps 参数的 define 用法不属于 CMD 规范,而属于 Modules/Transport 规范。---来自:https://github.com/seajs/seajs/issues/242)。

AMD也可以在factory中使用require来现加载用到的模块,但是这个模块就不会预先加载,属于用到才加载的同步加载了。

var a = require('a'); // 加载模块a

有不妥之处,欢迎斧正。

以上这篇浅析AMD CMD CommonJS规范--javascript模块化加载学习心得总结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
载入进度条 效果
Jul 08 Javascript
兼容ie、firefox的图片自动缩放的css跟js代码分享
Jan 21 Javascript
jquery实现叠层3D文字特效代码分享
Aug 21 Javascript
JS实时弹出新消息提示框并有提示音响起的实现代码
Apr 20 Javascript
js+html5实现canvas绘制椭圆形图案的方法
May 21 Javascript
AngularJS实现单独作用域内的数据操作
Sep 05 Javascript
js实现日历的简单算法
Jan 24 Javascript
vue中如何实现变量和字符串拼接
Jun 19 Javascript
mpvue跳转页面及注意事项
Aug 03 Javascript
vue-test-utils初使用详解
May 23 Javascript
JavaScript内置对象math,global功能与用法实例分析
Jun 10 Javascript
JS继承最简单的理解方式
Mar 31 Javascript
js纯数字逐一停止显示效果的实现代码
Mar 16 #Javascript
神奇!js+CSS+DIV实现文字颜色渐变效果
Mar 16 #Javascript
js获取时间精确到秒(年月日)
Mar 16 #Javascript
js实现内容显示并使用json传输数据
Mar 16 #Javascript
javascript中arguments,callee,caller详解
Mar 16 #Javascript
Bootstrap每天必学之滚动监听
Mar 16 #Javascript
基于jQuery Tipso插件实现消息提示框特效
Mar 16 #Javascript
You might like
php读取图片内容并输出到浏览器的实现代码
2013/08/08 PHP
PHP COOKIE及时生效的方法介绍
2014/02/14 PHP
ThinkPHP令牌验证实例
2014/06/18 PHP
jquery 实现的全选和反选
2009/04/15 Javascript
JQuery通过Ajax提交表单并返回结果
2011/07/31 Javascript
使用javascript创建快捷方式的简单实例
2013/08/09 Javascript
jQuery简单图表peity.js使用示例
2014/05/02 Javascript
利用Angularjs和bootstrap实现购物车功能
2016/08/31 Javascript
深入理解angular2启动项目步骤
2017/07/15 Javascript
详解webpack与SPA实践之开发环境搭建
2017/12/18 Javascript
js 取消页面可以选中文字的功能方法
2018/01/02 Javascript
vue+webpack实现异步组件加载的方法
2018/02/03 Javascript
vue使用监听实现全选反选功能
2018/07/06 Javascript
Vue.js组件间通信方式总结【推荐】
2018/11/23 Javascript
node链接mongodb数据库的方法详解【阿里云服务器环境ubuntu】
2019/03/07 Javascript
微信小程序中如何使用flyio封装网络请求
2019/07/03 Javascript
浅谈javascript错误处理
2019/08/11 Javascript
JS XMLHttpRequest原理与使用方法深入详解
2020/04/30 Javascript
vue实现移动端拖动排序
2020/08/21 Javascript
jquery实现简单每周轮换的日历
2020/09/10 jQuery
编写同时兼容Python2.x与Python3.x版本的代码的几个示例
2015/03/30 Python
分享一下如何编写高效且优雅的 Python 代码
2017/09/07 Python
Python动态赋值的陷阱知识点总结
2019/03/17 Python
python实现栅栏加解密 支持密钥加密
2019/03/20 Python
python实现给微信指定好友定时发送消息
2019/04/29 Python
python安装scipy的方法步骤
2019/06/26 Python
Pyqt助手安装PyQt5帮助文档过程图解
2020/11/20 Python
JackJones官方旗舰店:杰克琼斯男装
2018/03/27 全球购物
狗狗玩具、零食和咀嚼物的月度送货服务:Super Chewer
2018/08/22 全球购物
中学生学习生活的自我评价
2013/10/26 职场文书
公司办公室岗位职责
2014/03/19 职场文书
民政局副局长民主生活会个人对照检查材料
2014/09/19 职场文书
财务经理岗位职责范本
2015/04/08 职场文书
奖励申请报告范文
2015/05/15 职场文书
pytorch 带batch的tensor类型图像显示操作
2021/05/20 Python
利用python调用摄像头的实例分析
2021/06/07 Python