理解AMD ,CMD,CommonJS规范
https://blog.csdn.net/xcymorningsun/article/details/52709608
理解AMD ,CMD,CommonJS规范
这是一篇关于javascript模块化AMD,CMD,CommonJS的学习总结,作为记录也给同样对三种方式有疑问的童鞋们,有不对或者偏差之处,望各位大神指出,不胜感激。
本篇默认读者大概知道require,seajs的用法(AMD,CMD用法),所以没有加入使用语法。
1、为何而生:
这三个规范都是为javascript模块化加载而生的,都是在用到或者预计要用到某些模块时候加载该模块,使得大量的系统巨大的庞杂的代码得以很好的组织和管理。模块化使得我们在使用和管理代码的时候不那么混乱,而且也方便了多人的合作。
2、那些规范们:
(1)、CommonJS 是一个有志于构建 JavaScript 生态圈的组织。整个社区致力于提高 JavaScript 程序的可移植性和可交换性,无论是在服务端还是浏览器端。
a groupwith a goal of building up the JavaScript ecosystem for web servers, desktopand command line apps and in the browser.
一个有目标的构建JavaScript生态系统Web服务器组,在浏览器和命令行应用程序和桌面。(他自己wiki上这么说的)
这个组织呢制定了一些规范 (可以去他们网站看看 http://www.commonjs.org/)包括CommonJS Modules/1.0 规范,我们平时所说的commonjs规范,说的就是这个了。
“TheCommonJS API will fill that gap by defining APIs that handle many commonapplication needs, ultimately providing a standard library as rich as those ofPython, 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 在推广过程中对模块定义的规范化产出。
类似的还有 CommonJSModules/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出来之后不知道会怎样)。
当我们写一个文件需要兼容不同的加载规范的时候怎么办呢,看看下面的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
(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 aspossible.
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规范的更多相关文章
- js模块系统 - amd|cmd|commonjs|esm|umd
写过前端代码大概率听说过amd cmd umd commonjs esm这些名词, 想当初我第一次看到这些的时候, 人都麻了, 都是些啥啊. 后来我知道了, 这些都是js的模块规范. amd - 浏览 ...
- AMD/CMD/CommonJs到底是什么?它们有什么区别?
知识点1:AMD/CMD/CommonJs是JS模块化开发的标准,目前对应的实现是RequireJs/SeaJs/nodeJs. 知识点2:CommonJs主要针对服务端,AMD/CMD主要针对浏 ...
- FW: AMD, CMD, CommonJS和UMD
javascript 我是豆腐不是渣 4月5日发布 推荐 2 推荐 收藏 32 收藏,486 浏览 今天由于项目中引入的echarts的文件太大,requirejs经常加载超时,不得不分开来加载ech ...
- AMD, CMD, CommonJS和UMD
我的Github(https://github.com/tonyzheng1990/tonyzheng1990.github.io/issues),欢迎star 今天由于项目中引入的echarts的文 ...
- 关于 CommonJS AMD CMD UMD 规范的差异总结
一.CommonJS 主要是用于服务器端的规范,比如目前的nodeJS. 根据CommonJS规范,一个单独的文件就是一个模块.每一个模块都是一个单独的作用域,也就是说,在一个文件定义的变量(还包括函 ...
- 关于 CommonJS AMD CMD UMD 规范的差异总结(转)
根据CommonJS规范,一个单独的文件就是一个模块.每一个模块都是一个单独的作用域,也就是说,在一个文件定义的变量(还包括函数和类),都是私有的,对其他文件是不可见的. // foo.js var ...
- JS模块之AMD, CMD, CommonJS、UMD和ES6模块
CommonJS 传送门 同步加载,适合服务器开发,node实现了commonJS.module.exports和require 判断commonJS环境的方式是(参考jquery源码): if ( ...
- AMD,CMD.CommonJs和UMD还有es6的模块化对比
CommonJS CommonJS是服务器端模块的规范,Node.js采用了这个规范. 根据CommonJS规范,一个单独的文件就是一个模块.加载模块使用require方法,该方法读取一个文件并执行, ...
- AMD CMD commonJS es6
看到很多人傻傻的分不清楚 AMD.CMD . commonJS . es6的区别,实际上这跟这几年前段技术的发展有很大的关系. 实际上这是JavaScript的模块化思想演进的一个过程. 最开始的时候 ...
- 把自己的js模块兼容到AMD CMD CommonJS
为了让同一个模块可以运行在前后端,在写作过程中需要考虑兼容前端也实现了模块规范的环境.为了保持前后端的一致性,类库开发者需要将类库代码包装在一个闭包内.以下代码演示如何将hello()方法定义到不同的 ...
随机推荐
- 201871010118-唐敬博《面向对象程序设计(java)》第十六周学习总结
博文正文开头格式:(2分) 项目 内容 这个作业属于哪个课程 <https://www.cnblogs.com/nwnu-daizh/> 这个作业的要求在哪里 <https://ww ...
- web-程序逻辑问题
题目 查看源码 http://ctf5.shiyanbar.com/web/5/index.txt 代码如下 <html> <head> welcome to simplexu ...
- java环境变量和查看安装路径
java环境变量和查看安装路径一:先说windows查看安装路径和版本吧: set java_home:查看JDK安装路径 java -version:查看JDK版本 linux下查看: wherei ...
- 通过Socket实现TCP编程(十二)
原文链接:https://www.cnblogs.com/hysum/p/7531529.html Socket通信 : TCP协议是面向对象连接.可靠的.有序的,以字节流的方式发送数据. 基于TCP ...
- MDK快速定位硬件异常位置方法(移植SEGGER_HardFaultHandler库),调用show caller code即可快速锁定(参考硬汉哥)
今天网上看到keil中如果快速定位hardfault的方法参考如下说明:1. MDK的硬件异常分析主要是通过MDK调试状态进行分析的. 文档下载 apnt209.pdf (651 KB, 下载次数: ...
- 清北学堂(2019 5 2) part 5
今天讲图论,顺便搞一搞之前没弄完的前向星dij 1.图的基本概念(课件原话): G (图)= (V(点); E(边)) 一般来说,图的存储难度主要在记录边的信息 无向图的存储中,只需要将一条无向边拆成 ...
- [LeetCode] 834. Sum of Distances in Tree 树中距离之和
An undirected, connected tree with N nodes labelled 0...N-1 and N-1 edges are given. The ith edge co ...
- [LeetCode] 767. Reorganize String 重构字符串
Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...
- [LeetCode] 119. Pascal's Triangle II 杨辉三角之二
Given a non-negative index k where k ≤ 33, return the kth index row of the Pascal's triangle. Note t ...
- 【操作系统之十四】iptables扩展模块
1.iprange 使用iprange扩展模块可以指定"一段连续的IP地址范围",用于匹配报文的源地址或者目标地址.--src-range:匹配报文的源地址所在范围--dst-ra ...