模塊化JavaScript設計模式(一)

在可擴展JavaScript的世界裏,如果我們說一個應用程序是模塊化(modular)的,那麼通常意味着它是由一系列存儲於模塊中的高度解耦,不同的功能片段組成。在可能的情況下,通過一處依賴性,鬆耦合可以使應用程序的可維護性更加簡單。 如果有效地實現了這點,就很容易地瞭解一部分如何影響另一個部分。


異步模塊定義(AMD)的整體目標是提供模塊化的JavaScript解決方案,以便開發者使用。誕生於使用XHR+eval的Dojo開發經驗,這種格式的支持者希望能夠避免未來的任何解決方案受到過去解決方案缺點的影響。 AMD模塊格式本身就是對定義模塊的建議,其模塊和依賴都將可以進行異步加載。

AMD最開始是CommonJS重模塊格式的草案規範,但由於沒有達到廣泛的一致,這種格式的進一步發展就轉移到了amdjs社區(https://github.com/amdjs)。


一、模塊入門

關於AMD有兩個關鍵概念是值得我們注意的,他們是用於模塊定義的define方法和用於處理依賴加載的require方法。試用一下方法,define用於定義已命名或未命名模塊:

define(
    module_id /*可選*/,
    [dependencies] /*可選*/,
    definition function /*function for instantiating the module or object實例化模塊或對象的函數*/
)


module_id是一個可選參數,它通常只在非AMD 連接工具被使用時才需要。當遺漏這個參數時,我們稱這個模塊未匿名的(anonymous)。

當使用這個匿名模塊時,模塊身份的概念是DRY,以便更容易避免文件名和代碼重複。因爲代碼變得更輕便了,不需要修改代碼本身或改變其模塊ID,就可以將它很容易地移動到其他位置。


Developers可以僅僅通過使用AMD優化器在多個環境中運行相同的代碼,AMD優化器在CommonJS環境(譬如r.js https://github.com/jrburke/r.js/)下工作。

       define ("myModule",  //定義一個module
            ['foo', 'bar'],
            function (foo, bar) { //模塊定義函數,依賴foo  bar 作爲參數映射到函數上
                //這裏創建你的模塊
                var myModule = {
                    dostuff: function () {
                        console.log('yay, stuff');
                    }
                };
                return myModule;
            }
       );
       //另外一種定義方式
       define('myModule', ['math', 'graph'], function (math, graph) {
            return {
                plot: function(x, y) {
                    return graph.drawPie(math.randomGrid(x, y));
                }
            }
       });

require通常用於加載頂級JavaScript文件或模塊的代碼。

//foo bar是兩個外部模塊,兩個模塊加載以後輸出作爲回調函數的參數傳入
require(['foo', 'bar'], function (foo, bar) {
    //
    foo.doSomething();
})

動態加載依賴

define(function (require) {
    var isReady = false, foobar;
    require(['foo', 'bar'], function (foo, bar) {
        isReady = true;
        foobar = foo() + bar();
    });
    return {
        isReady: isReady,
        foobar: foobar
    }
})


瞭解 AMD: 插件

//使用AMD可以加載任意格式的內容
//這種方式可以用於模板依賴,以便在頁面加載的時候進行做換膚方面的工作
define(['./templates', 'text!./template.md', 'css!./template.css'], function (templates, template) {
    console.log(templates);
});


雖然在上面的示例重包含css!用於加載css依賴,但這種方法會有一些警告。黨css完全被加載時,它不一定完全生效。取決於如何處理創建過程,它也可能使用css作爲一個依賴文件而被包含在優化的文件中,因此,在將css作爲加載依賴使用的情況下,一定要謹慎。



該示例可以簡單看作是requirejs(['app/myModule'], function () {}),表明加載器的頂級全局對象被使用。這裏演示瞭如何使用不同的AMD加載器加載頂級模塊nahor,通過使用define()函數,如果塔接受了一個本地模塊參數,那麼所有require([])的示例都適用於curl.js 和 RequireJS這兩種類型的加載器。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章