亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

深入探尋seajs的模塊化與加載方式

2019-11-20 12:41:34
字體:
來源:轉載
供稿:網友

由于一直在使用,所以了解了下seajs的源代碼。這里是我對下面幾個問題的理解:

1、seajs的require(XXX)的方法是怎樣實現模塊加載的?

2、為什么需要預加載?

3、為什么需要構建工具?

4、構建前后的代碼究竟有些什么區別,為什么要這么做?

問題1: seajs的require(XXX)的方法是怎樣實現模塊加載的?

代碼邏輯比較繞,對源代碼的理解放在文章的末尾,這里先簡單梳理下模塊加載的邏輯:

1、從seajs.use方法入口,開始加載use到的模塊。

2、use到的模塊這時mod緩存當中一定是不存在的。seajs創建一個新的mod,賦予一些初始的狀態。

3、執行mod.load方法

4、一堆邏輯之后走到seajs.request方法,請求模塊文件。模塊加載完成之后,執行define方法。

5、define方法分析提取模塊的依賴模塊,保存起來。緩存factory但不執行。

6、模塊的依賴模塊再被加載,如果繼續有依賴模塊,則繼續加載。直至所有被依賴的模塊都加載完畢。

7、所有的模塊加載完畢之后,執行use方法的callback.

8、模塊內部邏輯從callback開始執行。require方法在這個過程當中才被執行。

問題2:為什么需要預加載?

我們看到seajs.use方法實際上是在所有依賴模塊都加載完了之后才執行callback。可以理解成在業務邏輯代碼在執行之前,必須先預加載所有被依賴的模塊代碼。那么為什么是一個這樣必須先做預加載的邏輯?

答案在于邏輯代碼里面引用其他模塊方法的這個require方法的執行方法:

var mod = require(id);

這個語法決定了mod的取得是個同步執行的過程,如果模塊代碼在此之前沒有被預加載的話,就只能采用異步加載回調的方法來實現了,那么整個seajs的執行邏輯將完全會是另一個樣子。因為異步你會搞不懂模塊的執行順序,邏輯會變的難以掌控。

問題3:為什么需要構建工具?

可以看到沒有構建前各個依賴模塊都是單獨加載的。這會產生過多的模塊請求,對于頁面的加載性能是不利的。構建工具本質上就是為了解決模塊合并加載的問題。

問題4:構建前后的代碼究竟有些什么區別,為什么要這么做?

構建工具究竟做了些什么。我們說它本質上是為了解決代碼合并加載的問題,那么它所做的只是簡單的將各個模塊文件合并成一個文件?

當然不是。測試一下,你如果只是簡單把幾個模塊文件合并到一個文件以后,會發現這個文件根本沒有辦法正常執行。

原因在于define方法的實現。

seajs是推崇定義模塊的時候只在define方法傳入factory參數的?;仡檇efine方法內部,當沒有傳入id(姑且等同于模塊的url)時,會通過getCurrentScript()方法去取得當前正在執行的這個模塊文件的url路徑,然后把這個路徑作為鍵值與模塊本身一起緩存到cachedMods。這里很關鍵的一點是,整個seajs內部的這個模塊緩存機制其實是依賴每個模塊的url來做緩存的鍵值。require(id)方法,歸根結底也是通過url鍵值到。require(id)方法,歸根結底也是通過url鍵值到cachedMods里面去找相應的模塊。這個鍵值不能重復不能出錯,不然模塊的對應關系就混亂了。如果把a、b、c幾個模塊文件簡單合并到一個目標文件x之后,getCurrentScript()只能獲取到x的路徑,三個模塊的鍵值就沒法做出區別了,執行肯定出錯。

所以如果要把幾個模塊文件合并在一起,就必須為每個模塊明確uri。也就是define方法必須都傳入id參數。當id傳入的時候,seajs會將這個id轉換為url用作緩存的鍵值。

如果只傳id和factory,也就是 define(id, factory),那么deps = undefined,define方法就會去執行parseDependencies(factory.toString())方法提取factory里面的依賴模塊,后續會走到解析模塊路徑,線上單獨加載各個模塊的邏輯里面去,這個時候就失去了合并加載的意義了。

所以合并加載,define方法必須正確的傳入id,deps,factory三個參數才能正確執行。

