前端模塊化(五):RequireJs
1 概述
RequireJS是一個JS模塊加載器,遵循AMD規範。它主要是為了實現JS文件的異步加載以及管理模塊之間的依賴性。下面,我們通過一下例子來了解requirejs的使用。
2 RequireJs的使用
首先,我們創建一個項目,主要文件目錄如下:
2.1 加載模塊
在使用requieJS模塊化開發之前,我們需要下載require.js,可以通過npm下載或者在官網獲得。然後,創建兩個文件index.html以及index.js,示例代碼一如下:
//index.html <!DOCTYPE html> <html> <head > <title>require栗子</title> </head> <body> <div> <h1>這是require栗子</h1> <button id="clickBtn">點擊展開</button> <p id="showMsg"></p> </div> <script data-main="js/ctr/index" src="js/lib/require.js" type="text/javascript"></script> </body> </html>
//js/ctr/index.js require.config({ paths: { ‘jquery‘: ‘../lib/jquery‘ } }); require([‘jquery‘], function($) { $(document).on(‘click‘, ‘#clickBtn‘, function() { $(‘#showMsg‘).html(‘看看jquery加載進來了沒有‘); }); });
使用<script>標簽來引入requireJS,這個是毫無疑問的。然後在<script>標簽中發現有個data-main屬性,這是什麽意思呢?在index.js文件中出現的require.config以及require有什麽作用呢?下面,我們逐一分析一下。
2.1.1 data-main
data-main屬性,它的作用是作為一個出入口,指定入口主模塊。也就是說,require.js會在加載完成以後通過回調方法去加載這個data-main裏面的js文件,所以這個js文件被加載的時候,RequireJS已經加載執行完畢。在示例代碼一中,加載完requirejs後,便會根據data-main屬性加載js/ctr/index.js文件。
data-main還有一個重要的功能,當script標簽指定data-main屬性時,require會默認的將data-main指定的js為根路徑。在上面的實例代碼一中,把js/ctr作為了根目錄,相當於默認設置了配置,示例代碼二如下:
require.config({ baseUrl : "js" })
當然,這個默認設置被index.js裏面的require.config配置所覆蓋,所以沒有生效。
2.1.2 require.config
require.config的作用就是配置requireJS的一些參數,然後公共引用。config函數需要傳入一個可選參數對象,這個可選參數對象包括了許多的配置參數選項。這些配置參數選項的主要作用如下:
- baseUrl——用於加載模塊的根路徑。
- paths——用於映射不存在根路徑下面的模塊路徑。
- shims——配置在腳本/模塊外面並沒有使用RequireJS的函數依賴並且初始化函數。
- deps——加載依賴關系數組
在示例代碼一中,我們定義了jquery文件的路徑,設置了模塊名為‘jquery’。 這裏,require是以當前主模塊index.js路徑為起點去尋找jquery.js文件的,所以在paths配置項中,我們設置的jquery路徑要‘../’回到上級目錄才能尋找到jquery。在主模塊中,調用的時候可以直接使用模塊名‘jquey’,require會根據config配置項中定義的路徑去加載js/lib/jquery.js。require.config的配置項優先權高於data-main,可以覆蓋data-main的默認配置。
2.1.3 require
require函數用於加載模塊依賴但並不會創建一個模塊。
require()函數接受兩個參數。第一個參數是一個數組,表示所依賴的模塊,上例就是[‘jquery‘],即主模塊依賴這個模塊;第二個參數是一個回調函數,當前面指定的模塊都加載成功後,它將被調用。加載的模塊會以參數形式傳入該函數,從而在回調函數內部就可以使用這些模塊。
在上面的實例代碼一中,require函數異步加載了jquery模塊,瀏覽器不會失去響應;它指定的回調函數,只有前面的模塊都加載成功後,才會運行,由此解決了模塊依賴性的問題。
2.1.4 加載擴展
在示例代碼一中,把require.config()放在index.js裏面,這樣子不夠優雅。我們應該把require.config()抽出來,單獨放在一個js文件裏面,這樣方便移植和復用。下面,我們修改idnex.js,把require.config()抽出來放在js/ctr/config.js中。示例代碼三如下:
// js/ctr/config.js總配置文件 define(function () { require.config({ paths: { ‘jquery‘: ‘../lib/jquery‘ } }); })
// js/ctr/index.js require([‘config‘],function(){//加載配置文件 require([‘jquery‘], function($) { $(document).on(‘click‘, ‘#clickBtn‘, function() { $(‘#showMsg‘).html(‘看看jquery加載進來了沒有‘); }); }); })
2.2 define模塊定義
require.js加載的模塊,采用AMD規範。也就是說,模塊必須按照AMD的規定來寫。
具體來說,就是模塊必須采用特定的define()函數來定義。如果一個模塊不依賴其他模塊,那麽可以直接定義在define()函數之中。
創建一個文件a.js,它定義了一個modA模塊。示例代碼四如下:
//js/ctr/a.js define(function (){ var funA = function (x,y){ return x+y; }; return { funA: funA }; });
//js/ctr/index.js require([‘jquery‘, ‘a‘], function ($ ,modA){ $(document).on(‘click‘, ‘#clickBtn‘, function() { $(‘#showMsg‘).html(‘看看jquery加載進來了沒有‘); }); console.log(modA.funA (1,1));//在控制臺輸出結果2 });
2.3 加載非AMD規範的模塊
通過require加載的模塊一般都需要符合AMD規範即使用define來申明模塊,但是部分時候需要加載非AMD規範的js,這時候就需要用到另一個功能:shim。shim是require.config配置對象中的一個屬性,專門用來配置不兼容的模塊。具體來說,每個非AMD規範模塊要定義exports值和deps數組。
(1)exports值(輸出的變量名),表明這個模塊外部調用時的名稱。我們有時候會用到underscore類庫,但是他並沒有實現AMD規範,那我們可以這樣配置,示例代碼五如下:
require.config({ shim: { "underscore" : { exports : "_"; } } })
這樣配置後,我們就可以在其他模塊中引用underscore模塊,示例代碼六如下:
require(["underscore"], function(_){ _.each([1,2,3], alert); })
(2)deps數組,表明該模塊的依賴性。例如,我們經常會用到jquery插件,而且這些插件基本都不符合AMD規範,比如jquery.form插件,這時候就需要將form插件"墊"到jquery中,示例代碼七如下:
require.config({ shim: { "jquery.form" : { deps : ["jquery"], exports: ‘jqueryForm‘ } } })
3 總結
本文對RequireJS的使用做了簡單的介紹,大家如有需要對RequireJS進行更深入的了解,可以直接看源碼或者查看官方API文檔。下一篇我們開始介紹CMD規範,進一步了解模塊化的演進。
前端模塊化(五):RequireJs