什麼是模塊化開發?
一個模塊就是實現特定功能的文件,有了模塊,我們就可以更方便地使用別人的代碼,想要什麼功能,就加載什麼模塊。模塊開發需要遵循一定的規範,否則就都亂套了。
在模塊化開發思想下,所有單獨存在的某一個文件都是一個模塊。
CommonJS
CommonJS是服務器端模塊的規範,Node.js採用了這個規範。Node.JS首先採用了js模塊化的概念。
根據CommonJS規範,一個單獨的文件就是一個模塊。
輸出模塊:module.exports
輸入模塊:module.imports
AMD
AMD是一個在瀏覽器端模塊化開發的規範。模塊將被異步加載,模塊加載不影響後面語句的運行。所有依賴某些模塊的語句均放置在回調函數中。
優點:異步並行加載,在AMD的規範下,同時異步加載是不會產生錯誤的。
目前,實現AMD的庫有RequireJS 、curl 、Dojo 、Nodules 等。
定義模塊:
AMD規範只定義了一個函數 define,它是全局變量。函數的描述爲:
define(id?, dependencies?, factory);
id:指定義中模塊的名字,可選;
dependencies:依賴參數,可選的,如果忽略,它默認爲["require", "exports", "module"]。
Factory:模塊初始化要執行的函數或對象。如果爲函數,它應該只被執行一次。如果是對象,此對象應該爲模塊的輸出值。
例(config.js):
require.config({
baseUrl:'js/',
paths:{
'jquery':'jquery-3.1.1',
'index':'index'
}
});
(index.js)
function show() {
console.log("hello");
}
引用模塊:
引入require.js文件
require.js中文網:http://www.requirejs.cn/docs/download.html
<script src="js/require.js" data-main="js/config"></script>
data-main:引入定義的模塊
在引入require.js後使用模塊:
<script>
require(['index'],function () {
show();
})
</script>
運行在瀏覽器上,會打印出hello
required.js就是爲了解決這兩個問題而誕生的:
1.實現js文件的異步加載,避免網頁失去響應;
2.管理模塊之間的依賴性,便於代碼的編寫和維護。
CMD
CMD(Common Module Definition)通用模塊定義。該規範是在國內發展出來的。
在 CMD 規範中,一個模塊就是一個文件。代碼的書寫格式如下:
define(factory);
factory 爲函數時,表示是模塊的構造方法。執行該構造方法,可以得到模塊向外提供的接口。factory 方法在執行時,默認會傳入三個參數:require、exports 和 module:
define(function(require, exports, module) {
// 模塊代碼
});
導出模塊:export
導入模塊:require
CMD規範地址:https://github.com/seajs/seajs/issues/242
Common.js,AMD,CMD的對比
RequireJS和common.js的三大區別:
1.Required.Js運行在瀏覽器上(客戶端),CommonJS設計的時候沒有考慮瀏覽器,所以它不適合瀏覽器環境,運行在服務器上
2.執行順序不一樣,common自動生成依賴關係,RequireJS手動執行依賴關係
3.Require.js主要提供define和require兩個方法來進行模塊化編程
commonJs通過module.imports, module.exports來進行模塊化編程
AMD和CMD的區別:
1.AMD 是 RequireJS 在推廣過程中對模塊定義的規範化產出。
CMD 是 SeaJS 在推廣過程中對模塊定義的規範化產出。
2.對於依賴的模塊
AMD:提前執行(異步加載:依賴先執行)+延遲執行
CMD:延遲執行(運行到需加載,根據順序執行)
3.CMD 推崇依賴就近,AMD 推崇依賴前置。看如下代碼:
// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此處略去 n 行
var b = require('./b') // 依賴可以就近書寫
b.doSomething()
// ...
})
// AMD 默認推薦的是
define(['./a', './b'], function(a, b) { // 依賴必須一開始就寫好
a.doSomething()
// 此處略去 n 行
b.doSomething()
...
})
4. AMD:API根據使用範圍有區別,但使用同一個api接口
CMD:每個API的職責單一
SeaJS與RequireJS的區別:
SeaJS對模塊的態度是懶執行, 而RequireJS對模塊的態度是預執行