上個星期寫了淺入requirejs的, 你們都知道 require是AMD規範(Asynchronous Module Definition)html
來 今天咱們一塊兒看看 CMD規範(Common Module Definition) 的seajs 是怎樣實現的api
seajs比require寫的簡單, 源碼幾乎是require的一半,gzip後差距是拉近了,可是仍以爲大。
(最近對size很敏感 ,由於領導 大領導抱怨咱們h5站點打開慢,今年咱們逐步作提速的事情, 我內心暗下一個目標,無論業務簡單複雜 3G及以上用戶,我要作到全站秒開 作到了跟你們分享一下 哈哈)
閉包
結束前戲 直入主題 哈哈
sea裏面一共就用到幾個api異步
sea.config ------ 配置函數
sea.use ------ 加載 並執行模塊(能夠是多個)
define ------ 定義模塊
require ------ 同步引入模塊
require.async ------ 異步引入模塊
exports ------ 導出單個屬性
module.exports ----- 導出整個模塊async
詳細用法 :http://www.zhangxinxu.com/sp/seajs/docs/zh-cn/cheatsheet.html#exports函數
目錄結構很簡單 定義了一個main.js 2個define的 模塊requirejs
//main.js // 全部模塊都經過 define 來定義 define(function(require, exports, module) { // 經過 require 引入依賴 var code = require('module/code'); var game = require('module/game'); console.log('code' , code); console.log('game' , game); code.codeAction(); game.gameAction(); });
//code.js define(function(require, exports, module) { exports.name = 'code'; exports.skill = 'play'; exports.codeAction = function() { console.log('coding'); }; // 或者經過 module.exports 提供整個接口 /* module.exports = { codeAction: function() { console.log('coding'); } }*/ });
//game.js define(function(require, exports, module) { // 或者經過 module.exports 提供整個接口 module.exports = { gameAction: function() { console.log('gaming'); } } });
首先我以爲sea的源碼有點有意思的地方,他真的是 「那裏用到, 那裏定義」 看過我上一篇requrejs的文章的同窗知道 我喜歡先把代碼疊起來 一覽衆山小,這招用不了在sea身上fetch
你們看ui
像不少人都有這麼一個強迫症,就是 因此定義都放在最開始的地方統必定義了, sea說 我偏不, 我哪裏用到, 那裏定義 哈哈 氣死處女座spa
for in 每個屬性, 處理好後 掛在 閉包全局的data裏
首先 seajs.use 會調用 Module.use , 而後 cid是每次調用自動++ 生成全局惟一標記,
Module.use 第一行, 初始化mod的屬性, 而後真正處理是mod.load(),注意 這裏的掛了callback函數 還有 callback後刪除變量 釋放內存
而後 module.load裏 會判斷這個模塊是否加載過, 若是沒有加載過,會調用fetch方法,加載過 直接調用m.load()
而後fetch方法裏 會把加載的模塊的真實地址爲key 生成requestCache[emitData.requestUri] = sendRequest ,賦值內部函數 sendRequest,而後sendRequest調用內部onRequest
758line fetch函數生成模塊的請求關係後, 而後 留意768 真正執行這個fetch函數
而後執行request函數 addOnload 會綁定模塊獲取成功的onload和onerror函數,392,script真正插入到頁面中。
順便補充一句, sea很奇怪, 加載成功use後,會remove這個script, 我沒搞懂這個用意何在, 節省了頁面一個script?
由於2個函數 是有關係的, 能夠是你中有我,我中有你, 因此就不拆開了。
先看define ,前面幾行是處理參數的, 過
主要看deps,這裏其實就是解析define裏的關鍵字,是否含有require,看控制檯輸出
這個470行到672行 其實就是require的實現, 純粹是個體力 、嚴謹、 技巧活 ,各類字符串處理,各類正則匹配, 沒有遇到的場景,寫不出來, 純粹我的看法。
而後再執行onRequest方法, 再次執行m.load方法解析modules裏的依賴模塊,若是存在就像剛纔use裏獲取main同樣,獲取模塊,執行callback
exports其實很簡單的, 其實就是一個空的obj,而後把你須要的屬性都掛在這個exports對象裏面
每個define裏都有一個屬於本身的exports 不會污染別的模塊
不用說你也懂了吧? 就是全部屬性都只能寫在module裏,看我上圖exports下面有個exports.module的註釋, 其實就是換個寫法罷了
好剩下
其實就是use的實現,加一個callback而已
看源碼 ,這麼聰明的你 ,確定一眼就懂了
好 寫了一個下午了, 有點累, 準備一下去健身房, 樓主很瘦 怕猝死 若是你知道有很好的增肥方法, 請告訴我 哈哈哈。
最後 若是此文對你有幫助, 記得點贊哦, 你的點贊,是我繼續創做的動力。