使用require.js

requirejs使用入門javascript

什麼是requirejs?

  RequireJS的目標是鼓勵代碼的模塊化,它使用了不一樣於傳統<script>標籤的腳本加載步驟。能夠用它來加速、優化代碼,但其主要目的仍是爲了代碼的模塊化。它鼓勵在使用腳本時以module ID替代URL地址。html

RequireJS以一個相對於baseUrl的地址來加載全部的代碼。 頁面頂層<script>標籤含有一個特殊的屬性data-main,require.js使用它來啓動腳本加載過程,而baseUrl通常設置到與該屬性相一致的目錄。java

 

爲何要使用require.js?

  咱們在作項目的過程當中,每每都須要加載不少個js文件,以下所示:jquery

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

 

  這樣的寫法的缺點是Js會阻塞渲染頁面,而且文件越多, 那麼等待的時間也就越長,而且文件多的狀況下每每還存在文件間依賴的問題, 有時候比較複雜,那麼文件間的依賴就成了問題。git

  因此require.js主要就是爲了解決下面的兩個問題:github

(1)實現js文件的異步加載,避免頁面失去響應。ajax

(2)管理項目之間的依賴性,便於代碼的維護和管理。api

 

如何使用require.js?

  require.js下載地址數組

  使用require.js很是簡單,只須要在頁面中使用一個require.js便可,以下所示:瀏覽器

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>require</title>
  <script src="./require.js" data-main="js/main" type="text/javascript"></script>
</head>
<body>
  <!-- your code is here -->
</body>
</html>

 

  即咱們在html文件中只須要使用一個require.js文件的引入便可,而後data-main引入的是網頁程序的主模塊,這個文件會被require.js第一個加載,因爲require.js默認文件的後綴名爲.js,因此這裏咱們寫成main便可。

  

如何寫主模塊main.js

  什麼是主模塊?

    主模塊就是入口文件,它是require.js加載執行的第一個文件,這就是主模塊,而且其餘的全部js文件將在這裏被引入執行。

  爲何要使用主模塊?

    咱們知道require.js在index.html惟一的被引入,而沒有引入其餘js文件,這也是爲了方便管理。 那麼內部機制就要求須要這麼一個主模塊,而後就能夠很好的管理模塊之間的關係,試想若是沒有這麼一個主模塊,那麼require.js也會無從下手的。

  main.js中怎麼寫呢? 若是咱們只須要這一個js就夠了,好比就執行alert("hello");那麼main.js文件中只有這麼一句:

alert("hello");

  而後打開html文件時,就會alert("hello");了,可是咱們使用require.js不可能就使用這麼一個文件,不然就不用require了。 

  真正的狀況是: 主文件main.js依賴於其餘文件, 這時就要使用AMD規範來定義require()函數。以下所示:

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

  即接受的第一個參數是一個數組,指定模塊名稱(不帶.js的文件), 而後第二個參數是一個函數,其中的參數暴露出了模塊中暴露的方法,而後咱們就能夠在回調函數中使用這些模塊了。

  require()異步加載moduleA,moduleB和moduleC,瀏覽器不會失去響應;它指定的回調函數,只有前面的模塊都加載成功後,纔會運行,解決了依賴性的問題。

  

  例子

  好比以前的index.html中的body部分是<div class="wrap"></div>,而後引入了require.js並指定了main.js爲入口文件,在main.js中定義以下:

require(['jquery'],function ($) {
  $('.wrap').html("hello, world!");
});

  即咱們只引入了jquery,而且在回調函數中將$暴露出來並使用,那麼啓動index.html文件以後,咱們就能夠在頁面上看到渲染的hello, world了。 注意: 此時的目錄結構以下:

     

  因此:咱們須要注意下面的幾點:

  • require.js會默認認爲require()中第一個參數數組裏的文件和main.js在同一個目錄下
  • 咱們引入的文件即jquery.js,由於默認是.js後綴,因此咱們直接寫文件名便可。
  • 在require的回調函數中,咱們使用回調函數中的接口,即若是這裏沒有定義爲$,而是定義爲foo,那麼咱們就須要使用foo。 

  、

存在的問題若是說依賴文件(如jquery)何main.js文件再也不同一個目錄中該怎麼引用呢

  好比如今的目錄時這樣的:

      

 

  那麼如今咱們就會發現,你在require函數的第一個參數中寫成'jquery'或者‘lib/jquery’或者‘../lib/jquery’或者‘./lib/jquery’都是沒法成功的

  這時咱們就須要使用require.config()方法對路徑進行配置了。以下所示:

