Javascript的模塊化編程


Javascript在設計之初並沒有提供一種原生的,語言級別的模塊化方式來組織代碼,比如Java語言通過package和import來管理和使用模塊。ECMAScript 6引入了class和import的概念來支持模塊化,但是瀏覽器全面支持這個標准還需要很長時間。

應用程序的模塊化指的就是通過一些高度解耦的,存放在不同地方的功能模塊構成。近年來隨着Javascript應用的復雜化,大型化,Javascript代碼需要更為有序的組織,在Javascript社區出現了很多種模塊化的實現方式,最主要的兩個規范是CommomJS和AMD,本文會重點闡述這兩個規范。

1. CommonJS

CommonJS是以在瀏覽器之外構建Javascript系統而產生的項目,致力於Javascript模塊的標准化工作。主要特點是同步加載Javascript模塊,運行在服務器端。Node.js 就是CommonJS規范的一個實現。

CommonJS對於模塊的定義非常簡單,分為模塊定義(exports),模塊引用(require),模塊標示三部分。
通過全局變量 exports 返回當前模塊希望提供給其他模塊的對象:

 1 // 定義行為
 2 function foobar(){
 3         this.foo = function(){
 4                 console.log('Hello foo');
 5         }
 6 
 7         this.bar = function(){
 8                 console.log('Hello bar');
 9         }
10 }
11 // 把 foobar 暴露給其它模塊
12 exports.foobar = foobar;

通過全局函數 require 來導入其他模塊的輸出:

1 //使用文件與模塊文件在同一目錄
2 var foobar = require('./foobar').foobar,
3 test = new foobar();
4 test.bar(); // 'Hello bar'

模塊標示其實就是傳遞給require方法的參數,用來指定加載文件路徑,可以沒有后綴名.js,例如上面例子中的 “./foobar”。

CommonJS模塊的代碼都運行在模塊作用域,不會污染全局作用域,模塊可以多次加載,但是結果會被緩存。CommonJS主要是為服務器端JavaScript運行庫設計的,模塊是同步加載的,這使得難以在瀏覽器中運行CommonJS代碼。Node.js上面有一些項目例如Browserify,將CommonJS帶進了瀏覽器,Browserify將依賴到的單獨的js文件打包成一個單獨的js文件,統一加載到瀏覽器端。
 

2. AMD

AMD(異步模塊定義)是為瀏覽器環境設計的,采用異步方式加載模塊,模塊的加載不影響它后面語句的運行。所有依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成之后,這個回調函數才會運行。

模塊通過 define 函數定義在閉包中,格式如下:

1 define(id?: String /*可選*/,
2        dependencies?: String /*可選*/,
3        factory: Function|Object /*用來初始化模塊或對象的函數*/);

id 是模塊的名字,它是可選的參數。dependencies 指定了所要依賴的模塊列表,它是一個數組,也是可選的參數,每個依賴的模塊的輸出將作為參數一次傳入 factory 中。factory 是最后一個參數,它包裹了模塊的具體實現,它是一個函數或者對象。如果是函數,那么它的返回值就是模塊的輸出接口或值。

定義一個名為 myModule 的模塊,它依賴 foo, bar 模塊:

 1 define('myModule',
 2     // 依賴
 3     ['foo', 'bar'],
 4     // 依賴(foo 和 bar)被映射為函數的參數
 5     function ( foo, bar ) {
 6         // 返回一個定義了模塊導出接口的值
 7         // 在這里創建模塊
 8         var myModule = {
 9             doSomething:function(){
10             }
11         }
12         return myModule;
13 });

定義一個獨立模塊,不需要依賴任何其他模塊:

define(function () {
    return {
        doSomething: function() {}
    };
});

通過 require 調用模塊:

1 require(['foo', 'bar'], function ( foo, bar ) {
2         foo.doSomething();
3 });

在模塊定義內部也可以使用require來加載其他模塊:

 1 define(function ( require ) {
 2     var isReady = false, foobar;
 3 
 4     require(['foo', 'bar'], function (foo, bar) {
 5         isReady = true;
 6         foobar = foo() + bar();
 7     });
 8 
 9     return {
10         isReady: isReady,
11         foobar: foobar
12     };
13 });

上面的例子中 foo 和 bar沒有加載完成之前,isReady屬性為 false。

目前主要有兩個Javascript庫實現了AMD規范:require.js和curl.js。RequireJS由James Burke創建,他也是AMD規范的創始人。

3. 結語

CommonJS 則采用了服務器優先的策略,使用同步方式加載模塊,而且試圖涵蓋更多更寬泛的東西,例如文件IO,Promise等等。而AMD 采取了一種瀏覽器優先的方式來開發,使用異步方式加載模塊。它支持對象、函數、構造器、字符串、JSON 以及其它許多類型的模塊,運行在瀏覽器本地環境之中。

由於當前版本的Javascript沒有提供原生的模塊化支持,社區的開發者進行了很多模塊化的探索,使得Javascript工程化成為了可能,CommonJS和AMD就是最主要的兩個規范。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM