CMD

CMD 模塊定義規(guī)范

在?Sea.js?中,所有?JavaScript?模塊都遵循?CMD(Common?Module?Definition)?模塊定義規(guī)范。該規(guī)范明確了模塊的基本書(shū)寫(xiě)格式和基本交互規(guī)則。

在?CMD?規(guī)范中,一個(gè)模塊就是一個(gè)文件。代碼的書(shū)寫(xiě)格式如下:

define(factory);

defineFunction

define是一個(gè)全局函數(shù),用來(lái)定義模塊。

definedefine(factory)

define接受factory參數(shù),factory可以是一個(gè)函數(shù),也可以是一個(gè)對(duì)象或字符串。

factory為對(duì)象、字符串時(shí),表示模塊的接口就是該對(duì)象、字符串。比如可以如下定義一個(gè)?JSON?數(shù)據(jù)模塊:

define({"foo":"bar"});

也可以通過(guò)字符串定義模板模塊:

define('I?am?a?template.?My?name?is?{{name}}.');

factory為函數(shù)時(shí),表示是模塊的構(gòu)造方法。執(zhí)行該構(gòu)造方法,可以得到模塊向外提供的接口。factory方法在執(zhí)行時(shí),默認(rèn)會(huì)傳入三個(gè)參數(shù):require、exports和module:

define(function(require,exports,module)?{

//?模塊代碼

});

definedefine(id?,?deps?,?factory)

define也可以接受兩個(gè)以上參數(shù)。字符串id表示模塊標(biāo)識(shí),數(shù)組deps是模塊依賴。比如:

define('hello',?['jquery'],function(require,exports,module)?{

//?模塊代碼

});

id和deps參數(shù)可以省略。省略時(shí),可以通過(guò)構(gòu)建工具自動(dòng)生成。

注意:帶id和deps參數(shù)的define用法不屬于?CMD?規(guī)范,而屬于Modules/Transport規(guī)范。

define.cmdObject

一個(gè)空對(duì)象,可用來(lái)判定當(dāng)前頁(yè)面是否有?CMD?模塊加載器:

if(typeofdefine==="function"&&define.cmd)?{

//?有?Sea.js?等?CMD?模塊加載器存在

}

requireFunction

require是factory函數(shù)的第一個(gè)參數(shù)。

requirerequire(id)

require是一個(gè)方法,接受模塊標(biāo)識(shí)作為唯一參數(shù),用來(lái)獲取其他模塊提供的接口。

define(function(require,exports)?{

//?獲取模塊?a?的接口

vara=require('./a');

//?調(diào)用模塊?a?的方法

a.doSomething();

});

注意:在開(kāi)發(fā)時(shí),require的書(shū)寫(xiě)需要遵循一些簡(jiǎn)單約定。

require.asyncrequire.async(id,?callback?)

require.async方法用來(lái)在模塊內(nèi)部異步加載模塊,并在加載完成后執(zhí)行指定回調(diào)。callback參數(shù)可選。

define(function(require,exports,module)?{

//?異步加載一個(gè)模塊,在加載完成時(shí),執(zhí)行回調(diào)

require.async('./b',function(b)?{

b.doSomething();

});

//?異步加載多個(gè)模塊,在加載完成時(shí),執(zhí)行回調(diào)

require.async(['./c','./d'],function(c,?d)?{

c.doSomething();

d.doSomething();

});

});

注意:require是同步往下執(zhí)行,require.async則是異步回調(diào)執(zhí)行。require.async一般用來(lái)加載可延遲異步加載的模塊。

require.resolverequire.resolve(id)

使用模塊系統(tǒng)內(nèi)部的路徑解析機(jī)制來(lái)解析并返回模塊路徑。該函數(shù)不會(huì)加載模塊,只返回解析后的絕對(duì)路徑。

define(function(require,exports)?{

console.log(require.resolve('./b'));

//?==>?http://example.com/path/to/b.js

});

這可以用來(lái)獲取模塊路徑,一般用在插件環(huán)境或需動(dòng)態(tài)拼接模塊路徑的場(chǎng)景下。

exportsObject

exports是一個(gè)對(duì)象,用來(lái)向外提供模塊接口。

define(function(require,exports)?{

//?對(duì)外提供?foo?屬性

exports.foo='bar';

//?對(duì)外提供?doSomething?方法

exports.doSomething=function()?{};

});

除了給exports對(duì)象增加成員,還可以使用return直接向外提供接口。

define(function(require)?{

//?通過(guò)?return?直接提供接口

return{

foo:'bar',

doSomething:function()?{}

};

});