seajs 所謂CMD的模塊定義方法,是提倡大家寫模塊的階段都只傳factory一個參數的,其他兩個參數在后期代碼構建的階段來生成。上面解釋了為什么這兩參數在構建后是必須的。

至于為什么提倡定義模塊的時候只傳factory,我看主要是因為手工傳入的id和deps參數,極易出錯,不便維護。工具可以提高效率并保證參數的正確。

附: 對seajs 主要代碼邏輯的理解。

說明:源代碼版本是Sea.js 2.3.0

1、先看看define方法做了些什么

Module.define = function (id, deps, factory)

define方法的時候,支持三個參數。其中id,deps是選填的。factory必須。代碼里面通過以下邏輯來控制:

但其實deps是必須的,因為seajs必須知道每個模塊依賴了哪些模塊,不然無法執行加載。

所以,當factory是函數,并且deps沒有被主動傳入的時候,就需要使用parseDependencies方法來分析出factory當中的依賴模塊了。

parseDependencies方法做的事情主要就是用一個正則表達式把函數體里面所有require(XXX)里面的XXX提取出來,這也就是這個函數依賴到的所有模塊了。

方法本身不復雜,但是這個正則表達式不簡單:

分析完deps之后,將模塊定義存入緩存:

注意,我們會發現define方法純粹只是分析模塊、存儲模塊,并沒有執行模塊。

2、真正執行模塊,是在require方法里面。我們接下來看require。

簡而言之require方法就是根據id在define定義存儲的模塊緩存中找到相應的模塊,并執行它,獲得模塊定義返回的方法:

整個這個大步驟中,有一個很關鍵的步驟,有必要細說:

Module.get(require.resolve(id))。

require一個模塊的時候,首先要找到這個模塊。 Module.get方法就起這個作用。

cachedMods里面沒有的話,就創建一個新的Module并緩存到cachedMods里面:

define和rquire方法這樣看來不算復雜。seajs主要還是模塊加載的邏輯有點復雜。

3、seajs真正執行的入口,是use方法:

通過use方法,從這里的ids開始觸發模塊的加載和執行。

可以看到加載的關鍵點在mod.load方法。

load方法代碼有點長,其中的主要邏輯是:判斷mod的當前狀態是否為已加載或者加載中。

在Module的舒適化函數中,我們可以看到status默認值是0.

所以沒有加載過的新模塊,到這里都是: mod.status = STATUS.LOADING 狀態設置為加載中,并執行后續加載邏輯。

接來下是獲取模塊的依賴urls

mod.resolve方法:

Module.resolve方法本質上就是把相對路徑、配置的path、別名等轉換成一個絕對路徑。不貼代碼了。

更新模塊加載狀態。

加載模塊的邏輯:

主要是m.fetch方法,里面其他邏輯這里略過。

可以看到 seajs.request最終會去執行模塊文件的加載:

當所有依賴模塊加載完了之后,執行mod的onload方法

這里是 mod.onload()方法

到此,seajs的核心邏輯就差不多都看到了。供參考,有理解不到位或者表達不準確的地方,歡迎一起探討。

