了解前端模块化系列内容:
三、了解前端模块化系列(1)——模块化的理解
三、了解前端模块化系列(2)——模块化规范-CommonJS
三、了解前端模块化系列(3)——模块化规范-AMD
三、了解前端模块化系列(4)——模块化规范-CMD & ES6
三、了解前端模块化系列(5)——模块化规范-UMD & 总结(CommonJS AMD CMD ES6 UMD)
三、模块化规范
3.2 AMD(Asynchronous Module Definition)
3.2.1 概念
| 规范 | 加载模块方式 | 含义 | 例子 | 时间 |
|---|---|---|---|---|
| CommonJS 规范 | 同步加载模块 | 加载完成,执行后面 | 服务器编程 Node.js,本地硬盘已存在模块文件,加载块,不考虑非同步加载方式,适用 CommonJS | |
| AMD 规范 | 非同步加载模块 | 允许指定回调函数 | 浏览器环境,从服务器端加载模块,非同步模式,浏览器端一般 AMD 规范 | AMD 规范早于 CommonJS 在浏览器端实现 |
3.2.2 基本语法
-
定义暴露模块(无依赖/有依赖):
//定义没有依赖的模块 define(function () { return 模块 }) //定义有依赖的模块 define(['module1', 'module2'], function (m1, m2) { return 模块 }) -
引入使用模块:
require(['module1', 'module2'], function (m1, m2) { 使用m1 / m2 })
3.2.3 AMD 实现(AMD 实际使用效果)
1.未使用 AMD 规范(未使用 require.js)
缺点:
- 发送多个请求
- 按顺序引入 js,否则报错。
dataService.js
;(function (window) {
// 【IIFE模式】【1.作用】——①数据私有
let msg = 'www.xianzao.com'
// 【IIFE模式】【2.编码】——①函数内部封装:**数据**&行为
function getMsg() {
return msg.toUpperCase()
}
// 【IIFE模式】【2.编码】——②window添加属性,向外暴露接口
window.dataService = { getMsg }
})(window) // 【IIFE模式】【3.bug】——当前模块依赖另一个模块,怎么办?
alerter.js
;(function (window, dataService) {
// 【IIFE模式】【1.作用】——①数据私有
let name = 'xianzao'
// 【IIFE模式】【2.编码】——①函数内部封装:**数据**&行为
function showMsg() {
// 【IIFE模式】【1.作用】——②外部只能通过暴露方法操作
alert(dataService.getMsg() + ', ' + name)
}
// 【IIFE模式】【2.编码】——②window添加属性,向外暴露接口
window.alerter = { showMsg }
})(window, dataService) // 【IIFE模式增强】库当作参数传入
main.js
;(function (alerter) {
// 【IIFE模式】【1.作用】——②外部只能通过暴露方法操作
alerter.showMsg()
})(alerter) // 【IIFE模式增强】库当作参数传入
index.html
- 注意:按顺序引入 dataService.js,alerter.js,main.js
<div><h1>1.未使用 AMD 规范(未使用 require.js)</h1></div>
<p>注意:按顺序引入 dataService.js,alerter.js,main.js</p>
<script type="text/javascript" src="js/modules/dataService.js"></script>
<script type="text/javascript" src="js/modules/alerter.js"></script>
<script type="text/javascript" src="js/main.js"></script>
弹框展示,输出结果:
WWW.XIANZAO.COM, xianzao
2.使用 AMD 规范(使用 require.js)
RequireJS 工具库:
- 管理客户端模块
- 遵循 AMD 规范
RequireJS 基本思想:
- define 定义模块
- require 加载模块
AMD 规范(RequireJS)在浏览器实现的步骤:
-
下载
require.js-V2.3.6&require.min.js-V2.3.6,并引入。 -
创建项目结构
|-js |-libs |-jquery |-2.0.0 |-jquery.min.js |-requirejs |-2.3.6 |-require.js |-require.min.js |-modules |-alerter.js |-dataService.js |-main.js |-index.html -
定义 modules 目录下的模块代码
js/modules/dataService.js
// dataService.js文件 // 定义没有依赖的模块 define(function () { let msg = 'www.djsz3y.xyz' function getMsg() { return msg.toUpperCase() } return { getMsg } // 暴露模块 })js/modules/alerter.js
- 没引入第三方模块前——alerter.js
//alerter.js文件 // 定义有依赖的模块 define(['dataService'], function (dataService) { // define(["dataService", "jquery"], function (dataService, $) { let name = 'djsz3y' function showMsg() { alert(dataService.getMsg() + ', ' + name) } // $("body").css("background", "yellowgreen"); // 暴露模块 return { showMsg } })js/main.js
- 没引入第三方模块前——main.js
// main.js文件 ;(function () { require.config({ baseUrl: 'js/', //基本路径 出发点在根目录下 paths: { // 自定义模块——映射: 模块标识名: 路径 alerter: './modules/alerter', //此处不能写成alerter.js,会报错 dataService: './modules/dataService' // // 第三方库模块 // jquery: "./libs/jquery/2.0.0/jquery.min", //注意:写成jQuery会报错 } }) require(['alerter'], function (alerter) { alerter.showMsg() }) })()index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Modular Demo(AMD-RequireJS)</title> </head> <body> <!-- 引入require.js并指定js主文件的入口 --> <script data-main="js/main" src="js/libs/requirejs/2.3.6/require.js" ></script> </body> </html> -
引入第三方库:
在 alerter.js 文件中引入 jQuery 第三方库,main.js 文件也要有相应的路径配置。
-
修改
alerter.js修改:js/modules/alerter.js
// alerter.js文件 // 定义有依赖的模块 define(['dataService', 'jquery'], function (dataService, $) { // ... // ... $('body').css('background', 'yellowgreen') // ... }) -
修改
main.js添加两行
-
一行注释,
-
一行映射 jquery
修改:js/main.js
// main.js文件 ;(function () { require.config({ baseUrl: 'js/', //基本路径 出发点在根目录下 paths: { // 自定义模块——映射: 模块标识名: 路径 alerter: './modules/alerter', //此处不能写成alerter.js,会报错 dataService: './modules/dataService', ++++++// 第三方库模块 ++++++jquery: './libs/jquery/2.0.0/jquery.min' //注意:写成jQuery会报错 } }) require(['alerter'], function (alerter) { alerter.showMsg() }) })() -
-
-
效果:
- 未引入第三方模块前:
- 弹框展示结果:
WWW.DJSZ3Y.XYZ, djsz3y
- 弹框展示结果:
- 引入第三方模块后:
- 弹框展示结果:
WWW.DJSZ3Y.XYZ, djsz3y - 并且 body 背景变为黄绿色。
- 弹框展示结果:
- 未引入第三方模块前:
-
测试:
- 确实
js/main.js,alerter&dataService模块引入顺序不分先后 - 很快
- 确实
3.2.4 总结
AMD 规范:
- 定义方法清晰,不污染全局环境,依赖关系清楚。
- 可用于浏览器环境,
非同步、按需动态加载模块。