[JavaScript] AMD和CMD概述
1. cmd 和 amd
在浏览器中,受网络和浏览器渲染的制约,不能采用同步加载,只能采用异步加载。于是 AMD 规范应运而生
2. AMD
AMD(Asynchronous Module Definition),意思就是"异步模块定义"。它采用异步方式加载模块,制定了定义模块的规则,这样模块和模块的依赖可以被异步加载,不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。这和浏览器的异步加载模块的环境刚好适应(浏览器同步加载模块会导致性能、可用性、调试和跨域访问等问题)
2.1 define 函数定义模块
本规范只定义了一个函数 "define",它是全局变量 define(id?, dependencies?, factory),参数分别是模块名,依赖,工厂方法
2.2 require(module,callback)加载模块
- 引入 require.js
<script type=”text/javascript” defer async=”true” src=”./require.js”></script>
<script type=”text/javascript” defer async=”true” src=”js/init.js”></script>
- init.js
//require.config 主要是用来对要加载文件的目录进行自定义
require.config({
baseUrl: 'js',
paths: {
"jquery": "../lib/jquery",
"undersocre": "../lib/underscore",
}
})
require(['jquery', 'underscore'], function ($, _) {
$(window).resize(function () {
var color = ["rgba(", Math.floor(Math.random() * 255), ",", Math.floor(Math.random() * 255), ",", Math.floor(Math.random() * 255), ")"];
$(".background").css({
position: "fixed",
top: "0px",
bottom: "0px",
left: "0px",
right: "0px",
background: color.join("")
});
})
});
第一个参数是一个数组,值是依赖的模块。回调事件会在所有依赖模块加载完毕后才会执行
2.3 预加载,在定义模块的时候就提前加载好所有模块
3. CMD
该规范解决的浏览器环境下如何编写代码实现模块化,该规范定义可模块的一些遵循的特征,来支持能共用的模块
- 模块单一文件
- 不应引入模块作用域范围内的新的自由变量
- 懒加载
3.1 模块定义
define(factory)定义模块
- define 函数接受一个参数作为模块工厂
- factory 可以是一个函数或者其他有效值
- 如果 factory 是一个函数,回调函数中会指定三个参数 require,exports,module
- 如果个 factory 不是一个函数(对象,字符串),这是模块的接口就是当前对象,字符串
define(function(require, exports, module) {
// do something
});
3.2 require
- require 函数接收一个模块标识符(模块标识符也叫模块 id)。
- require 函数返回外部模块的导出 API(”导出 API“是用来导出内容给外部模块使用的)。
- 如果无法返回请求的模块, require 函数将返回 null。
3.3 require.async
- require.async 接收一个模块 Id 列表和一个可选的回调函数。
- 回调函数接收模块导出作为函数参数,按照与第一个参数中的顺序相同的顺序列出。
- 如果不能返回请求的模块,则回调应该相应地收到 null。
3.4 exports 对象
每个模块中都有个名叫"exports"的自由变量,这是一个模块可以在模块执行时添加模块 API 的对象。
3.5 module 对象
- module.uri:完整解析的模块 URI(模块 URI 的全路径)。
- module.dependencies:模块请求的标识符(模块 id)列表。
- module.exports:模块的导出 API(”导出 API“是”用来导出什么东西的 API“)。 它与 export 对象相同。
3.6 模块标识符(模块 id)
- 模块的标识符(模块 id)必须是字面量字符串。
- 模块标识符(模块 id)不能有类似 .js 的文件名扩展。
- 模块标识符(模块 id)应该是加前/后缀的字符串,比如:foo-bar。
- 模块标识符(模块 id)可以是相对路径,例如: ./foo 和 ../bar.。
懒加载,在 require 时候才会加载模块
3.7 一个简单的示例(seajs)
这是 seajs 对象上绑定的属性和方法

color.js
define("color", function(require, exports, module) {
var \$ = require("jquery");
var createColor = function() {
return ["rgba(", Math.floor(Math.random() * 255), ",", Math.floor(Math.random() * 255), ",", Math.floor(Math.random() * 255), ")"];
};
module.exports = {
changeBg: function() {
\$("#bg").css({
position: "fixed",
top: "0px",
bottom: "0px",
left: "0px",
right: "0px",
background: createColor().join("")
});
}
};
});
使用非函数的工厂包装模块 text.js
define({
text: "我是初始化程序",
text2: "我要开始执行了"
});
init.js
define("init", function(require, exports, module) {
var color = require("../src/color");
var initText = require("../src/text");
var \$ = require("jquery");
module.exports = {
start: function() {
console.log(initText.text + "," + initText.text2);
$(function() {
$("#change").click(function() {
color.changeBg();
});
});
}
};
});
sea.js.html
...
<body id="bg">
<button id="change">点我我变色</button>
</body>
<script src="./lib/sea.js"></script>
<script>
seajs.config({
alias: {
underscore: "underscore.js",
init: "./src/init.js",
color: "./src/color.js"
}
});
seajs.use(["underscore", "init"], function(u, init) {
init.start();
});
</script>
...
目录结构

