[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规范前,还是需要先来简单地了解下什么是模块化,模块化开发? 模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问题 ...
随机推荐
- hadoop HA 详解
NameNode 高可用整体架构概述 在 Hadoop 1.0 时代,Hadoop 的两大核心组件 HDFS NameNode 和 JobTracker 都存在着单点问题,这其中以 NameNode ...
- 连接Access数据遇到的问题总览!
由于要访问一个厂商的access数据,所以要写一个对于access的demo,相对于mysql.sqlserver来说,连接access花费了不少精力,现在将遇到的问题分享出来,以后大家遇到类似问题时 ...
- JavaScript和JQuery的区别
一.本质上的区别 1.JavaScript 是通过<script></script>标签插入到HTML页面,可由所有的现代浏览器执行的一种轻量级的编程语言. 2.JQuery是 ...
- python_日历
>>> import datetime>>> Today=datetime.date.today()>>> Todaydatetime.date( ...
- jq slideToggle()坑
jQuery slideToggle() 方法 jQuery slideToggle() 方法可以在 slideDown() 与 slideUp() 方法之间进行切换. 如果元素向下滑动,则 slid ...
- Tiny4412之按键驱动
一:按键驱动 按键驱动跟之前的LED,蜂鸣器的方法类似:通过底板,核心板我们可以看到按键的电路图: 通过电路图我们可以看出,当按键按下去为低电平,松开为高电平:所以我们要检测XEINT26的状态,通过 ...
- WPF MVVM UI分离之《交互与数据分离》
在我们使用WPF过程中,不可避免并且超级喜欢使用MVVM框架. 那么,使用MVVM的出发点是视觉与业务逻辑分离,即UI与数据分离 诸如下面的问题: 删除操作,假如需要先执行一部分数据的处理,然后删除界 ...
- springboot集成schedule(深度理解)
背景 在项目开发过程中,我们经常需要执行具有周期性的任务.通过定时任务可以很好的帮助我们实现. 我们拿常用的几种定时任务框架做一个比较: 从以上表格可以看出,Spring Schedule框架功能完善 ...
- JAVA API操作hbase1.4.2
package com.quyf; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; imp ...
- 自动化测试用例getText()获取某一个元素的值返回null或空
问题描述 页面上一个元素无法获取它的值. 用getText() 获取该元素的值返回null或空. 根本原因 ? 需要更多了解dom结构 解决办法 用getAttribute("value&q ...