什么是模塊化?為什么要模塊化?
命名沖突:為了方便也避免重復(fù)造輪子,我們習(xí)慣于把一些通用的、底層的工具抽離出來,例如寫成一個(gè)函數(shù)放在另一個(gè)文件中,我們需要的時(shí)候再去引用就可以;但是在工具中被定義的變量我不能在當(dāng)前文件使用,因?yàn)闀?huì)產(chǎn)生沖突導(dǎo)致工具無法正常使用。所以我們希望這個(gè)工具能是一個(gè)獨(dú)立的空間,不要影響到當(dāng)前頁面的開發(fā)。
文件依賴:當(dāng)我們?cè)趯懸粋€(gè)新工具的時(shí)候,有可能會(huì)需要調(diào)用其它功能更小的工具;那么在執(zhí)行時(shí)因?yàn)閖s的同步特性,要使用這個(gè)新工具就必須要先加載小工具,也就是說小工具要先于新工具去引入;當(dāng)引入文件較多或者順序亂了之后維護(hù)起來非常困難。
原因:使用模塊化主要是為了解決兩個(gè)問題:命名沖突和文件依賴。
模塊化x命名沖突:用面向?qū)ο蟮姆绞綄⒎椒?、工具綁在?duì)象上;約定用關(guān)鍵字exports暴露接口返回對(duì)象。
模塊化x文件依賴:約定關(guān)鍵字require來獲取對(duì)象將文件依賴內(nèi)置,不需要外部引入。
CMD、AMD、CommonJS 規(guī)范分別指什么?
Common JS:它是一個(gè)規(guī)范,它通過定義豐富的能解決一些通常的應(yīng)用開發(fā)需求的API來補(bǔ)足了js官方關(guān)于標(biāo)準(zhǔn)庫的不足。建立它的意圖是希望開發(fā)者可以運(yùn)用這些API去開發(fā)應(yīng)用,而且所開發(fā)的應(yīng)用能夠在不同的js環(huán)境中運(yùn)行而不僅僅是瀏覽器。服務(wù)器端的javascript應(yīng)用node.js就是運(yùn)用Common JS的一個(gè)例子,服務(wù)器端的程序比瀏覽器端要更復(fù)雜,也需要與操作系統(tǒng)和其他程序互動(dòng),因此服務(wù)器端必須要模塊塊以便應(yīng)對(duì)上述問題。node.js參照Common JS 規(guī)范創(chuàng)建了模塊系統(tǒng),模塊系統(tǒng)通過exports暴露接口返回對(duì)象,通過require獲取接口返回的對(duì)象。例如
// math.js文件 的內(nèi)容:
exports.method=function(){
var obj=xxx;
// doing something
return obj;
};
// main.js文件 的內(nèi)容:
var newObj= require('math').method;
// 當(dāng)然 main.js可以繼續(xù)exports接口 以供其他文件調(diào)用
AMD:"Asynchronous Module Definition"即異步模塊定義,實(shí)現(xiàn)AMD的庫有RequireJS 、curl 、Dojo 等。在服務(wù)器端采用的Common JS規(guī)范到瀏覽器端因?yàn)橥綀?zhí)行加載的問題會(huì)導(dǎo)致瀏覽器在加載獲取時(shí)處于假死狀態(tài)什么都不能做只能等引用加載完,AMD在這種環(huán)境下誕生了;AMD采用異步加載的方式去獲取引用的js,待加載完成后采取執(zhí)行對(duì)應(yīng)程序,從而避免了等待和瀏覽器假死的狀況。它的語法和應(yīng)用如下:
// 語法
define(id?,dependencies?,factory);
// id 即對(duì)這個(gè)模塊命名
// dependencies 這個(gè)模塊所依賴的其他模塊 多個(gè)時(shí)用數(shù)組傳遞
// factory 加載完成后執(zhí)行的回調(diào)函數(shù)
// math.js文件 定義模塊
define(function(){
var obj=xxx;
// doing somethig
return obj
})
// main.js文件 加載模塊
define(method,['math'],function(math){
//把加載的模塊傳遞進(jìn)來 doing something
})
CMD:CMD(Common Module Definition)是Sea JS推廣過程中產(chǎn)生的。在 CMD 規(guī)范中,一個(gè)模塊就是一個(gè)文件。其語法與comment js類似,不過多了一個(gè)外包裝;且相對(duì)與AMD的提前設(shè)置依賴,CMD的區(qū)別就是它將依賴內(nèi)置了,需要時(shí)就使用require去獲取,從表面上看實(shí)現(xiàn)了comment js的瀏覽器端化,但實(shí)質(zhì)是通過設(shè)置外包裝 define(function(require, exports, module){}來包裹代碼,提前去加載引用的模塊,等加載完成后再同步執(zhí)行。
// 語法 一個(gè)模塊就是一個(gè)文件
define(factory);
//math.js 定義
define(function(require, exports, module){
exports.obj=xxx;
})
// main.js 加載引用
define(function(require, exports, module){
var method=require('math').obj;
//doing something
})
// 當(dāng)然這個(gè)模塊也可以繼續(xù)exports接口 讓其他模塊調(diào)用