3.8 seajs 引入其他插件或库
一般控制台报错 xxx is not a function
一些库不支持模块引入或者只支持 amd 规范的引入方式,不支持 cmd。所有需要对库进行一些改造
//Underscore.js 1.9.1
if (typeof define === "function" && define.amd && define.amd.jQuery) {
define("underscore", [], function() {
return \_;
});
}
//更改如下
if (typeof define === "function" && (define.amd || define.cmd)) {
define("underscore", [], function() {
return _;
});
}
//或者整个 define 的判断不要了
if (typeof define === "function") {
define("underscore", [], function() {
return _;
});
}
UMD
是一种思想,就是一种兼容 commonjs,AMD,CMD 的兼容写法,define.amd / define.cmd / module 等判断当前支持什么方式,都不行就挂载到 window 全局对象上面去
(function (root, factory) {
if (typeof define === 'function' && (define.amd || define.cmd)) {
//AMD,CMD
define(['b'], function(b){
return (root.returnExportsGlobal = factory(b))
});
} else if (typeof module === 'object' && module.exports) {
//Node, CommonJS之类的
module.exports = factory(require('b'));
} else {
//公开暴露给全局对象
root.returnExports = factory(root.b);
}
}(this, function (b) {
return {};
}));
[JavaScript] AMD和CMD概述的更多相关文章
- JavaScript AMD 与CMD的代码区别
1:CMD 依赖就近 define(function(require,export) { var b =1; var a = require("../a"); a.dosometh ...
- 【整理】 JavaScript模块化规范AMD 和 CMD 的区别有哪些?
根据玉伯等人在知乎上的回答整理.整理中... AMD 规范在这里:https://github.com/amdjs/amdjs-api/wiki/AMD CMD 规范在这里:https://githu ...
- 该如何理解AMD ,CMD,CommonJS规范--javascript模块化加载学习总结
是一篇关于javascript模块化AMD,CMD,CommonJS的学习总结,作为记录也给同样对三种方式有疑问的童鞋们,有不对或者偏差之处,望各位大神指出,不胜感激. 本篇默认读者大概知道requi ...
- JavaScript模块化 --- Commonjs、AMD、CMD、es6 modules
随着前端js代码复杂度的提高,JavaScript模块化这个概念便被提出来,前端社区也不断地实现前端模块化,直到es6对其进行了规范,下面就介绍JavaScript模块化. 这篇文章还是希望能给大家一 ...
- JavaScript中的模块化之AMD和CMD
前言: 为什么我们需要模块化开发,模块化开发的好处有哪些? 首先我们先说一下非模块化的开发方式带来的弊端. 非模块化开发中会导致一些问题的出现,变量和函数命名可能相同,会造成变量污染和冲突,并且出错时 ...
- javascript模块化之CommonJS、AMD、CMD、UMD、ES6
javascript模块化之CommonJS.AMD.CMD.UMD.ES6 一.总结 一句话总结: CommonJS是同步加载模块,用在服务端:AMD是异步加载模块,用于浏览器端 1.为什么服务器端 ...
- JavaScript模块化思想之CommonJS、AMD、CMD、UMD
前一篇文章了解了什么是模块,这一篇就简单介绍一下如何定义并加载一个模块. 我所了解的三种模块加载方式分别是CommonJS.AMD和CMD 网上关于这三种模块加载方式讲解的文章很多,我就简单的做个介绍 ...
- JavaScript模块化-CommonJS、AMD、CMD、UMD、ES6
前言:模块化开发需求 在JS早期,使用script标签引入JS,会造成以下问题: 加载的时候阻塞网页渲染,引入JS越多,阻塞时间越长. 容易污染全局变量. js文件存在依赖关系,加载必须有顺序.项目较 ...
- AMD与CMD(转载)
JavaSript模块化 在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发? 模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问题 ...
随机推荐
- 【Java】运用泽勒一致性计算某天是星期几
/** * Created by liangjiahao on 2017/2/26. * 运用泽勒一致性计算某天是星期几? * 公式: * h = (q + 26(m+1)/10 + k +k/4 + ...
- C语言 > 指向指针的指针
Int **pt; 一个指向指针的指针: { int ** pt; //一个指向指针的指针; int *ppt; ; ppt = &a; pt = &ppt; printf(" ...
- 利用Swagger2自动生成对外接口的文档
一直以来做对外的接口文档都比较原始,基本上都是手写的文档传来传去,最近发现了一个新玩具,可以在接口上省去不少麻烦. swagger是一款方便展示的API文档框架.它可以将接口的类型最全面的展示给对方开 ...
- Hadoop平台基本组成
1.Hadoop系统运行于一个由普通商用服务器组成的计算集群上,能提供大规模分布式数据存储资源的同时,也提供了大规模的并行化计算资源. 2.Hadoop生态系统 3.MapReduce并行计算框架 M ...
- CentOS6.7 mysql5.6.33修改数据文件位置
问题:mysql存放的数据文件,分区容量较小,目前已经满,导致mysql连接不上, 解决方案: 1.删除分区里一个不需要用的数据,如:日志文件等(解决不了根本问题) 2.对某个磁盘扩容 3.修改数据存 ...
- xinetd被动服务唤醒
rsync设置: 1.打开rsync控制开关(修改文件 /etc/default/rsync)2.sudo cp /usr/share/doc/rsync/examples/rsyncd.conf / ...
- 开源RPC(gRPC/Thrift)框架性能评测
海量互联网业务系统只能依赖分布式架构来解决,而分布式开发的基石则是RPC:本文主要针对两个开源的RPC框架(gRPC. Apache Thrift),以及配合GoLang.C++两个开发语言进行性能对 ...
- 25.创业真的需要app吗?真的需要外包吗?
两个星期前,一名亲戚的朋友打算投入自己的二十多万元去搞个摄影社交app,问我有没有靠谱的外包推荐,我赶紧劝住他,现在app的成本已经非常高了,初期的研发就要十几万,加上后期的推广(每个用户成本大概2元 ...
- 最短寻道优先算法----SSTF算法
请珍惜小编劳动成果,该文章为小编原创,转载请注明出处. 该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短 java代码实现如下: import java.ut ...
- Python3 venv 创建虚拟环境
简介 Python3.3以上的版本通过venv模块原生支持虚拟环境,可以代替Python之前的virtualenv. 该venv模块提供了创建轻量级"虚拟环境",提供与系统Pyth ...