require.config({
  paths: {
    jquery: '/lib/jquery'
  }
});

 

  若是有多個文件,而且多個文件在一樣的目錄下,咱們能夠定義一個baseUrl, 以下:

  require.config({
    baseUrl: "js/lib",
    paths: {
      "jquery": "jquery.min",
      "underscore": "underscore.min",
      "backbone": "backbone.min"
    }
  });

  若是某個模塊在另外一個主機上,咱們能夠直接定義其網址:

 require.config({
    paths: {
      "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"
    }
  });

 

 

 

如何定義模塊?

  在使用require時,咱們用的是AMD的規範進行加載的,因此在定義模塊時,也是須要使用AMD規範來定義模塊。

  好比如今咱們在和main.js同一個目錄下定義一個alert模塊:

define(function () {
    var alertName = function (str) {
      alert("I am " + str);
    }
    var alertAge = function (num) {
      alert("I am " + num + " years old");
    }
    return {
      alertName: alertName,
      alertAge: alertAge
    };
  });

  即便用define定義,其中接受一個回調函數做爲參數,在這個回調函數中定義模塊,最後返回一個對象,對象的屬性就是咱們能夠調用的方法。

  而後咱們看看如何在main.js中使用:

require(['alert'], function (alert) {
  alert.alertName('JohnZhu');
  alert.alertAge(21);
});

  即便用也很是簡單,就是引入alert模塊,而後調用其中的alertName和alertName方法便可。  

 

  問題:若是一個模塊在定義時須要依賴其餘模塊怎麼辦?

  好比這個alert模塊須要依賴jquery,那麼咱們就能夠這麼定義:

  define(['jquery'],function () {
      var alertName = function (str) {
        alert("I am " + str);
        $('.wrap').html("I am " + str);
      }
      var alertAge = function (num) {
        alert("I am " + num + " years old");
      }
      return {
        alertName: alertName,
        alertAge: alertAge
      };
    });

  即咱們直接將define的第一個參數(一個數組)中使用jquery, 而後直接使用便可。

  • 注意: 這裏顯然使用jquery的使用默認路徑仍是和main.js在同一個目錄下。
  • 這裏咱們沒有在回調函數中傳入參數,可是是能夠傳的,只是省略了,若是我傳入foo,那麼就能夠用foo(".wrap").html("I am " + str);來使用。
  • 因而main.js在加載alert模塊時,會等到jquery模塊加載完再執行其中的回調函數。 

 

 

加載非規範的模塊

  理論上,require.js加載的模塊,必須是按照AMD規範、用define()函數定義的模塊。可是實際上,雖然已經有一部分流行的函數庫(好比jQuery)符合AMD規範,更多的庫並不符合。那麼,require.js是否可以加載非規範的模塊呢?

   答案是能夠的,可是須要在使用require以前,用require.config()方法定義一些他們的特徵。

  require.config({
    shim: {

      'underscore':{
        exports: '_'
      },
      'backbone': {
        deps: ['underscore', 'jquery'],
        exports: 'Backbone'
      }
    }
  });

 

  以前咱們介紹過require.config中的paths,這裏又介紹了shim對象,它專門用來配置不兼容的模塊。具體來講,每一個模塊要定義:

  (1)exports值(輸出的變量名),代表這個模塊外部調用時的名稱;

  (2)deps數組,代表該模塊的依賴性。

   好比,咱們能夠這樣定義一個jquery插件:

  shim: {
    'jquery.scroll': {
      deps: ['jquery'],
      exports: 'jQuery.fn.scroll'
    }
  }

  即deps說明他是須要依賴jquery的, exports說明能夠經過juqery的scroll訪問到它。

  

 

require.js插件

  requirejs還提供了一系列的插件供咱們使用。

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

 require(['domready!'], function (doc){
    // called once the DOM is ready
  });

  text和image插件,則是容許require.js加載文本和圖片文件。

  define([
    'text!review.txt',
    'image!cat.jpg'
    ],

    function(review,cat){
      console.log(review);
      document.body.appendChild(cat);
    }
  );

  

 

補充例子

  最近看到有人相似於這樣使用require。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>require</title>
  <script src="./require.js" type="text/javascript"></script>
</head>
<body>
  <!-- your code is here -->
  <div class="wrap">
    
  </div>
  <script>
    require(['js/dosomething']);
  </script>
  <script src="js/jquery.js"></script>
</body>
</html>

  dosomething是這樣的:

alert('god');
  • 即咱們使用require來引入模塊,可是dosomething這個模塊並無按照AMD規範來編寫。 
  • 咱們能夠看到利用require的好處在於能夠異步加載文件。 這種用法的好處就是在於require的文件會異步加載。
  • 而且在咱們引入的目的僅僅是執行一些功能,而不須要暴露出方法來,因此能夠直接寫

 

  

 

 

 

 

 

 

 

參考文檔:

http://www.requirejs.cn/

http://www.ruanyifeng.com/blog/2012/11/require_js.html

相關文章
相關標籤/搜索