高能預警,前方山路十八彎html
在上一篇文章裏簡單的討論了一下模塊化Js, 先來回顧一下目前模塊化的兩大規範:jquery
CommonJs 同步加載模塊規範gulp
AMD/CMD 異步加載模塊規範app
其中CMD規範的產出是國內目前十分火爆的SeaJs, 這篇文章主要是解釋幾個使用SeaJs會碰到的重要概念異步
具名模塊模塊化
匿名模塊函數
路徑即ID原則grunt
SeaJs定義匿名模塊通常採用以下的方式:工具
define(function(require,exports,module){xx})
SeaJs定義除了定義匿名模塊,還能夠定義具名模塊ui
//define(BlockID,[Deps],function(require,exports,module){}) define(‘A’,[],function(require,exports,module){xx})
其中能夠
第一個參數 定義該模塊的名字(即ID),用來惟一標識該模塊
第二個參數 把該模塊依賴的模塊從函數體裏提到參數中,用來標識該模塊還依賴了哪些模塊
第三個參數 模塊主體
誠然,咱們能夠把全部模塊都以匿名的形式書寫。但這樣有個很大的缺點,就是模塊化會致使Js文件特別多,這樣無形中會加大了http請求的數
咱們在知道,在文件比較小的時候, 文件的大小並不顯著影響http的下載速度, 可是若是把這個文件拆成兩個文件下載,增長的一次http開銷確是很大的
因此,不少狀況下咱們須要把零碎的Js模塊進行合併成一個文件。可是這麼多模塊合併在一個文件裏,全是匿名的話,系統如何區別哪一個是哪一個模塊呢? 所以,咱們須要對這些模塊給不一樣的ID進行標識。 因而這些帶了ID的模塊,就叫作具名模塊
上面解釋了什麼是具名模塊,爲何須要用具名模塊,咱們如今就來給具名模塊命名
SeaJs遵循的是路徑即ID命名規則,意思就是具名模塊的ID名是路徑的一部分. 而沿着最終拼接出來的路徑,確定能夠找獲得這個具名模塊
聽起來很繞,但這個規則很是很是很是重要.做者也是在理解SeaJs路徑的過程當中踩坑無數,這裏就來重點講一下
首先來看SeaJs的路徑的書寫種類,總的來講,能夠分爲3種.
相對路徑(以相對路徑符開頭,好比../js/
), 路徑以本頁面爲起點
直接路徑(以直接目錄開頭,好比js/
), 路徑以baseUrl爲起點
根路徑(以根路徑開頭, 好比/app/js/
) 路徑以項目根目錄爲起點
這裏拿入口文件index.html舉例:
<!--例1--> <script> seajs.config({ base: "../js/", alias:{"JQ":"lib/jquery"} }) seajs.use("src/index.js") </script>
base
參數是以當前頁面(index.html)爲參照,設定基礎相對路徑baseUrl.
在本例中base
設定採用相對路徑的形式, 那麼baseUrl = (index.html的位置) + (../js/)
alias
可以給具名模塊(例子中該匿名模塊ID爲lib/jquery)取別名(JQ),取別名的好處在於能夠把具名模塊自己很是冗長的路徑命名變得很短很小清新,通常是針對頁面須要引用的庫文件.
在本例中JQ 後的路徑是採用直接路徑的形式, 那麼JQ的路徑= (baseUrl) + (lib/jquery) = (index.html的位置)+ (../js/) + (lib/jquery/
)
sea.use
用來指定SeaJS加載器的入口, 經過在入口js再加載七七八八頁面所需的JS模塊達到按需加載的目的
在本例中,sea.use的路徑是採用直接路徑的形式, 那麼入口文件index.js的路徑 = (baseUrl) + (src/index.js) = (index的位置) + (../js/) + (src/index.js)
若是換一種形式寫:
<!--例2--> <script> seajs.config({ base: "../js/", alias:{"JQ":"../js/lib/jquery"} }) seajs.use("../js/src/index.js") </script>
base設定採用相對路徑的形式, 那麼baseUrl = (index.html的位置) + (../js/)
alias JQ 後的路徑是採用相對路徑的形式, 那麼JQ的路徑= (index.html的位置) + (../js/lib/jquery)
sea.use的路徑是採用相對路徑的形式, 那麼入口文件index.js的路徑= (index.html的位置) + (../js/src/index.js)
如今拿例1來講:
<!--例1--> <script> seajs.config({ base: "../js/", alias:{"JQ":"lib/jquery"} }) seajs.use("src/index.js") </script>
既然alias中具名模塊叫lib/jquery, 那麼你的jquery經過define定義的模塊ID必定是lib/jquery
define(‘lib/jquery’,[],function(require,exports,module){xx})
又因爲alias
中具名模塊(lib/jquery)
的採用了直接路徑的方式, 根據路徑即ID的原則,你應該能夠順着 (baseUrl) + (lib/jquery)
找到該具名模塊的位置,若是找不到,確定會報錯
如今拿例2來講:
<!--例2--> <script> seajs.config({ base: "../js/", alias:{"JQ":"../js/lib/jquery"} }) seajs.use("../js/src/index.js") </script>
既然alias中具名模塊叫../js/lib/jquery, 那麼你的jquery經過define定義的模塊ID必定是../js/lib/jquery
define(‘../js/lib/jquery’,[],function(require,exports,module){xx})
又因爲alias
中具名模塊(../js/lib/jquery)
的採用了相對路徑的方式, 根據路徑即ID的原則,你應該能夠順着 index.html當前位置 + (../js/lib/jquery)
找到該具名模塊的位置,若是找不到,確定會報錯
但實際的使用上,咱們基本不會去寫具名模塊, 而是所有寫匿名模塊
而後經過自動化構建工具(好比grunt,gulp,fis3)的插件去自動解決匿名模塊具名化的問題,好比grunt就提供了相關插件:
grunt-cmd-transport 將匿名模塊轉換成具名模塊
grunt-cmd-concat 將具名模塊合併壓縮到一個Js文件裏
SeaJs大法好,Grunt大法好 但在使用這些工具的之時,並非簡單抄一兩個demo就完事. 不少狀況下你要根據本身工程的特性來調整目錄結構,而模塊所在的路徑
,和模塊的ID
, 和最後JS合併壓縮
的過程息息相關. 因此必須理解它們的規則,運用起來才能更加駕輕就熟