一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

前端模塊化開(kāi)發(fā)(AMD和CDM規(guī)范)

 昵稱(chēng)19107491 2014-08-27

前端模塊化開(kāi)發(fā)(AMD和CDM規(guī)范)

JS

2014-8-9  作者:前端工程師小V  瀏覽:34

標(biāo)簽: javascript javascript的依賴(lài)管理 前端模塊化開(kāi)發(fā)

1、AMD和CDM規(guī)范來(lái)歷

前提:
CommonJS 原來(lái)叫 ServerJS,推出 Modules/1.0 規(guī)范后,在 Node.js 等環(huán)境下取得了很不錯(cuò)的實(shí)踐。09年下半年這幫充滿(mǎn)干勁的小伙子們想把 ServerJS 的成功經(jīng)驗(yàn)進(jìn)一步推廣到瀏覽器端,于是將社區(qū)改名叫 CommonJS,同時(shí)激烈爭(zhēng)論 Modules 的下一版規(guī)范。分歧和沖突由此誕生,逐步形成了三大流派:

1.Modules/1.x 流派。這個(gè)觀(guān)點(diǎn)覺(jué)得 1.x 規(guī)范已經(jīng)夠用,只要移植到瀏覽器端就好。要做的是新增 Modules/Transport 規(guī)范,即在瀏覽器上運(yùn)行前,先通過(guò)轉(zhuǎn)換工具將模塊轉(zhuǎn)換為符合 Transport 規(guī)范的代碼。主流代表是服務(wù)端的開(kāi)發(fā)人員。現(xiàn)在值得關(guān)注的有兩個(gè)實(shí)現(xiàn):越來(lái)越火的 component 和走在前沿的 es6 module transpiler。

2.Modules/Async 流派。這個(gè)觀(guān)點(diǎn)覺(jué)得瀏覽器有自身的特征,不應(yīng)該直接用 Modules/1.x 規(guī)范。這個(gè)觀(guān)點(diǎn)下的典型代表是 AMD 規(guī)范及其實(shí)現(xiàn) RequireJS。

3.Modules/2.0 流派。這個(gè)觀(guān)點(diǎn)覺(jué)得瀏覽器有自身的特征,不應(yīng)該直接用 Modules/1.x 規(guī)范,但應(yīng)該盡可能與 Modules/1.x 規(guī)范保持一致。這個(gè)觀(guān)點(diǎn)下的典型代表是 BravoJS 和 FlyScript 的作者。BravoJS 作者對(duì) CommonJS 的社區(qū)的貢獻(xiàn)很大,這份 Modules/2.0-draft 規(guī)范花了很多心思。
FlyScript 的作者提出了 Modules/Wrappings 規(guī)范,這規(guī)范是 CMD 規(guī)范的前身。可惜的是 BravoJS 太學(xué)院派,F(xiàn)lyScript 后來(lái)做了自我閹割,將整個(gè)網(wǎng)站(flyscript.org)下線(xiàn)了。


AMD
異步模塊定義(AMD)的編程接口提供了定義模塊,及異步加載該模塊的依賴(lài)的機(jī)制。它非常適合于使用于瀏覽器環(huán)境,瀏覽器的同步加載模塊機(jī)制會(huì)帶來(lái)性能,可用性,調(diào)試和跨域訪(fǎng)問(wèn)的問(wèn)題。

本規(guī)范只定義了一個(gè)函數(shù) "define",它是全局變量。函數(shù)的描述為:
   
define(id?, dependencies?, factory);

id
是個(gè)字符串,它指的是定義中模塊的名字,這個(gè)參數(shù)是可選的。如果沒(méi)有提供該參數(shù),模塊的名字應(yīng)該默認(rèn)為模塊
加載器請(qǐng)求的指定腳本的名字。如果提供了該參數(shù),模塊名必須是“頂級(jí)”的和絕對(duì)的(不允許相對(duì)名字)。

