seajs源碼閱讀

乘着週日有點時間,閱讀一下玉伯大神的源碼。html

seajs的源碼寫得真的很好,非常佩服,工整美觀不愧是大神,造福百姓。segmentfault

 

提及seajs不得不說,AMD和CMD的區別。app

 CMD 推崇依賴就近,AMD 推崇依賴前置。
 
事實上我對他們的區別沒啥興趣。關鍵是requirejs沒明顯的BUG,seajs明顯沒BUG。
 
二者最大區別請看這裏:http://www.cnblogs.com/gyjWEB/p/4543945.html
 
好了,扯正題。
 
能夠先看看別人寫的源碼解析:https://segmentfault.com/a/1190000000471722
 
我只補上模塊的加載過程.首先,弄個簡單的DEMO。
 
<!DOCTYPE html>
<html>
<head>
    <title>seajs源碼閱讀</title>
</head>
<body>
    <script src="seajs-2.2.3/dist/sea-debug.js"></script>
    <script>
        seajs.use("./application",function(){
        })
    </script>
</body>
</html>

 

很簡單的代碼,使用application.js作主文件.下面是application.js源碼.requirejs

define(function(require,exports,module){
    var test = require('ModuleTest');
});

application.js只依賴了ModuleTest.fetch

 

seajs.use爲入口.會先預加載,而後再調用Module.use.ui

seajs.use = function(ids, callback) {
  //預加載,預加載的模塊能夠經過seajs.config設置
  Module.preload(function() {
    //開始了
    Module.use(ids, callback, data.cwd + "_use_" + cid())
  })
  return seajs
}

 

Module.use的代碼很關鍵.一開始會建立一個模塊就叫作入口模塊吧,這個模塊是沒有id的,並且這個模塊會依賴主模塊,更關鍵的是,這個入口模塊有callback,其餘模塊是沒有callback。spa

Module.use = function (ids, callback, uri) {
  var mod = Module.get(uri, isArray(ids) ? ids : [ids])
  //模塊回調,加載完了以後就執行
  mod.callback = function() {
    //......
  }
  //加載模塊
  mod.load()
}

 

入口模塊的callback,最終會在Module.prototype.onload調用prototype

Module.prototype.onload,不得不扯Module.prototype.load.下面是load的流程.debug

 

大致流程:3d

 

demo中:

會建立入口模塊,設置入口模塊的callback,加載入口模塊。

因爲入口模塊依賴了"application模塊",就會fetch "application模塊",fetch成功就會調用"application模塊"中的define。

define會算出"application模塊"的依賴,也就是"ModuleTest模塊",而後回到load,繼續fetch "ModuleTest模塊"。

繼續回到"ModuleTest模塊"的load,這時候「ModuleTest模塊」的remain爲0,就會調用"ModuleTest模塊"的onload,而後根據waittings調用"application模塊"的onload。

最後就是入口模塊的onload.最後的最後,全部的模塊exec。KO。

吃完飯,再弄張圖,千言萬語不如一張圖。

相關文章
相關標籤/搜索