如果return語(yǔ)句是模塊中的唯一代碼,還可簡(jiǎn)化為:

define({

foo:'bar',

doSomething:function()?{}

});

上面這種格式特別適合定義?JSONP?模塊。

特別注意:下面這種寫(xiě)法是錯(cuò)誤的!

define(function(require,exports)?{

//?錯(cuò)誤用法?。?

exports={

foo:'bar',

doSomething:function()?{}

};

});

正確的寫(xiě)法是用return或者給module.exports賦值:

define(function(require,exports,module)?{

//?正確寫(xiě)法

module.exports={

foo:'bar',

doSomething:function()?{}

};

});

提示:exports僅僅是module.exports的一個(gè)引用。在factory內(nèi)部給exports重新賦值時(shí),并不會(huì)改變module.exports的值。因此給exports賦值是無(wú)效的,不能用來(lái)更改模塊接口。

moduleObject

module是一個(gè)對(duì)象,上面存儲(chǔ)了與當(dāng)前模塊相關(guān)聯(lián)的一些屬性和方法。

module.idString

模塊的唯一標(biāo)識(shí)。

define('id',?[],function(require,exports,module)?{

//?模塊代碼

});

上面代碼中,define的第一個(gè)參數(shù)就是模塊標(biāo)識(shí)。

module.uriString

根據(jù)模塊系統(tǒng)的路徑解析規(guī)則得到的模塊絕對(duì)路徑。

define(function(require,exports,module)?{

console.log(module.uri);

//?==>?http://example.com/path/to/this/file.js

});

一般情況下(沒(méi)有在define中手寫(xiě)id參數(shù)時(shí)),module.id的值就是module.uri,兩者完全相同。

module.dependenciesArray

dependencies是一個(gè)數(shù)組,表示當(dāng)前模塊的依賴。

module.exportsObject

當(dāng)前模塊對(duì)外提供的接口。

傳給factory構(gòu)造方法的exports參數(shù)是module.exports對(duì)象的一個(gè)引用。只通過(guò)exports參數(shù)來(lái)提供接口,有時(shí)無(wú)法滿足開(kāi)發(fā)者的所有需求。?比如當(dāng)模塊的接口是某個(gè)類的實(shí)例時(shí),需要通過(guò)module.exports來(lái)實(shí)現(xiàn):

define(function(require,exports,module)?{

//?exports?是?module.exports?的一個(gè)引用

console.log(module.exports===exports);//?true

//?重新給?module.exports?賦值

module.exports=newSomeClass();

//?exports?不再等于?module.exports

console.log(module.exports===exports);//?false

});

注意:對(duì)module.exports的賦值需要同步執(zhí)行,不能放在回調(diào)函數(shù)里。下面這樣是不行的:

//?x.jsdefine(function(require,exports,module)?{

//?錯(cuò)誤用法

setTimeout(function()?{

module.exports={?a:"hello"};

},0);

});

在?y.js?里有調(diào)用到上面的?x.js:

//?y.jsdefine(function(require,exports,module)?{

varx=require('./x');

//?無(wú)法立刻得到模塊?x?的屬性?a

console.log(x.a);//?undefined

});

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1 個(gè)人理解;有錯(cuò)希望大家指出;稍后更新拖拽上傳文件; 2、commonJS commonjs的目標(biāo)是制定一個(gè)js...
    吳高亮閱讀 1,639評(píng)論 0 2
  • 隨著前端業(yè)務(wù)復(fù)雜度的增加,模塊化成為一個(gè)大的趨勢(shì)。而在ES6還未被瀏覽器所支持的情況下,commonjs作為ES6...
    吳高亮閱讀 1,102評(píng)論 0 3
  • 為什么要使用模塊化? 最主要的目的:解決命名沖突依賴管理 其他價(jià)值提高代碼可讀性代碼解耦,提高復(fù)用性 CMD、AM...
    Eazer閱讀 769評(píng)論 3 1
  • 轉(zhuǎn)載于作者:linwalker via:http://www.itdecent.cn/p/d67bc79976e6...
    猩崽大叔閱讀 719評(píng)論 0 0
  • 以代碼愛(ài)好者角度來(lái)看AMD與CMD 隨著瀏覽器功能越來(lái)越完善,前端已經(jīng)不僅僅是切圖做網(wǎng)站,前端在某些方面已經(jīng)媲美桌...
    鄙人才疏學(xué)淺閱讀 1,984評(píng)論 2 7

友情鏈接更多精彩內(nèi)容