dependencies
是個(gè)定義中模塊所依賴(lài)模塊的數(shù)組。依賴(lài)模塊必須根據(jù)模塊的工廠(chǎng)方法優(yōu)先級(jí)執(zhí)行,并且執(zhí)行的結(jié)果應(yīng)該按照依賴(lài)數(shù)組中的位置順序以參數(shù)的形式傳入(定義中模塊的)工廠(chǎng)方法中。

依賴(lài)的模塊名如果是相對(duì)的,應(yīng)該解析為相對(duì)定義中模塊。換句話(huà)來(lái)說(shuō),相對(duì)名解析為相對(duì)與模塊的名字,并非相對(duì)于尋找該模塊的名字的路徑。

本規(guī)范定義了截然不同的三種特殊的依賴(lài)關(guān)鍵字。如果"require","exports", 或 "module"出現(xiàn)在依賴(lài)列表中,參數(shù)應(yīng)該按照CommonJS模塊規(guī)范自由變量去解析。

依賴(lài)參數(shù)是可選的,如果忽略此參數(shù),它應(yīng)該默認(rèn)為["require", "exports", "module"]。然而,如果工廠(chǎng)方法的長(zhǎng)度屬性小于3,加載器會(huì)選擇以函數(shù)的長(zhǎng)度屬性指定的參數(shù)個(gè)數(shù)調(diào)用工廠(chǎng)方法。


Factory
為模塊初始化要執(zhí)行的函數(shù)或?qū)ο蟆H绻麨楹瘮?shù),它應(yīng)該只被執(zhí)行一次。如果是對(duì)象,此對(duì)象應(yīng)該為模塊的輸出值。

如果工廠(chǎng)方法返回一個(gè)值(對(duì)象,函數(shù),或任意強(qiáng)制類(lèi)型轉(zhuǎn)換為true的值),應(yīng)該為設(shè)置為模塊的輸出值。

下面的例子顯示了requirejs如何動(dòng)態(tài)加載模塊。
define(function ( require ) {
    var isReady = false, foobar;
 
    require(['foo', 'bar'], function (foo, bar) {
        isReady = true;
        foobar = foo() + bar();
    });
 
    return {
        isReady: isReady,
        foobar: foobar
    };
});
上面代碼所定義的模塊,內(nèi)部加載了foo和bar兩個(gè)模塊,在沒(méi)有加載完成前,isReady屬性值為false,加載完成后就變成了true。因此,可以根據(jù)isReady屬性的值,決定下一步的動(dòng)作。

require.js
config方法,用來(lái)配置require.js運(yùn)行參數(shù)。config方法接受一個(gè)對(duì)象作為參數(shù)。


paths
參數(shù)指定各個(gè)模塊的位置。這個(gè)位置可以是同一個(gè)服務(wù)器上的相對(duì)位置,也可以是外部網(wǎng)址??梢詾槊總€(gè)模塊定義多個(gè)位置,如果第一個(gè)位置加載失敗,則加載第二個(gè)位置,上面的示例就表示如果CDN加載失敗,則加載服務(wù)器上的備用腳本。需要注意的是,指定本地文件路徑時(shí),可以省略文件最后的js后綴名。

baseUrl
參數(shù)指定本地模塊位置的基準(zhǔn)目錄,即本地模塊的路徑是相對(duì)于哪個(gè)目錄的。該屬性通常由require.js加載時(shí)的data-main屬性指定。

shim
有些庫(kù)不是AMD兼容的,這時(shí)就需要指定shim屬性的值。shim可以理解成“墊片”,用來(lái)幫助require.js加載非AMD規(guī)范的庫(kù)。
require.config({
    paths: {
        "backbone": "vendor/backbone",
        "underscore": "vendor/underscore"
    },
    shim: {
        "backbone": {
            deps: [ "underscore" ],
            exports: "Backbone"
        },
        "underscore": {
            exports: "_"
        }
    }
});
上面代碼中的backbone和underscore就是非AMD規(guī)范的庫(kù)。shim指定它們的依賴(lài)關(guān)系(backbone依賴(lài)于underscore),以及輸出符號(hào)(backbone為“Backbone”,underscore為“_”)。


CDM

CMD 模塊定義規(guī)范

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

