區(qū)分幾種模塊加載器(AMD,CMD...)

異步加載是現(xiàn)在已經(jīng)不是一個熱門的話題了。 雖然不熱門了,但他更成為了每一個JSer的基本功。 再次看玉伯博客上推seajs的文章和第一次看的心情已經(jīng)大有不同。特別是玉伯博客 這篇文章。

我學(xué)習(xí)seajs已經(jīng)是3年前的時候了,還記得當(dāng)時看到異步加載覺得很NB??戳四瞧恼潞笥X得seajs ‘a(chǎn)s lazy as possible' 明顯比requirejs 要好...
現(xiàn)在看看評論區(qū)大家就知道兩個東西真正的區(qū)別了。


言歸正傳

用更科學(xué)的方式來區(qū)分amd(requirejs), cmd(seajs), commonJS

首先站在框架設(shè)計者的角度,思考一個模塊加載器要做什么事

0、分析模塊代碼依賴的文件
1、下載文件
2、 JS加載文件

現(xiàn)在我們考慮一種seajs和commonJS中的場景

\\ a.js
if(flag){
require('b');
}else{
require('c');
}

上面代碼 b和c 只有一個會執(zhí)行。 那么我們這兩個文件是否都需要去下載?

動手實(shí)踐發(fā)現(xiàn)seaj 把兩個文件都下載了。 但只加載了一個文件。
commonjs因?yàn)椴恍枰紤]下載,文件都在本地。所以自然是同步執(zhí)行代碼,用到了再去本地加載執(zhí)行。


再看requireJS的場景

require(['b','c'], function(b,c){
if( flag ){
  b();
}else{
  c();
}
});

在動手得知, requirejs也是都下載了2個文件,并且b和c都被JS加載了。

這里的加載指的是b和c在使用到之前已經(jīng)是一個對象。
而在seajs中 到 var b = require('b') ;這行之前 b文件只是一個字符串。

requirejs轉(zhuǎn)化為seajs相當(dāng)于

\\ a.js
var b =  require('b');
var c = require('c');
...
1000行代碼
...
if(flag){
 c();
}else{
 b();
}

這兩個的區(qū)別現(xiàn)在就顯而易見了。 requirejs 在模塊被使用到之前就先準(zhǔn)備好。 seajs在用到的時候再去準(zhǔn)備模塊。

這里我們可以發(fā)現(xiàn)seajs 比 requirejs 少做了沒用的事,更有效率。

但是我們再考慮一種特殊情況比如c模塊中如果會報錯。
那requirejs在一開始就 拋出了錯誤。
而seajs在執(zhí)行到的時候拋出錯誤。
但是! 注意那1000行代碼。 如果c報錯了, 那1000行代碼還有必要執(zhí)行嗎?我們還能回滾那1000行代碼嗎?

這里我們就真正理解了requirejs這樣設(shè)計的原因。seajs用好了能更加極致,用不好就會出上面這種可怕的錯誤。


現(xiàn)在我們已經(jīng)知道設(shè)計一個模塊加載器要做什么和需要注意的點(diǎn)了。
讓我們做個整理。

如果在node端不需要下載文件。 我們則讓代碼同步加載 即Commonjs。

如果在瀏覽器端, 則都需要提早下載文件, 執(zhí)行到一半去下載1秒鐘這可不行。當(dāng)然我們可以提供異步下載的實(shí)現(xiàn), require.async 。
下載完文件后是否應(yīng)該先提前準(zhǔn)備模塊? 是 AMD, 否CMD。

希望看完你可以知道你需要哪一種了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容