js模塊化開發——require.js學習總結

一、爲何使用require.js

做爲命名空間; 做爲命名空間使用;
異步加載js,避免阻塞,提升性能; js經過require加載,沒必要寫不少scriptcss

二、require.js的加載

require.js下載 下載後,放在指定目錄就能夠加載了html

?
1
<script src= "js/require.js" ></script>

有人可能會想到,加載這個文件,也可能形成網頁失去響應。解決辦法有兩個,一個是把它放在網頁底部加載,另外一個是寫成下面這樣:java

?
1
<script src= "js/require.js" defer async= "true" ></script>

async屬性代表這個文件須要異步加載,避免網頁失去響應。IE不支持這個屬性,只支持defer,因此把defer也寫上。node

 

 

 

 

這種寫法雖然簡單,但其實並不推薦,通常的寫法還要再加個屬性:jquery

?
1
<script data-main= "js/main" src= "js/require-jquery.js" ></script>

就像一個c程序總有一個 main 方法做爲入口同樣,上面這種寫法,作了幾件事情:
一、加載了 require-jquery.js 文件。注意,官方提供了 require.js和 jquery 的打包版本,推薦。
二、在加載以後,加載入口文件 js/main.js ,注意,main.js 寫進去的時候,不須要後綴名。
你的全部其餘 js 模塊文件,均可以寫在 main.js 裏面,經過 main.js 加載。ajax

三、require.js的配置

在data-main指定的主文件中,經過require.config來配置,並加載其餘js模塊json

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
require.config({
     baseUrl: 'js/'
     paths: {
         "backbone" : "backbone" ,
         "underscore" : "underscore"
     },
     shim: {
         "backbone" : {
             deps: [ "underscore" ],
             exports: "Backbone"
         },
         "underscore" : {
             exports: "_"
         }
     }
});

