淺析JS模組規範:AMD和CMD
阿新 • • 發佈:2019-01-27
在瞭解
簡單的說,一個模組就是實現特定功能的檔案,有了模組,我們就可以更方便地使用別人的程式碼,想要什麼功能,就載入什麼模組。當然,模組開發需要遵循一定的規範,否則各用各的就會亂套了。
目前,常用的JS模組規範主要有兩種: ,它是全域性變數。用法:
在上面的程式碼中,我們引入了require.js,然後使用
CMD
在
商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
原文: http://ghmagical.com/article/page/id/N7VY7Hg4TlgW © ghmagical.com
AMD
,CMD
規範前,我們先來簡單地瞭解下什麼是模組?簡單的說,一個模組就是實現特定功能的檔案,有了模組,我們就可以更方便地使用別人的程式碼,想要什麼功能,就載入什麼模組。當然,模組開發需要遵循一定的規範,否則各用各的就會亂套了。
目前,常用的JS模組規範主要有兩種:
CMD
和AMD
。
AMD
AMD
,非同步模組定義(Asynchronous
Module Definition),它是依賴前置 (依賴必須一開始就寫好)會先儘早地執行(依賴)模組 。換句話說,所有的require
都被提前執行(require
可以是全域性或區域性 )。
AMD規範只定義了一個函式 define
defind(id, dependencies, factory)
引數說明:
id
:字串型別,指定義中模組的名稱,可選。如果沒有提供該引數,模組的名稱應該預設為模組載入器請求的指定指令碼的名稱。如果提供了該引數,模組名必須是“頂級”的和絕對的(不允許相對名稱)。dependencies
:array型別,包含一組當前模組依賴的,已被模組定義的模組標識。
["require", "exports", "module"]
。然而,如果工廠方法的長度屬性小於3,載入器會選擇以函式的長度屬性指定的引數個數呼叫工廠方法。
factory
模組名是用正斜槓分割的有意義單詞的字串
單詞須為駝峰形式,或者".",".."
模組名不允許副檔名的形式,如“.js”
模組名可以為 "相對的" 或 "頂級的"。如果首字元為“.”或“..”則為相對的模組名
頂級的模組名從根名稱空間的概念模組解析
相對的模組名從 "require" 書寫和呼叫的模組解析
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>AMD</title> </head> <body> <script data-main="scripts/main" src="require.js"></script> </body> </html>
在上面的程式碼中,我們引入了require.js,然後使用
data-main
屬性指定入口檔案為scripts/main(這裡省略字尾.js)。
然後在index.html同級下建立一個資料夾scripts,跟著建立三個js檔案:a.js、b.js、mian.js,程式碼如下:
/*
* a.js
* 建立一個名為“a”的模組
*/
define('a', function(require, exports, module) {
exports.getTime = function() {
return new Date();
}
});
/*
* b.js
* 建立一個名為“b”的模組,同時使用依賴require、exports和名為“a”的模組:
*/
define('b', ['require', 'exports', 'a'], function(require, exports, a) { exports.test = function() {
return {
now: a.getTime()
};
}
});
/* main.js */
require(['b'], function(b) {
console.log(b.test());
});
CMD
CMD
(Common Module Definition)更貼近 CommonJS Modules/1.1
和 Node Modules 規範,一個模組就是一個檔案;它推崇依賴就近,想什麼時候 require
就什麼時候載入,實現了懶載入(延遲執行 ) ;它也沒有全域性 require, 每個API都簡單純粹 。在
CMD
規範中,一個模組就是一個檔案。程式碼的書寫格式如下:
define(factory);
factory 為函式時,表示是模組的構造方法。執行該構造方法,可以得到模組向外提供的介面。factory 方法在執行時,預設會傳入三個引數:require、exports 和 module
:
define(function(require, exports, module) {
// 模組程式碼
});
簡單例項:
建立一個index.html,內容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CMD</title>
</head>
<body>
<script src="sea.js"></script>
<script>
/* 載入入口模組 */
seajs.use('./scripts/main');
</script>
</body>
</html>
然後在index.html同級下建立一個scripts資料夾,跟著建立兩個js檔案:a.js、main.js,程式碼如下:
/*
* a.js
* 一個檔案就是一個模組
*/
define(function(require, exports, module) {
exports.getTime = function() {
return new Date();
}
});
/* main.js */
define(function(require, exports, module) {
/* 按需載入a.js */
var a = require('./a');
console.log(a.getTime());
});
RequireJS和Sea.js
的共同點:
- RequireJS 和 Sea.js 都是模組載入器
- 定位有差異。RequireJS 想成為瀏覽器端的模組載入器,同時也想成為 Rhino / Node 等環境的模組載入器。Sea.js 則專注於 Web 瀏覽器端,同時通過 Node 擴充套件的方式可以很方便跑在 Node 環境中。
- 遵循的規範不同。RequireJS 遵循 AMD(非同步模組定義)規範,Sea.js 遵循 CMD (通用模組定義)規範。規範的不同,導致了兩者 API 不同。Sea.js 更貼近 CommonJS Modules/1.1 和 Node Modules 規範。
- 推廣理念有差異。RequireJS 在嘗試讓第三方類庫修改自身來支援 RequireJS,目前只有少數社群採納。Sea.js 不強推,採用自主封裝的方式來“海納百川”,目前已有較成熟的封裝策略。
- 對開發除錯的支援有差異。Sea.js 非常關注程式碼的開發除錯,有 nocache、debug 等用於除錯的外掛。RequireJS 無這方面的明顯支援。
- 外掛機制不同。RequireJS 採取的是在原始碼中預留介面的形式,外掛型別比較單一。Sea.js 採取的是通用事件機制,外掛型別更豐富。
AMD
:依賴前置,預執行(非同步載入:依賴先執行)。CMD
:依賴就近,懶(延遲)執行(執行到需載入,根據順序執行)
// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething();
// 省略1萬行
var b = require('./b') // 依賴可以就近書寫
b.doSomething();
})
// AMD 預設推薦的是
define(['./a', './b'], function(a, b) { // 依賴必須一開始就寫好
a.doSomething();
// 省略1萬行
b.doSomething();
})
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
原文: http://ghmagical.com/article/page/id/N7VY7Hg4TlgW © ghmagical.com