define 是一個(gè)全局函數(shù),用來(lái)定義模塊。
define(factory)
define 接受 factory 參數(shù),factory 可以是一個(gè)函數(shù),也可以是一個(gè)對(duì)象或字符串。

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

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

define(function(require, exports, module) {
// 模塊代碼
});

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

中間包括兩個(gè)概念
相對(duì)標(biāo)識(shí)  以 . 開(kāi)頭,只出現(xiàn)在模塊環(huán)境中(define 的 factory 方法里面)。相對(duì)標(biāo)識(shí)永遠(yuǎn)相對(duì)當(dāng)前模塊的 URI 來(lái)解析:

頂級(jí)標(biāo)識(shí)  不以點(diǎn)(.)或斜線(xiàn)(/)開(kāi)始, 會(huì)相對(duì)模塊系統(tǒng)的基礎(chǔ)路徑(即 Sea.js 的 base 路徑)來(lái)解析:

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

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

  // 模塊代碼

});
id 和 deps 參數(shù)可以省略

require
require 是 factory 函數(shù)的第一個(gè)參數(shù)。
require.async
1.require.async 來(lái)進(jìn)行條件加載。
2.require 是同步往下執(zhí)行,require.async 則是異步回調(diào)執(zhí)行。require.async 一般用來(lái)加載可延遲異步加載的模塊。

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

 

define(function(require, exports) {

  console.log(require.resolve('./b'));
  // ==> http:///path/to/b.js

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

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

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

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

module.id
String
模塊的唯一標(biāo)識(shí)。

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

  // 模塊代碼

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

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

define(function(require, exports, module) {

  console.log(module.uri);
  // ==> http:///path/to/this/file.js

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

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

exports 參數(shù)是 module.exports 對(duì)象的一個(gè)引用。只通過(guò) exports 參數(shù)來(lái)提供接口,有時(shí)無(wú)法滿(mǎn)足開(kāi)發(fā)者的所有需求。
比如當(dāng)模塊的接口是某個(gè)類(lèi)的實(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 = new SomeClass();

  // exports 不再等于 module.exports
  console.log(module.exports === exports); // false

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

 

相關(guān)參考

https://github.com/seajs/seajs/issues/242  CMD 模塊定義規(guī)范
https://github.com/seajs/seajs/issues/588  前端模塊化開(kāi)發(fā)那點(diǎn)歷史
https://github.com/seajs/seajs/issues/258   模塊標(biāo)識(shí)
https://github.com/amdjs/amdjs-api/wiki/AMD-(中文版)   AMD
http://javascript./tool/requirejs.html  


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多

    精品al亚洲麻豆一区| 99久久国产精品免费| 五月综合婷婷在线伊人| 搡老熟女老女人一区二区| 国产日韩欧美国产欧美日韩 | 欧美精品亚洲精品一区| 国产精品蜜桃久久一区二区| 99视频精品免费视频播放| 国产精品一区二区三区日韩av| 欧美做爰猛烈叫床大尺度| 日韩欧美一区二区亚洲| 99视频精品免费视频播放| 亚洲免费视频中文字幕在线观看| 污污黄黄的成年亚洲毛片| 国产亚洲欧美日韩国亚语| 日本深夜福利在线播放| 日本人妻的诱惑在线观看| 欧美日韩欧美国产另类| 99少妇偷拍视频在线| 日韩不卡一区二区三区色图| 欧美一区二区三区十区| 亚洲女同一区二区另类| 欧美日韩一级aa大片| 大胆裸体写真一区二区| 亚洲中文字幕高清乱码毛片| 99福利一区二区视频| 国产精品一区二区三区黄色片| 一区二区三区四区亚洲另类| 亚洲欧洲成人精品香蕉网| 亚洲日本久久国产精品久久| 日本高清一道一二三区四五区| 亚洲日本加勒比在线播放| 一二区中文字幕在线观看| 夫妻性生活真人动作视频 | 国产精品白丝久久av| 国内胖女人做爰视频有没有| 五月婷婷缴情七月丁香| 久久99国产精品果冻传媒| 国产亚洲二区精品美女久久| 日韩亚洲激情在线观看| 亚洲精品成人福利在线|