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】运用泽勒一致性计算某天是星期几

    /** * Created by liangjiahao on 2017/2/26. * 运用泽勒一致性计算某天是星期几? * 公式: * h = (q + 26(m+1)/10 + k +k/4 + ...

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

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

  3. 利用Swagger2自动生成对外接口的文档

    一直以来做对外的接口文档都比较原始,基本上都是手写的文档传来传去,最近发现了一个新玩具,可以在接口上省去不少麻烦. swagger是一款方便展示的API文档框架.它可以将接口的类型最全面的展示给对方开 ...

  4. Hadoop平台基本组成

    1.Hadoop系统运行于一个由普通商用服务器组成的计算集群上,能提供大规模分布式数据存储资源的同时,也提供了大规模的并行化计算资源. 2.Hadoop生态系统 3.MapReduce并行计算框架 M ...

  5. CentOS6.7 mysql5.6.33修改数据文件位置

    问题:mysql存放的数据文件,分区容量较小,目前已经满,导致mysql连接不上, 解决方案: 1.删除分区里一个不需要用的数据,如:日志文件等(解决不了根本问题) 2.对某个磁盘扩容 3.修改数据存 ...

  6. xinetd被动服务唤醒

    rsync设置: 1.打开rsync控制开关(修改文件 /etc/default/rsync)2.sudo cp /usr/share/doc/rsync/examples/rsyncd.conf / ...

  7. 开源RPC(gRPC/Thrift)框架性能评测

    海量互联网业务系统只能依赖分布式架构来解决,而分布式开发的基石则是RPC:本文主要针对两个开源的RPC框架(gRPC. Apache Thrift),以及配合GoLang.C++两个开发语言进行性能对 ...

  8. 25.创业真的需要app吗?真的需要外包吗?

    两个星期前,一名亲戚的朋友打算投入自己的二十多万元去搞个摄影社交app,问我有没有靠谱的外包推荐,我赶紧劝住他,现在app的成本已经非常高了,初期的研发就要十几万,加上后期的推广(每个用户成本大概2元 ...

  9. 最短寻道优先算法----SSTF算法

    请珍惜小编劳动成果,该文章为小编原创,转载请注明出处. 该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短 java代码实现如下: import java.ut ...

  10. Python3 venv 创建虚拟环境

    简介 Python3.3以上的版本通过venv模块原生支持虚拟环境,可以代替Python之前的virtualenv. 该venv模块提供了创建轻量级"虚拟环境",提供与系统Pyth ...