以上所述就是本文的全部內容了,希望大家能夠喜歡。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲风情亚aⅴ在线发布| 国产盗摄xxxx视频xxx69| 亚洲国产精品福利| 久久久女人电视剧免费播放下载| 亚洲欧美第一页| 伊人伊成久久人综合网小说| 欧美激情小视频| 日韩精品久久久久久福利| 欧美极品美女电影一区| 欧美一二三视频| 午夜精品一区二区三区在线播放| 中文字幕一精品亚洲无线一区| 亚洲美女精品成人在线视频| 97人人爽人人喊人人模波多| 中文字幕日韩精品在线| 岛国av一区二区| 亚洲欧洲在线观看| 亚洲人成欧美中文字幕| 亚洲国模精品一区| 97精品国产97久久久久久春色| 亚洲第一国产精品| 自拍亚洲一区欧美另类| 欧洲亚洲免费在线| 国产一区二区日韩精品欧美精品| 久久99热这里只有精品国产| 粗暴蹂躏中文一区二区三区| 日韩免费在线观看视频| 欧美成人免费全部观看天天性色| 成人在线精品视频| 欧美日韩国产精品一区| 91在线视频导航| 疯狂做受xxxx欧美肥白少妇| 91中文字幕在线| 欧美高清电影在线看| 中文字幕日韩av| 57pao成人国产永久免费| 亚洲欧美在线第一页| 91美女片黄在线观| 欧美黑人性生活视频| 久久久久久久一区二区三区| 日本亚洲欧洲色α| 色综合久久中文字幕综合网小说| 欧美一级淫片aaaaaaa视频| 一区二区成人av| 亚洲色图综合久久| 久久激情视频久久| 色偷偷偷亚洲综合网另类| 欧美激情亚洲视频| 久久久女女女女999久久| 日本一区二三区好的精华液| 欧美情侣性视频| 日韩精品视频中文在线观看| 精品视频久久久久久| 欧美另类在线观看| 91av在线网站| 在线播放日韩专区| 亚洲欧美中文日韩在线| 亚洲欧洲在线视频| 中文字幕亚洲无线码在线一区| 国产精品国产自产拍高清av水多| 国产成人精品一区| 成人午夜两性视频| 国产精品视频色| 中文字幕日本精品| 91午夜在线播放| 久久精品色欧美aⅴ一区二区| 欧美日韩成人网| 日韩av网址在线观看| 欧美自拍大量在线观看| 久久av红桃一区二区小说| 欧美日韩人人澡狠狠躁视频| 国产亚洲精品美女久久久久| 日韩成人网免费视频| www.久久草.com| 日韩免费高清在线观看| 日韩国产精品亚洲а∨天堂免| 色哟哟网站入口亚洲精品| 国产激情久久久| 欧美亚洲视频在线看网址| 国内精品久久久久影院优| 亚洲美女性生活视频| 欧美最近摘花xxxx摘花| 色噜噜狠狠色综合网图区| 中文字幕欧美日韩精品| 亚洲一区二区三区sesese| 日韩激情在线视频| 欧美电影在线观看网站| 992tv成人免费影院| 欧美大片网站在线观看| 国产色视频一区| 亚洲成人激情在线观看| 97涩涩爰在线观看亚洲| 亚洲欧美国产精品专区久久| 国产999精品久久久影片官网| 国产91在线播放精品91| 亚洲欧美中文日韩v在线观看| 亚洲人成网在线播放| 欧美成人精品一区二区| 精品欧美国产一区二区三区| 社区色欧美激情 | 国产精品免费一区豆花| 欧美一级在线亚洲天堂| 尤物99国产成人精品视频| 国产精品日韩在线观看| 成人h片在线播放免费网站| 亚洲天堂开心观看| 亚洲国产精品国自产拍av秋霞| 精品综合久久久久久97| 欧美一区二区三区图| 久久久久国色av免费观看性色| 97碰碰碰免费色视频| 欧美成人精品在线| 久久久久久久一区二区三区| 欧美成人h版在线观看| 日韩三级影视基地| 日韩一级裸体免费视频| 国产精品爽爽爽爽爽爽在线观看| 亚洲欧美在线一区| 国产91在线播放精品91| 国产精品视频自在线| 亚洲精品久久久久中文字幕二区| 精品久久久久久久久国产字幕| 成人黄色大片在线免费观看| 91精品国产777在线观看| 91精品久久久久久久| 日韩精品中文字幕在线播放| 成人xxxxx| 欧美精品生活片| 国产精品高潮粉嫩av| 欧美极品第一页| 亚洲国产免费av| 97在线视频国产| 欧美大片在线看| 日本成人在线视频网址| 国产精品高潮呻吟久久av野狼| 一个人看的www欧美| 久久99精品久久久久久噜噜| 亚洲偷欧美偷国内偷| 亚洲欧美日韩一区在线| 91青草视频久久| 久久精品国产视频| 国产z一区二区三区| 亚洲第一天堂无码专区| 欧美成人亚洲成人日韩成人| 久久免费少妇高潮久久精品99| 91亚洲精品久久久久久久久久久久| 亚洲电影免费观看高清完整版在线| 久久久久久一区二区三区| 久久精品视频在线| 久久国产一区二区三区| 成人精品久久久| 国产日韩视频在线观看| 中文字幕日韩av| 久久久国产精品免费| 亚洲色图欧美制服丝袜另类第一页| 国产玖玖精品视频| 日韩在线视频网| 国产主播欧美精品| 欧美国产乱视频| 久久综合伊人77777| 久久综合国产精品台湾中文娱乐网| 日韩**中文字幕毛片| 久久久精品免费| 一区二区三欧美|