CommonJs, AMD/RequireJs,CMD/seajs
JavaSript模塊化
在了解AMD,CMD規(guī)范前,還是需要先來(lái)簡(jiǎn)單地了解下什么是模塊化,模塊化開(kāi)發(fā)?
模塊化是指在解決某一個(gè)復(fù)雜問(wèn)題或者一系列的雜糅問(wèn)題時(shí),依照一種分類的思維把問(wèn)題進(jìn)行系統(tǒng)性的分解以之處理。
模塊化是一種處理復(fù)雜系統(tǒng)分解為代碼結(jié)構(gòu)更合理,可維護(hù)性更高的可管理的模塊的方式。
可以想象一個(gè)巨大的系統(tǒng)代碼,被整合優(yōu)化分割成邏輯性很強(qiáng)的模塊時(shí),對(duì)于軟件是一種何等意義的存在。對(duì)于軟件行業(yè)來(lái)說(shuō):解耦軟件系統(tǒng)的復(fù)雜性,使得不管多么大的系統(tǒng),也可以將管理,開(kāi)發(fā),維護(hù)變得“有理可循”。
那么在理想狀態(tài)下我們只需要完成自己部分的核心業(yè)務(wù)邏輯代碼,其他方面的依賴可以通過(guò)直接加載被人已經(jīng)寫(xiě)好模塊進(jìn)行使用即可。
首先,既然是模塊化設(shè)計(jì),那么作為一個(gè)模塊化系統(tǒng)所必須的能力:
commonjs
commonjs起初是服務(wù)端模塊的規(guī)范,nodejs就是采用這個(gè)規(guī)范。
CommonJs原來(lái)是叫ServerJs,從名字可以看出是專攻服務(wù)端的,為了統(tǒng)一前后端而改名CommonJs。它的規(guī)范是一個(gè)單獨(dú)的文件就是一個(gè)模塊。加載模塊使用require方法,該方法讀取文件并執(zhí)行,最后導(dǎo)出一個(gè)exports對(duì)象。
例如:
// foo.js
// require 方法默認(rèn)讀取js文件,所以可以省略js后綴
var test = require('./foo').foo; test.bar();commonjs是同步加載模塊,所以加載完成后才能執(zhí)行后面的操作。服務(wù)端require一個(gè)模塊,加載的模塊文件一般都是已經(jīng)存在本地硬盤(pán),所以加載起來(lái)比較快,消耗的時(shí)間可以忽略,就沒(méi)有必要采用異步方式的來(lái)加載。但是如果我們考慮到瀏覽器端的話,就肯定知道,同步加載,阻塞頁(yè)面的渲染,造成頁(yè)面白屏,或者卡死等現(xiàn)象,對(duì)于用戶體驗(yàn)肯定是不友好的。
另外,資源的加載方式與服務(wù)端完全不同,在瀏覽器端,需要從服務(wù)端來(lái)下載這個(gè)文件,然后運(yùn)行里面的代碼才能得到API,需要花費(fèi)一個(gè)http請(qǐng)求,也就是說(shuō),require后面的一行代碼,需要資源請(qǐng)求完成才能執(zhí)行。由于瀏覽器端是以插入<script>標(biāo)簽的形式來(lái)加載資源的(ajax方式不行,有跨域問(wèn)題),沒(méi)辦法讓代碼同步執(zhí)行,所以像commonjs那樣的寫(xiě)法會(huì)直接報(bào)錯(cuò)。所以就有了AMD,CMD。
AMD(Asynchromous Module Definition)
字面意思”異步模塊定義”,就是一種規(guī)范。依賴前置(依賴在使用之前都必須提前加載)。requirejs可以簡(jiǎn)單理解為AMD規(guī)范的一種實(shí)現(xiàn)。
AMD寫(xiě)模塊的api如下:
define(id,dependencies,factory);
//通過(guò)數(shù)組引入依賴,回調(diào)函數(shù)通過(guò)形參傳入依賴
CMD(Common Module Definition)
CMD規(guī)范是國(guó)內(nèi)發(fā)展出來(lái)的,CMD是SeaJS在推廣過(guò)程中對(duì)模塊定義的規(guī)范化產(chǎn)出。
CMD推崇:
- 一個(gè)文件一個(gè)模塊,所以經(jīng)常就用文件名作為模塊id
- 依賴就近,所以一般不在define的參數(shù)中寫(xiě)依賴,在factory中寫(xiě)
factory有三個(gè)參數(shù):function(require, exports, module)
require是 factory 函數(shù)的第一個(gè)參數(shù)
require(id) 是一個(gè)方法,接受 模塊標(biāo)識(shí) 作為唯一參數(shù),用來(lái)獲取其他模塊提供的接口
exports 是一個(gè)對(duì)象,用來(lái)向外提供模塊接口
module 是一個(gè)對(duì)象,上面存儲(chǔ)了與當(dāng)前模塊相關(guān)聯(lián)的一些屬性和方法
//CMD
// 定義模塊 myModule.js define(function(require, exports, module) {//依賴可以就近書(shū)寫(xiě) var $ = require('jquery.js') $('div').addClass('active'); }); // seajs.use實(shí)現(xiàn)模塊系統(tǒng)的加載啟動(dòng) 加載模塊 seajs.use(['myModule.js'], function(my){ });AMD,CMD區(qū)別
最明顯的區(qū)別就是對(duì)依賴模塊的執(zhí)行時(shí)機(jī)處理不同
AMD推崇依賴前置,在定義模塊的時(shí)候就要聲明其依賴的模塊,并且所有的依賴模塊都是先執(zhí)行。
對(duì)應(yīng)的require.js在js程序中的依賴模塊的執(zhí)行順序和書(shū)寫(xiě)順序不一定一致,哪個(gè)先下載下來(lái),哪個(gè)先執(zhí)行。所有模塊都加載執(zhí)行完后會(huì)進(jìn)入require的回調(diào)函數(shù),執(zhí)行主邏輯。
CMD推崇就近依賴,是一種按需加載的模式,定義一個(gè)模塊的時(shí)候不需要立即制定模塊之間的依賴模塊,只有在用到某個(gè)模塊的時(shí)候再去require
對(duì)應(yīng)的seajs在js程序中的執(zhí)行順序是按照順序結(jié)構(gòu)的,當(dāng)遇到require某模塊的時(shí)候再去調(diào)用某些模塊。
共同點(diǎn):
都是異步加載模塊。
RequireJS和SeaJS與CommonJS的比較(嚴(yán)格意義上前兩者與后者不該放在一起比較,因?yàn)榍皟烧呤且?guī)范的具體實(shí)現(xiàn),而后者是一種規(guī)范)
總結(jié)
以上是生活随笔為你收集整理的CommonJs, AMD/RequireJs,CMD/seajs的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 谈谈对闭包的理解
- 下一篇: css布局左右2边固定,中间自适应