Requirejs源碼閱讀

接著上文的學(xué)習(xí)以及嘗試實現(xiàn),準(zhǔn)備好好看下源碼的實現(xiàn)。

var requirejs, require, define;
(function (global, setTimeout){...}(this ,setTimeout));

整體結(jié)構(gòu)就是放出了3個全局的變量,然后在一個匿名函數(shù)中對3個變量進行賦值。這里把this和setTimeout傳進去應(yīng)該是歷史原因,怕這些東西被改寫

然互看匿名函數(shù)的整體的結(jié)構(gòu):

  • 最先申明了一些簡寫以及使用到的正則以及瀏覽器屬性的判斷。
  • 然后申明了一些簡單的輔助方法,包括一些循環(huán),還有對象的檢測。
  • 然后是一個主要的方法newContext。這個很長,慢慢看。
  • 然后申明了require方法
  • 然后調(diào)用了req({});進行了最初的初始化
  • 然后遍歷拿到script,來得到data-main的入口,與我的寫法一樣
  • 然后申明了define方法
  • 然后再執(zhí)行了一次req(cfg);用配置好的cfg

執(zhí)行的主要流程

主要是就是執(zhí)行了一次req({});然后初始化了cfg,然后再執(zhí)行了一次req(cfg)。

這里函數(shù)執(zhí)行的比較復(fù)雜,我花了一些時間畫了一個圖,畫的精疲力盡:

requirejs.png

圖里面其實已經(jīng)畫的很詳細(xì)了,我的圖只是其中一種執(zhí)行的順序,簡單總結(jié)就是

  • 第一次req()初始化環(huán)境
  • 第二次req()開始加載入口的模塊
  • define函數(shù)實際上往全局的隊列推入
  • 模塊加載好了會執(zhí)行onScriptLoad方法,然后進行一層層的事件通知(注意事件是綁在依賴的模塊上的,出發(fā)后,執(zhí)行父模塊的回調(diào),然后再emit調(diào)用父模塊的回調(diào))
  • 內(nèi)部還是有輪詢在不斷的檢查時候加載好的,我個人感覺是為了處理error事件,他本身的加載過程并不依賴與這個輪詢
  • 他內(nèi)部支持commonjs的方式其實就是用個正則表達(dá)式來進行檢索,然后推入deps正常加載,換了個形式騙騙人..

小的tip

nextTick里面的4ms是因為html5的規(guī)范要求的

順便給個github的傳送門,喜歡的朋友star一下啊,自己平時遇到的問題以及一下學(xué)習(xí)的思考都會在上面記錄~

參考:

http://www.cnblogs.com/yexiaochai/p/3632580.html

http://www.cnblogs.com/zhiyishou/p/4770013.html

http://www.nihaoshijie.com.cn/index.php/archives/381
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容