原文: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的作者玉伯給出了非常明確的答案