寫在前面
AMD是"Asynchronous Module Definition"的縮寫,意思就是"異步模塊定義"。目前,主要有兩個Javascript庫實現了AMD規範:require.js 和 curl.js。這裏介紹 require.js。既然是模塊,就涉及到兩個通用的問題:1. 模塊如何定義。2. 模塊如何加載。
定義模塊
在 require.js 中,定義一個模塊的方式為:
define(callback)
// or
define([...modules], callback)
可以看出,在引入了 require.js 之後,全局提供了一個 define 函數,用於模塊的定義。當 define 函數只接收到一個參數時,該參數為該模塊的回調函數,在模塊被加載時調用,函數的返回值即作為該模塊的導出值。當 define 函數接收到兩個參數時,第一個參數為該模塊的依賴數組,第二個函數為該模塊的回調函數,函數的參數依次為依賴數組的每一項。函數的返回值為該模塊的導出值。
由模塊定義的方式可以看出,define 函數並未提供定義模塊名字的位置,那怎麼唯一定義這個模塊的名字呢?引用這個模塊時的名字是什麼呢?答案是文件名。
require.js要求,每個模塊是一個單獨的js文件。
加載模塊
在 require.js 中,加載一個模塊的方式為:
require([...modules], callback)
require 函數的第一個參數為要加載的模塊,第二個函數為回調函數,在前面的模塊加載完成後會調用回調函數,並將加載的模塊的返回值依次傳遞給回調函數。
示例
下面以在瀏覽器項目中引用 require.js 為例展示其用法。項目結構如下:
1⃣️ 瀏覽器中引入 require.js
需要用 data-main 屬性指明 require.js 的入文件,即主程序。
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Amd test</title>
</head>
<body>
<script data-main="js/main.js" src="https://cdn.bootcdn.net/ajax/libs/require.js/2.3.6/require.min.js"></script>
</body>
</html>
2⃣️ 定義 a 模塊和 b 模塊
// a.js
define(function() {
return {
sayHi: function() {
console.log('我是 A 模塊!');
}
}
})
// b.js
define(['a'], function(a) {
return {
sayHi: function() {
console.log('我是 B 模塊!');
a.sayHi()
}
}
})
3⃣️ 定義主模塊,main.js
模塊名即為文件名,當文件名不加後綴js的時候,文件路徑默認與main.js在同一個目錄。當文件名加後綴js的時候,文件路徑默認為項目根目錄。(這種現象為實踐得到)
// main.js
require(['a', 'b'], function(a, b) {
a.sayHi()
b.sayHi()
})
在瀏覽器運行如下:
參考文章
Javascript模塊化編程(一):模塊的寫法
Javascript模塊化編程(二):AMD規範
Javascript模塊化編程(三):require.js的用法