(一)入口瀏覽器
經過 data-main 去加載 JS 模塊,是經過 req(cfg) 入口去進行處理的。閉包
爲了跟蹤,你能夠在此 加斷點 進行調試跟蹤。函數
(二)fetch
req({ })執行時,function newContext() 已經建立了上下文環境 context。咱們能夠看看 context 擁有哪些屬性與方法。ui
經過執行 context.confgiure(config)便可加載 data-main所對應的js文件(main.js)。spa
當req(cfg)執行,config值 如右圖所示---------prototype
在context.confgiure()函數最後一行代碼中,開始執行 context.require() .調試
context.require(...),其中 context.require = context.makeRequire();code
其中,makeRequire() 以及 localRequire() 這裏已經造成了閉包。對象
由於在 req( { } )調用makeRequire()時 ,已經直接返回 localRequire(),所以 context.require(..),直接進入 localRequire()函數。
localRequire()函數裏,作很不少事,可是,因爲此時 全局隊列,局部隊列( defQueue、globalDefQueue,) 都爲空,暫時不考慮 intakeDefines(),
重點看看 context.nextTick()這裏到底作了些什麼處理。
若是Module 不存在,則建立一個新的Module;存在,則直接返回。咱們能夠看看建立的 requireMod 擁有哪些屬性值呢?
. Module對象採用 混合構造方式,將方法都寫在了 原型鏈上。
Module = function (map){ }; Module.prototype = { init: function() { }, //用於初始化屬性
load: function () { } };
整個 data-main 中的 js 文件 主 加載順序以下
requireMod.init() ===>
Module..enable() //init()方法內部調用 ===>
Module.check() ===> Module.fetch() ===> Module.load() ===> context.load() ===> req.load() ===> context.onScriptLoad()
Module.init() Module.check() 都是 對 main Module進行信息處理,最後得到了 data-mian 中js文件的路徑,控制器又回到了 req.load() 手裏
請看下面核心代碼。
req.load() 先建立了一個<script src="main.js"></script> 標籤,給其注入了一自定義屬性,
綁定了一個事件而後,將這個標籤<head></head>標籤中,這樣,瀏覽器自動會去加載這個js文件。
從頁面上,咱們能夠清晰的看到,會多了一行代碼。
至此,data-main 文件的加載 過程,已經梳理完成。