require.js用法以及原理


原文:https://www.cnblogs.com/wangzhihui/articles/8824168.html

requireJs可以解決文件依賴加載問題,例如 JS1依賴於JS2,JS2依賴JS3,JS3依賴JS4,文件加載就應該是 JS4 JS3 JS2 JS1。但是我只想使用JS1中的函數,其他的我不想管,就用到了requireJS 按需加載,我只需要加載JS1,其他的都交給require來做。

用法:

舉一個栗子 我要做一個給數組排序的功能,一個HTML,一個test.js,一個sort.js(給JS排序),一個isarr.js(判斷傳入的參數是否為數組),給一個數組排序首先要判斷傳入的參數是否為數組,如果為數組進行排序,否則返回錯誤信息。

 

HTML

<script src="js/require.js" data-main="js/test"></script>

// data-main 為requireJs 的依賴文件入口 H5規定自定義屬性最好以‘date-’開頭

 

 

//test.js

復制代碼
require(['sort'],function(sort) {

var arr = [1,4,8,11,25];

console.log(sort(arr));

})
復制代碼

 

 

//sort.js

復制代碼
define(['isarr'],function(isArr){

// ‘isarr’(藍色) 為sort 依賴文件。 isArr(黃色)為導入的isArr,雖然可以隨便寫,但是最好和依賴文件函數保持一致

  function sort(arr) {

    if (isArr(arr)) {

      return arr.sort(function(a,b) {

        return a - b; //數組排序

      })

    }else{

      return "傳入的參數不是數組";

    }
  }

  return sort;

})

 
復制代碼

 

//isarr.js

復制代碼
define(function() {

  function isArr(arr) {

    if(arr.constructor == Array && arr instanceof Array){

/*判斷arr是否為數組

 *1. typeof arr 返回值的是Object 而不是Array 所以無法判斷

 *2. arr.constructor(構造函數或叫構造器),能找到arr數組的構造函數是Array 沒有引                           號“”  

 *3. arr instanceof Array 可以判斷數組類型

 */

    return true;

   }

   return false;

}

return IsArr;

})
復制代碼

 

 

原理:

既然文件加載有效,那requireJS是怎么實現加載的呢? 我們打開工具發現body中並沒有多出<script>標簽,但是在<head>中發現了我們依賴的兩個JS文件,requireJS是怎么加載的呢?

 

 

其中一個<script>

<script type="text/javascript" charset="utf-8" async="" data-requirecontext="_" data-requiremodule="sort" src="js/sort.js"></script>

 requireJS加載的文件比我們自己寫的文件多出了三個屬性  async,data-requirecontent和data-requiremodule。

其中data-requiremodule指向的是需要加載的模塊。

1.async 和 defer

而async是一種異步加載。 異步加載有兩種,defer和async。下圖是正常加載和defer異步加載與async異步加載的解析加載對比

 

 

正常加載是 解析HTML 遇見了JS 就去下載然后立刻執行

defer 異步加載是解析HTML遇見JS,異步的去下載JS,在最后去執行。所以defer加載從理論上能保證JS文件的加載順序。

async 異步加載是解析HTML遇見JS,異步去下載JS,然后立刻執行。所以async不一定能保證JS文件加載順序。如果JS文件比較小的情況下可能后被加載先執行。

defer和async的區別是什么呢? defer是IE提出的語法,async是標准瀏覽器提出的語法。兼容性問題不太一樣,功能也不一樣。他們都叫Js的異步加載都會增加瀏覽器對JS的加載速度。

如果文件增加了async或者defer,文件里是不能夠寫document.write(),會報錯

2. AMD和CMD

AMD(Asynchronous Module Define) 異步模塊化定義

CMD(Common Module Define) 通用模塊化定義

其實模塊化開發框架不只有requireJS  還有一個seaJS 這個框架是一個阿里程序員玉伯開發的。

其中seaJS的寫法為

復制代碼
//seaJS 寫法

define(function(require) {

  var arr = [1,4,8,11,25];

  //此處省略100行業務邏輯

  var sort = require('sort');//導入依賴的排序函數

  console.log(sort(arr));

})

 

//requireJS

require(['sort'],function(sort) {

  var arr = [1,4,8,11,25];

  //此處省略100行業務邏輯

  console.log(sort(arr));

})
復制代碼

 

觀察以上兩種寫法,

第一種寫法是依賴就近,就是你寫了很多很多業務邏輯,等你想用的時候再加載依賴的方法。先聲明后加載。

第二種寫法是依賴前置,就是不管你什么時候用這個方法,聲明require時就要把依賴的方法加載進來。先聲明先加載。

其中SeaJS的寫法在requireJS-2.0版本也支持。

在百度上搜索 ’AMD CMD的區別‘ 在知乎上,seaJS的作者玉伯給出了非常明確的答案

 

 


免責聲明!

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



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