RequireJS 的好處 Requires 官方網站這樣說的: (RequireJS is a Javascript fileand module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will imPRove the speed and quality of your code.)RequireJS 是一個 JavaScript 模塊加載器。它非常適合在瀏覽器中使用,但它也可以用在其他腳本環境, 就像 Rhino and Node. 使用 RequireJS 加載模塊化腳本將提高代碼的加載速度和質量。
RequireJS 的初識~~不勝風情 首先我們先使用一個普通的頁面來看看:
<!doctype html><html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript" src="js/test01.js"></script> </head> <body> <h1>Hello requireJS</h1> </body> </html>test01文件:
(function(){ function fn1() { alert("Hello requirejs~~~"); }; fn1(); })();使用閉包寫了一個最簡單的函數,彈出一句話,我們使用閉包的好處就是避免全局變量的出現,這樣就防止了全局變量的污染。 在這段代碼中,我們導入了一個 test01.js 文件,當我們打開頁面時,引入的test01.js 文件加載成功; 我們發現頁面上的內容沒有輸出,js 彈出框在等待用戶的點擊后,頁面才會繼續運行,這樣的結果我們不能接受,因為 js 一般和頁面的加載關,我們應該讓頁面繼續加載,js 執行自己就行了,但是現在阻塞住了頁面的繼續加載,如果某個 js 文件報錯,很有可能導致頁面的正常加載和運行,這是我們不能接受的。 那么如果我們使用 requireJS 呢?首先我們來演示下,大家來看看:
test02.js 文件:
define(function(){ function fn1() { alert("Hello requirejs~~~"); fn1(); });我們看出,首先頁面上不再導入 test02.js,只是導入了 requireJS,其次在 javascript 中我們使用 require()方法,在其中傳遞了一個數組的參數,實參為我們要導入的 js 文件的【路徑+文件名稱(后綴名可帶可不帶,不建議寫,因為后面的網絡訪問時不能寫,為了保持一致,不建議帶)】 ,這樣就完成了 requireJS 的使用,那么運行效果如何呢?
我們發現此時的頁面加載已經完成了,并不像前面我們傳統的一樣在等待 js 運行完成后頁面再加載,而是頁面加載完成后才運行 js 代碼,這樣在運行效率上就大大的提高了。
回過頭來我們看看 test02.js,我們發現和 test01.js 寫法不同的是閉包—()();的寫法改成了 define();在 define 函數中傳遞匿名函數完成操作,這個變化不大,大家應該很好能接受。 基本 API requireJS 會定義三個變量:define、require、requirejs。
1 require === requirejs,一般使用 require 更簡短。 2 define 從名字就可以看出這個 api 是用來定義一個模塊。 3 require 加載依賴模塊,并執行加載完后的回調函數。前面我們寫的 test02.js:
define(function(){ function fn1() { alert("Hello requirejs~~~"); } fn1(); });就是使用 define 來定義了一個模塊,然后使用 require 來引用
<script type="text/javascript"> require(["js/test02"]);//參數為一個數組 </script>來加載該模塊(注意 require 中的依賴是一個數組,即使只有一個依賴,你也必須使用數組來定義),requir API 的第二個參數是 callback,一回調函數,是用來處理加載完畢后的邏輯,如:
require(["js/test02.js"],function(){ alert("js加載完成"); });當所有的模塊都加載完成后就會觸發這個函數。同樣存在了第三個參數,也是一個callback 函數,這個是來處理加載失敗后的情況的,如:
require(["js/test03"],function(){ alert("js加載完成"); },function(){ //當沒有加載成功后就會觸發 //失敗的話,在這個函數中處理 alert("加載失敗~~~"); });此時 test03.js 不存在,頁面肯定加載不成功,所以會觸發第三個參數。 加載網絡文件 之前的例子中加載模塊都是本地 js,但是大部分情況下網頁需要加載的 JS 可能來自本地服務器、其他網站或 CDN,這樣就不能通過這種方式來加載了,我們以加載一個 jquery 庫為例: *//百度cdn公共庫jQuery地址: http://apps.bdimg.com/libs/jquery/2.1.1/jquery.js //jQuery官方地址: https://code.jquery.com/jquery-3.1.1.js*
//注意:網絡上去取時不能加后綴,否則取不到 require.config({ paths : { //為網絡上的庫去一個名字:jquery "jquery" : ["https://code.jquery.com/jquery-3.1.1"] } }); // require(["jquery","js/test01","js/test02"],function(){ alert("頁面加載成功~~"); },function(){ alert("頁面加載失敗~~") });在取網絡上的文件時注意: 1、 config 方法的參數是一個對象 2、 paths 的值也是一個對象 3、 當我們為網絡上的庫取名字是任意,但是建議取有意義的名字,別人可以通過名稱知道你的網絡資源是什么資源 4、 庫的值是一個數組,意味著可以多個同時寫,防止網絡異常取不到 5、 特別注意:網絡資源路徑不能帶后綴名,否則取不到 6、 我們也可以先讓去網絡中去取,如果取不到,再在本地取,減輕本地服務的壓力(屬于項目優化)
require.config({ paths : { //這樣配置,減輕本地服務器的壓力 "jquery" :["https://code.jquery.com/jquery3.1.1.js", "js/jquery-1.8.3"] } }); require(["jquery","js/test01","js/test02"],function(){ alert("頁面加載成功~~"); },function(){ alert("頁面加載失敗~~") });同樣我們也可以將本地的配置到 paths 中:
require.config({ paths : { //這樣配置,減輕本地服務器的壓力 "jquery" : ["https://code.jquery.com/jquery-3.1.1","js/jquery-1.8.3"], //將本地的js文件同樣配置,之后引用 "test01" : ["js/test01"], "test02" : ["js/test02"] } }); // require(["jquery","test01","test02"],function(){ alert("頁面加載成功~~"); },function(){ alert("頁面加載失敗~~") });全局配置 上面的例子中重復出現了 require.config 配置,如果每個頁面中都加入配置,必然顯得十分不雅,requirejs 提供了一種叫”主數據”的功能,我們首先創建一個 main.js:
require.config({ paths : { //這樣配置,減輕本地服務器的壓力 "jquery" : ["https://code.jquery.com/jquery-3.1.1","js/jquery-1.8.3"], //將本地的js文件同樣配置,之后引用 "test01" : ["js/test01"], "test02" : ["js/test02"] } });然后再頁面中使用下面的方式來使用 requirejs:
<script type="text/javascript" src="js/require2.1.11.js" ></script> <script type="text/javascript" src="js/main.js" ></script> <script type="text/javascript"> require(["jquery","t1","t2"],function(){ alert("頁面加載成功~~"); },function(){ alert("頁面加載失敗~~") }); </script>在官方提供了一種基于標簽屬性的方式:
<script data-main="js/main" src="js/require2.1.11.js" ></script>將所有的配置和導入 js 都放在了 main.js 中,這樣在頁面只要這樣一個標簽就行了。 第三方模塊 通過 require 加載的模塊一般都需要符合 AMD 規范即使用 define 來申明模塊,但是部分時候需要加載非 AMD 規范的 js,這時候就需要用到另一個功能:shim,shim 解釋起來也比較難理解,shim 直接翻為”墊”,其實也是有這層意思的,目前我們主要用在兩個地方 非 AMD 模塊輸出,將非標準的 AMD 模塊”墊”成可用的模塊,例如:在老版本的jquery 中,是沒有繼承 AMD 規范的,所以不能直接 require[“jquery”],這時候就需要 shim,比如我要是用 underscore 類庫,但是他并沒有實現 AMD 規范,那我們可以這樣配置`
require.config({ shim: { "underscore" : { } } })這樣配置后,我們就可以在其他模塊中引用 underscore 模塊: require
require(["underscore"], function(_){ _.each([1,2,3], alert); })插件形式的非 AMD 模塊,我們經常會用到 jquery 插件,而且這些插件基本都不符合AMD 規范,比如 jquery.form 插件,這時候就需要將form 插件”墊”到 jquery 中:
require.config({ shim: { "underscore" : { exports : "_"; "jquery.form" : { deps : ["jquery"] } } })也可以簡寫為:
require.config({ shim: { "underscore" : { exports : "_"; }, "jquery.form" : ["jquery"] } })這樣配置之后我們就可以使用加載插件后的 jquery 了
require.config(["jquery", "jquery.form"], function($){ $(function(){ $("#form").AjaxSubmit({...}); }) })其他內容 在回調函數中,我們可以再對應的參數得到加載的 js 對象,如第一個就是 jQuery 對象,第二個和第三個我們自己的 js 中沒有返回對象,所以為 undefined。
<script type="text/javascript" src="js/require2.1.11.js" ></script> <script type="text/javascript" src="js/main.js" ></script> <script type="text/javascript"> require(["jquery","t1","t2"],function($,t1,t2){ //我們在回調函數中可以傳遞參數,這些參數就是require方法中的js對象,如jQuery對象 alert($("body").html()); },function(){ alert("頁面加載失敗~~") }); </script>還是就是在 define 函數中同樣可以傳遞一個數組參數,這個數組參數就是在前面我們已經 config 過的 js 庫或者我們本地的 js 文件,如:
//將要使用的庫可以再這兒引入 define(["jquery"],function($){ function fn1() { alert("Hello requirejs~~~***"); } //alert($(window).scrollTop()); fn1(); });這樣我們在 define 中制作 jQuery 的插件的話,就可以直接使用了
新聞熱點
疑難解答