JavaScript的模塊系統詳解(一)

由於JavaScript開發變得越來越普遍,命名空間和依賴管理更加難以處理,前赴後繼的程序員們提出來很多的解決方案,本文將探討一些經典的方案,並描述這些方案解決了哪些問題。

爲什麼需要模塊系統

作爲開發人員,我們一定知道封裝和依賴。在實際的項目開發中,我們通常會引入項目依賴,如果沒有封裝機制,這可能會導致代碼間的各種衝突,所以我們在看一些C語言的源碼庫的時候,經常會看到各種前綴:

#ifndef MYLIB_INIT_H
#define MYLIB_INIT_H

enum mylib_init_code {
    mylib_init_code_success,
    mylib_init_code_error
};
enum mylib_init_code mylib_init(void);
//(...)

#endif //MYLIB_INIT_H

封裝可以有效解決代碼衝突。但在Web端的js開發中,僅僅做到封裝是不夠的,我們還要確保各依賴模塊能按照正確的順序加載和執行。

我們通過Backbone.js的一個例子來說明手動控制依賴的加載順序:

<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Backbone.js Todos</title>
        <link rel="stylesheet" href="todos.css"/>
    </head>

    <body>
        <script src="../../test/vendor/json2.js"></script>
        <script src="../../test/vendor/jquery.js"></script>
        <script src="../../test/vendor/underscore.js"></script>
        <script src="../../backbone.js"></script>
        <script src="../backbone.localStorage.js"></script>
        <script src="todos.js"></script>
    </body>

    <!-- (...) -->

</html>

隨着現代JavaScript的開發越來越複雜,依賴管理也變得越來越困難,引入模塊系統是大勢所趨。

特殊的模塊封裝

在介紹現代模塊系統之前,我們先介紹一種特殊的編程模式,在一定程度上它也可以解決很多JavaScript應用的模塊管理。


var myRevealingModule = (function () {
    var privateVar = "Ben Cherry",
        publicVar = "Hey there!";

    function privateFunction() {
        console.log( "Name:" + privateVar );
    }

    function publicSetName( strName ) {
        privateVar = strName;
    }

    function publicGetName() {
        privateFunction();
    }

    // Reveal public pointers to
    // private functions and properties
    return {
        setName: publicSetName,
        greeting: publicVar,
        getName: publicGetName
    };
})();

myRevealingModule.setName( "Paul Kinlan" );

這是通過函數作用域來實現私有變量的封裝,有函數return語句暴露對外訪問的接口。在上面的例子中,函數內部不一定需要通過var來聲明變量,函數也無需立即執行,命名函數也可以作爲一個模塊來使用。
在很長一段時間,這種方式可以很好地實現模塊封裝,但它不能解決依賴管理的問題,同時也無法引入其它模塊,除非在函數內容通過eval執行外部JavaScript。

特點

  • 實現簡單,原生支持;
  • 在單個文件中定義多個模塊。

缺陷

  • 無法導入其他文件中的模塊;
  • 手動處理依賴管理;
  • 無法實現依賴的異步加載;
  • 無法有效處理依賴間的循環引用;
  • 無法靜態分析源碼依賴。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章