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。

吃完饭,再弄张图,千言万语不如一张图。

相关文章
相关标签/搜索