1. cmd 和 amd
在浏覽器中,受網絡和浏覽器渲染的制約,不能采用同步加載,隻能采用異步加載。于是 AMD 規範應運而生
2. AMD
AMD(Asynchronous Module Definition),意思就是"異步子產品定義"。它采用異步方式加載子產品,子產品的加載不影響它後面語句的運作。所有依賴這個子產品的語句,都定義在一個回調函數中,等到加載完成之後,這個回調函數才會運作
2.1 define(module,callback)定義子產品,require(module,callback)加載子產品
require(['jquery'],function($){
$("#bg").css({background:'red'});
})
第一個參數是一個數組,值是依賴的子產品。回調事件會在所有依賴子產品加載完畢後才會執行
2.2 預加載,在定義子產品的時候就提前加載好所有子產品
3. CMD
該規範解決的浏覽器環境下如何編寫代碼實作子產品化,該規範定義可子產品的一些遵循的特征,來支援能共用的子產品
- 子產品單一檔案
- 不應引入子產品作用域範圍内的新的***變量
- 懶加載
3.1 子產品定義
define(factory)定義子產品
- define 函數接受一個參數作為子產品工廠
- factory 可以是一個函數或者其他有效值
- 如果 factory 是一個函數,回調函數中會指定三個參數 require,exports,module
- 如果個 factory 不是一個函數(對象,字元串),這是子產品的接口就是目前對象,字元串
define(function(require, exports, module) {
// do something
});
3.2 require
- require 函數接收一個子產品辨別符(子產品辨別符也叫子產品 id)。
- require 函數傳回外部子產品的導出 API(”導出 API“是用來導出内容給外部子產品使用的)。
- 如果無法傳回請求的子產品, require 函數将傳回 null。
3.3 require.async
- require.async 接收一個子產品 Id 清單和一個可選的回調函數。
- 回調函數接收子產品導出作為函數參數,按照與第一個參數中的順序相同的順序列出。
- 如果不能傳回請求的子產品,則回調應該相應地收到 null。
3.4 exports 對象
每個子產品中都有個名叫"exports"的***變量,這是一個子產品可以在子產品執行時添加子產品 API 的對象。
3.5 module 對象
- module.uri:完整解析的子產品 URI(子產品 URI 的全路徑)。
- module.dependencies:子產品請求的辨別符(子產品 id)清單。
- module.exports:子產品的導出 API(”導出 API“是”用來導出什麼東西的 API“)。 它與 export 對象相同。
3.6 子產品辨別符(子產品 id)
- 子產品的辨別符(子產品 id)必須是字面量字元串。
- 子產品辨別符(子產品 id)不能有類似 .js 的檔案名擴充。
- 子產品辨別符(子產品 id)應該是加前/字尾的字元串,比如:foo-bar。
- 子產品辨別符(子產品 id)可以是相對路徑,例如: ./foo 和 ../bar.。
懶加載,在 require 時候才會加載子產品
3.7 一個簡單的示例(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 _;
});
}
Common Module Definition
AMD
require.js 基本使用