baseUrl:指定基路徑 paths:模塊加載路徑 shim:加載非AMD規範模塊api

    1. exports值(輸出的變量名),代表這個模塊外部調用時的名稱;
    2. deps數組,代表該模塊的依賴性。
    3. 主模塊能夠將項目基礎模塊加載加來並定義全局方法等
    4. ?
      1
      2
      3
      require([ 'jquery' , 'underscore' , 'backbone' ], function ($, _, Backbone){
             // some code here
          });

      四、定義模塊(符合AMD規範)

      require.js加載的模塊,採用AMD規範。也就是說,模塊必須按照AMD的規定來寫。
      具體來講,就是模塊必須採用特定的define()函數來定義。若是一個模塊不依賴其餘模塊,那麼能夠直接定義在define()函數之中。
      假定如今有一個math.js文件,它定義了一個math模塊。那麼,math.js就要這樣寫:
      ?
      1
      2
      3
      4
      5
      6
      7
      8
      9
      // math.js
          define(function (){
            var add = function (x,y){
               return x+y;
            };
             return {
              add: add
            };
          });
      加載方法以下:
      ?
      1
      2
      3
      4
      // main.js
          require([ 'math' ], function (math){
            alert(math.add( 1 , 1 ));
          });
      若是這個模塊還依賴其餘模塊,那麼define()函數的第一個參數,必須是一個數組,指明該模塊的依賴性。
      ?
      1
      2
      3
      4
      5
      6
      7
      8
      define([ 'myLib' ], function(myLib){
            function foo(){
              myLib.doSomething();
            }
             return {
              foo : foo
            };
          });

      定義的模塊返回函數個數問題數組

      一、define 的return只有一個函數,require的回調函數能夠直接用別名代替該函數名。瀏覽器

      二、define 的return當有多個函數,require的回調函數必須用別名調用全部的函數。

      ?
      1
      2
      3
      4
      5
      6
      require([ 'selector' , 'book' ], function(query,book) {
           var els = query( '.wrapper' );
       
           book.fun1();
           book.fun2();
      });
      此處query 函數是1的狀況,book 函數是2的狀況。

      五、加載js文件

      到此爲止,咱們遇到了兩個關鍵詞,一個是 define ,能夠用來定義模塊(命名空間),第一部分咱們講了;還有一個是 require,能夠直接加載其餘 js。它除了簡單的用法:
      ?
      1
      2
      3
      <script>
      require( [ "some" ] );
      </script>
      以外,還有和 define 相似的複雜用法:
      ?
      1
      2
      3
      4
      5
      6
      <script>
      require([ "aModule" , "bModule" ], function() {
           myFunctionA(); // 使用 aModule.js 中的函數 myFunctionA
           myFunctionB(); // 使用 bModule.js 中的函數 myFunctionB
      });
      </script>
      總結一下,define 是你定義本身的模塊的時候使用,能夠順便加載其餘js;require 直截了當,供你加載用的,它就是一個加載方法,加載的時候,能夠定義別名。

      六、requ.js插件

      require.js還提供一系列插件,實現一些特定的功能。

      domready插件,可讓回調函數在頁面DOM結構加載完成後再運行。

      ?
      1
      2
      3
      require([ 'domready!' ], function (doc){
         // called once the DOM is ready
      });
      text和image插件,則是容許require.js加載文本和圖片文件。
      ?
      1
      2
      3
      4
      5
      6
      7
      8
      9
      define([
             'text!review.txt' ,
             'image!cat.jpg'
            ],
            function(review,cat){
              console.log(review);
              document.body.appendChild(cat);
            }
          );
      相似的插件還有json和mdown,用於加載json文件和markdown文件。

      七、其餘問題

      一、路徑與後綴名 在 require 一個 js 文件的時候,通常不須要加上後綴名。若是加上後綴名,會按照絕對路徑加載。沒有後綴名,是按照下面的路徑加載:
      ?
      1
      <script data-main= "js/main" src= "js/require-jquery.js" ></script>
      也就是默認加載 data-main 指定的目錄,即 js/main.js 文件所在的目錄。固然,你能夠經過配置文件修改。
      二、define 定義模塊方法只能用在獨立的js文件中,不能在頁面中直接使用。
      不然會報 Mismatched anonymous define() module 錯誤。

      三、在代碼中require一個文件屢次,不會致使瀏覽器反覆加載

      不會,這是 RequrieJS 的優勢,即便你反覆 require 它,它只加載一次。

      八、require深刻

      一、cdn回退 其支持當CDN加載不正確時,回退加載本地相應的庫。咱們能夠經過require.config達到這個目的:
      ?
      1
      2
      3
      4
      5
      6
      7
      8
      requirejs.config({
           paths: {
               jquery: [
                   '//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js' ,
                   'lib/jquery'
               ]
           }
      });
      二、沒有依賴?對象字面量?沒問題!
      當你寫一個沒有任何依賴的模塊,而且只是返回一個對象包含一些功能函數,那麼咱們可使用一種簡單的語法:
      ?
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      define({
           forceChoke: function() {
       
           },
           forceLighting: function() {
       
           },
           forceRun: function() {
       
           }   
      });
      很簡單,也頗有用,若是該模塊僅僅是功能的集合,或者只是一個數據包。
      三、循環依賴 在一些狀況中,咱們可能須要模塊moduleA和moduleA中的函數須要依賴一些應用。這就是循環依賴。
      ?
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      // js/app/moduleA.js
      define( [ "require" , "app/app" ],
           function( require, app ) {
               return {
                   foo: function( title ) {
                       var app = require( "app/app" );
                       return app.something();
                   }
               }
           }
      );
      四、獲得模塊的地址 若是你須要獲得模塊的地址,你能夠這麼作……
      ?
      1
      var path = require.toUrl( "./style.css" );
      五、JSONP
      咱們能夠這樣處理JSONP終端:
      ?
      1
      2
      3
      4
      5
      require( [
      ], function (data) {
           console.log(data);
      });

      九、r.js壓縮

      Require.js 提供一個腳本 r.js ,能夠將全部使用到的模塊壓縮成一個腳本文件,r.js 可使用 node.js 來執行。

      在壓縮模塊前,須要寫一個配置文件,說明主模塊名,壓縮後的文件名,哪些模塊不要壓縮

      沒有使用 define 定義的模塊都不要壓縮,包括 jquery,backbone 等庫及其插件


      ?
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      //build.js
      ({
           baseUrl: '.' ,
           paths: {
           'jquery' : 'empty:' ,
           'underscore' : 'empty:' ,
           'backbone' : 'empty:' ,
         },
           name: 'main' ,
           out: 'main.min.js'
      })
      壓縮命令:
      ?
      1
      node r.js -o build.js
      更多require.js學習連接
相關文章
相關標籤/搜索