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. Flask入门之Virtualvenv的安装及使用(windows)

    Virtualvenv 提供一个特定的Python虚拟环境(沙盒),以便于那些要求特定版本的模块的脚本能够顺利运行. 因为在Virtualvenv中,我们可以使用 pip install -r req ...

  2. Java并发之ReentrantLock

    一.ReentrantLock简介 ReentrantLock字面意义上理解为可重入锁.那么怎么理解可重入这个概念呢?或者说和我们经常用的synchronized又什么区别呢? ReentrantLo ...

  3. Python_csv电子表格

    import csv with open('test.csv','w',newline='')as fp: test_writer=csv.writer(fp,delimiter=' ',quotec ...

  4. 读《图解HTTP》有感-(HTTP首部)

    写在前面 该章节是对请求报文及响应报文的首部信息进行解析.通过该章节的学习,相信大家对首部结构,及各个首部字段的作用有个基本的了解 正文 HTTP报文由HTTP报文首部.空行以及HTTP报文主体组成. ...

  5. MyBatis xml配置文件详解

    http://blog.csdn.net/fenghuibian/article/details/52525671

  6. Java NIO Channel to Channel Transfers通道传输接口

    原文链接:http://tutorials.jenkov.com/java-nio/channel-to-channel-transfers.html 在Java NIO中如果一个channel是Fi ...

  7. maven重新导入,不能拉到最新jar包的问题

    需要删除本地jar,再重新reimport  pom.xml

  8. 对JDK的深入理解

    今天对Java的jdk有了更加深入的理解: Java的jdk其实一共包含三部分内容: 1.工具包 2.类库 3.JRE jdk的全名:Java develop kit (java开发工具) jdk包含 ...

  9. jenkins+gitlab自动化编译部署方案探索及服务端编译webpack实战

    一. 背景 之前我们的开发流程为在本地进行webpack打包编译,然后svn提交源代码和编译后的代码.同时每次提交前也会从svn更新源代码和编译后的代码.这样做有几个缺点: 1. svn 更新和提交编 ...

  10. 浅析mydumper

    Ⅰ.背景 mysqldump单线程备份,很慢 恢复慢,一张表一张表恢复, 如果备份了100G的数据,想恢复其中一个表,做不到(所有的表都在一个文件里) 所以推荐使用mydumper备份 备份并行,基于 ...