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

该规范解决的浏览器环境下如何编写代码实现模块化,该规范定义可模块的一些遵循的特征,来支持能共用的模块

  1. 模块单一文件
  2. 不应引入模块作用域范围内的新的自由变量
  3. 懒加载

3.1 模块定义

define(factory)定义模块

  1. define 函数接受一个参数作为模块工厂
  2. factory 可以是一个函数或者其他有效值
  3. 如果 factory 是一个函数,回调函数中会指定三个参数 require,exports,module
  4. 如果个 factory 不是一个函数(对象,字符串),这是模块的接口就是当前对象,字符串

define(function(require, exports, module) {
// do something
});
3.2 require
  1. require 函数接收一个模块标识符(模块标识符也叫模块 id)。
  2. require 函数返回外部模块的导出 API(”导出 API“是用来导出内容给外部模块使用的)。
  3. 如果无法返回请求的模块, require 函数将返回 null。
3.3 require.async
  1. require.async 接收一个模块 Id 列表和一个可选的回调函数。
  2. 回调函数接收模块导出作为函数参数,按照与第一个参数中的顺序相同的顺序列出。
  3. 如果不能返回请求的模块,则回调应该相应地收到 null。

3.4 exports 对象

每个模块中都有个名叫"exports"的自由变量,这是一个模块可以在模块执行时添加模块 API 的对象。

3.5 module 对象

  1. module.uri:完整解析的模块 URI(模块 URI 的全路径)。
  2. module.dependencies:模块请求的标识符(模块 id)列表。
  3. module.exports:模块的导出 API(”导出 API“是”用来导出什么东西的 API“)。 它与 export 对象相同。

3.6 模块标识符(模块 id)

  1. 模块的标识符(模块 id)必须是字面量字符串。
  2. 模块标识符(模块 id)不能有类似 .js 的文件名扩展。
  3. 模块标识符(模块 id)应该是加前/后缀的字符串,比如:foo-bar。
  4. 模块标识符(模块 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概述的更多相关文章

  1. JavaScript AMD 与CMD的代码区别

    1:CMD 依赖就近 define(function(require,export) { var b =1; var a = require("../a"); a.dosometh ...

  2. 【整理】 JavaScript模块化规范AMD 和 CMD 的区别有哪些?

    根据玉伯等人在知乎上的回答整理.整理中... AMD 规范在这里:https://github.com/amdjs/amdjs-api/wiki/AMD CMD 规范在这里:https://githu ...

  3. 该如何理解AMD ,CMD,CommonJS规范--javascript模块化加载学习总结

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

  4. JavaScript模块化 --- Commonjs、AMD、CMD、es6 modules

    随着前端js代码复杂度的提高,JavaScript模块化这个概念便被提出来,前端社区也不断地实现前端模块化,直到es6对其进行了规范,下面就介绍JavaScript模块化. 这篇文章还是希望能给大家一 ...

  5. JavaScript中的模块化之AMD和CMD

    前言: 为什么我们需要模块化开发,模块化开发的好处有哪些? 首先我们先说一下非模块化的开发方式带来的弊端. 非模块化开发中会导致一些问题的出现,变量和函数命名可能相同,会造成变量污染和冲突,并且出错时 ...

  6. javascript模块化之CommonJS、AMD、CMD、UMD、ES6

    javascript模块化之CommonJS.AMD.CMD.UMD.ES6 一.总结 一句话总结: CommonJS是同步加载模块,用在服务端:AMD是异步加载模块,用于浏览器端 1.为什么服务器端 ...

  7. JavaScript模块化思想之CommonJS、AMD、CMD、UMD

    前一篇文章了解了什么是模块,这一篇就简单介绍一下如何定义并加载一个模块. 我所了解的三种模块加载方式分别是CommonJS.AMD和CMD 网上关于这三种模块加载方式讲解的文章很多,我就简单的做个介绍 ...

  8. JavaScript模块化-CommonJS、AMD、CMD、UMD、ES6

    前言:模块化开发需求 在JS早期,使用script标签引入JS,会造成以下问题: 加载的时候阻塞网页渲染,引入JS越多,阻塞时间越长. 容易污染全局变量. js文件存在依赖关系,加载必须有顺序.项目较 ...

  9. AMD与CMD(转载)

    JavaSript模块化   在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发?       模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问题 ...

随机推荐

  1. Java面试官最常问的volatile关键字

    在Java相关的职位面试中,很多Java面试官都喜欢考察应聘者对Java并发的了解程度,以volatile关键字为切入点,往往会问到底,Java内存模型(JMM)和Java并发编程的一些特点都会被牵扯 ...

  2. C#之Redis为所欲为

    一 Redis是一种支持多种数据结构的键值对数据库 1.1Redis下载地址 :https://github.com/MicrosoftArchive/Redis 建议下载 .msi结尾的应用程序进行 ...

  3. C语言 > 指向指针的指针

    Int **pt; 一个指向指针的指针: { int ** pt; //一个指向指针的指针; int *ppt; ; ppt = &a; pt = &ppt; printf(" ...

  4. webpack4:连奏中的进化

    webpack4在2月底的时候发布,这次webpack4有了一个名字"Legato",也就是"连奏"的意思,寓意webpack在不断进化,而且是无缝(no-ga ...

  5. 记录几个经典的字符串hash算法

    记录几个经典的字符串hash算法,方便以后查看: 推荐一篇文章: http://www.partow.net/programming/hashfunctions/# (1)暴雪字符串hash #inc ...

  6. Centos7搭建hadoop完全分布式

    虽然说是完全分布式,但三个节点也都是在一台机器上.拿来练手也只能这样咯,将就下.效果是一样滴.这个我自己都忘了步骤,一起来回顾下吧. 必备知识: Linux基本命令 vim基本命令 准备软件: VMw ...

  7. 微信小程序开发之formId使用(模板消息)

    基于微信小程序的模板消息:基于微信的通知渠道,我们为开发者提供了可以高效触达用户的模板消息能力,以便实现服务的闭环并提供更佳的体验.模板推送位置:服务通知模板下发条件:用户本人在微信体系内与页面有交互 ...

  8. Springboot+JPA+Thymeleaf 校园博客完整小网站

    本文所属[知识林]:http://www.zslin.com/web/article/detail/35 此项目是一个比较简易的校园博客.麻雀虽小五脏俱全,虽然是比较简易的但是涉及的知识点还是比较全面 ...

  9. 关于ArrayList的5道面试题

    我以面试官的身份参加过很多Java的面试,以下是五个比较有技巧的问题,我发现有些初级到中级的Java研发人员在这些问题上没有完全弄明白,似懂非懂.所以我写了一篇相关的文章,帮助初级Java研发人员弄清 ...

  10. 2101: Bake Off

    Description Davy decided to start a weekend market stall where he sells his famous cakes. For the fi ...