javascript 模塊化

1.模塊的寫法javascript

  a、原始寫法:html

function m1() {..........}

function m2() {..........}

    這兩個函數組成一個模塊,使用時直接調用,可是這樣明顯污染全局環境,沒法保證不與其餘的模塊發生變量名衝突,而且這樣也看不出來各個模塊之間的依賴關係。java

  b、後來寫成對象:jquery

var module1 = new Object({
        _count : 0,
        m1 : function (){
                //...
            },
        m2 : function (){
               //...
            }
});                        

    這樣就寫module.m1(); 可是這樣暴露了全部模塊成員,內部代碼能夠被外部改寫。好比外部代碼能夠直接改變內部計數的值  :module1._count =5;數組

  c、使用當即執行函數能夠達到不暴露私有成員變量的目的。瀏覽器

var module1 = (function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
    return {
      m1 : m1,
      m2 : m2
    };
})();

  d、後來又有了寬放大的模式服務器

var module1 = ( function (mod){
    //...
    return mod;
})(window.module1 || {});

 

2.出現模塊化規範,目前有 :CommonJS模塊、AMD模塊還有CMD模塊 幾種規範。異步

  a、CommonJS規範同步加載模塊,這對服務器端不是一個問題,由於全部的模塊都存放在本地硬盤,能夠同步加載完成,等待時間就是硬盤的讀取時間。可是,對於瀏覽器,這倒是一個大問題,由於模塊都放在服務器端,等待時間取決於網速的快慢,可能要等很長時間,瀏覽器處於"假死"狀態。所以,瀏覽器端的模塊,不能採用"同步加載"(synchronous),只能採用"異步加載"(asynchronous)。這就是AMD規範誕生的背景。
 async

var math = require('math');
math.add(2, 3)

 

  b、主要講AMD異步加載模塊加載採用異步方式加載模塊,模塊的加載不影響它後面語句的運行。全部依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成以後,這個回調函數纔會運行。
AMD也採用require加載模塊 require([module], callback);第一個參數[module],是一個數組,裏面的成員就是要加載的模塊;第二個參數callback,則是加載成功以後的回調函數
 模塊化

require(['math'], function (math) {
   math.add(2, 3);
});

  math.add()與math模塊加載不是同步的,瀏覽器不會發生假死。因此很顯然,AMD比較適合瀏覽器環境。require.js這個JavaScript的庫實現了AMD規範

 

3.require.js用法

  a、開始引用js文件

<script src="1.js"></script>
<script src="2.js"></script>
<script src="3.js"></script>
<script src="4.js"></script>

  這樣的方式加載有兩個缺點:加載的時候,瀏覽器會中止網頁渲染,加載文件越多,網頁失去響應的時間就會越長(解決方法在下邊);其次,因爲js文件之間存在依賴關係,所以必須嚴格保證加載順序

  b、require.js解決了這個問題 <script src="js/require.js" defer async="true" ></script>
async屬性代表這個文件須要異步加載,避免網頁失去響應。IE不支持這個屬性,只支持defer,因此把defer也寫上。加載require.js之後就須要 加載咱們本身的代碼了,寫一個main.js 這就至關於c語言的main()入口;
<script src="js/require.js" data-main="js/main"></script> data-main屬性的做用是,指定網頁程序的主模塊

main.js --------->
  require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
    // some code here
  });

  require()函數接受兩個參數。第一個參數是一個數組,表示所依賴的模塊,上例就是['moduleA', 'moduleB', 'moduleC'],即主模塊依賴這三個模塊;第二個參數是一個回調函數,當前面指定的模塊都加載成功後,它將被調用。加載的模塊會以參數形式傳入該函數,從而在回調函數內部就可使用這些模塊。
  require()異步加載moduleA,moduleB和moduleC,瀏覽器不會失去響應;它指定的回調函數,只有前面的模塊都加載成功後,纔會運行,解決了依賴性的問題。

  c、自定義模塊的加載行爲 :使用require.config()方法進行定義;寫在main.js的頭部。

require.config({
    paths: {
           // 或者寫上baseUrl: "js/lib",下邊就不用寫lib
      "jquery": "lib/jquery.min",
      "underscore": "lib/underscore.min",
      "backbone": "lib/backbone.min"
    }
  });    

  若是加載多個模塊,就會發出屢次HTTP請求,會影響網頁的加載速度。所以,require.js提供了一個優化工具,當模塊部署完畢之後,能夠用這個工具將多個模塊合併在一個文件中,減小HTTP請求數。

 

4.加載方式完了,而後就是本身寫的模塊 應該用AMD規範進行,寫模塊必須採用特定的define()函數來定義;
    

---------------->// math.js模塊
  define(function (){
    var add = function (x,y){
      return x+y;
    };
    return {
      add: add
    };
  }); 

 


  b、若是這個模塊依賴其餘的模塊怎麼辦?

---------------->// math.js模塊
  define(['myLib'], function(myLib){
    function foo(){
      myLib.doSomething();
    }
    return {
      foo : foo
    };
  });

 

5.不少的庫的模塊並不符合AMD規範那麼怎麼進行加載呢?那加載他們以前必需要先定義他們的特徵,好比加載underscore和backbone

require.config({
    shim: {
      'underscore':{
        exports: '_'
      },
      'backbone': {
        deps: ['underscore', 'jquery'],
        exports: 'Backbone'
      }
    }
});

  require.config()接受一個配置對象,這個對象除了有前面說過的paths屬性以外,還有一個shim屬性,專門用來配置不兼容的模塊。具體來講,每一個模塊要定義(1)exports值(輸出的變量名),代表這個模塊外部調用時的名稱;(2)deps數組,代表該模塊的依賴性。

 

參照文檔:http://www.ruanyifeng.com/blog/2012/10/javascript_module.html(阮一峯)  本身理解

相關文章
相關標籤/搜索