30分鐘 帶你淺入seajs源碼

上個星期寫了淺入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函數

demo

目錄結構很簡單 定義了一個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

 

config函數

for in 每個屬性, 處理好後 掛在 閉包全局的data裏

 

use函數

首先 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?

 

define,require函數

由於2個函數 是有關係的, 能夠是你中有我,我中有你, 因此就不拆開了。
先看define ,前面幾行是處理參數的, 過

主要看deps,這裏其實就是解析define裏的關鍵字,是否含有require,看控制檯輸出

這個470行到672行 其實就是require的實現, 純粹是個體力 、嚴謹、 技巧活 ,各類字符串處理,各類正則匹配, 沒有遇到的場景,寫不出來, 純粹我的看法。 

 

而後再執行onRequest方法, 再次執行m.load方法解析modules裏的依賴模塊,若是存在就像剛纔use裏獲取main同樣,獲取模塊,執行callback

 

 

exports

exports其實很簡單的, 其實就是一個空的obj,而後把你須要的屬性都掛在這個exports對象裏面

每個define裏都有一個屬於本身的exports  不會污染別的模塊

 

exports.module

不用說你也懂了吧? 就是全部屬性都只能寫在module裏,看我上圖exports下面有個exports.module的註釋, 其實就是換個寫法罷了

好剩下

require.async  

其實就是use的實現,加一個callback而已

看源碼  ,這麼聰明的你 ,確定一眼就懂了

 

 

好  寫了一個下午了, 有點累, 準備一下去健身房, 樓主很瘦  怕猝死  若是你知道有很好的增肥方法, 請告訴我  哈哈哈。

最後  若是此文對你有幫助, 記得點贊哦, 你的點贊,是我繼續創做的動力

相關文章
相關標籤/搜索