02.29 想開發webpack插件?先搞懂tapable模塊是如何使用的

這篇文章給大家介紹一個模塊——tapable,它可以專門用來創建鉤子,例如webpack中的鉤子就是用它來創建的。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖1

如圖1所示,tapable提供了很多的構造函數,我們利用這些構造函數就可以創建鉤子。

SyncHook

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖2

如圖2,所有hook構造函數的使用都是先new一個對象,參數是一個數組,這個數組的每個元素和下面tap方法的回調函數的參數是一一對應的。換句話說,這個數組有幾個元素,tap方法的回調函數就有幾個參數。

call方法的參數和tap方法回調函數的參數也是一一對應的,在運行時,圖2中的1、2、3參數將會依次傳入arg1、arg2、arg3中。

咱們運行一下,如下:

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖3

從運行結果看,我們所言不虛,其他的hook的參數傳遞也是如此。

tap方法綁定回調,call方法觸發,h1先執行,h2後執行。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖4

tap方法綁定回調,promise方法觸發,h1先執行,h2後執行。但是hook.promise方法會返回一個promise對象,如果h1、h2執行中有異常,可以在後面直接catch。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖5

tap方法綁定回調,callAsync方法觸發,h1先執行,h2後執行。但是hook.callAsync方法需要多傳入一個回調函數,如果h1、h2執行中有異常,就會把錯誤傳遞給callAsync的回調函數,如果沒有異常,h1和h2完成執行後就會執行callAsync的回調函數。

SyncBailHook

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖6

tap方法綁定回調,call方法觸發,h1先執行,h2後執行。如果h1返回非undefined的值,那麼h2就不會執行,如果h1返回undefined,那麼h2就會執行。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖7

tap方法綁定回調,promise方法觸發,h1先執行,h2後執行。如果h1返回非undefined的值,那麼h2就不會執行,h1的值通過promise對象傳遞出來,如果h1返回undefined,那麼h2就會執行。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖8

tap方法綁定回調,callAsync方法觸發,如果h1返回結果,就會直接執行callAsync的回調,如果沒有再去執行h2,如果h2也沒有返回結果,最後callAsync的回調方法也會被執行。

SyncWaterfallHook

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖9

tap方法綁定回調,call方法觸發,h1先執行,h1的返回結果會當做h2的第一個參數,h2再執行,h2的返回結果會當做h3的第一個參數,h3再執行,h3沒有返回結果,依然把h2的返回結果傳給h4的第一個參數,h4再執行,以此類推。。。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖10

tap方法綁定回調,promise方法觸發,h1先執行,h1的返回結果會當做h2的第一個參數,h2再執行,h2的返回結果會當做h3的第一個參數,h3再執行,h3沒有返回結果,依然把h2的返回結果傳給h4的第一個參數,h4再執行,以此類推,最後通過promise對象返回。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖11

tap方法綁定回調,callAsync方法觸發,執行邏輯和圖9圖10一致,最後通過callAsync的回調函數返回結果。

SyncLoopHook

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖12

tap方法綁定回調,call方法觸發,如果h1返回結果,會再次執行h1,直到h1不返回任何值,然後再去執行h2,如果h2返回結果,會回到h1從頭開始執行,只有h1、h2都不返回值才會執行h3,如果h3有返回值又會回頭從h1開始執行,只有所有回調都沒有返回值,整個執行程序才會結束。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖13

tap方法綁定回調,promise方法觸發,執行邏輯同上。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖14

tap方法綁定回調,callAsync方法觸發,執行邏輯同上。

AsyncParallelHook

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖15

tap方法綁定回調,promise方法觸發,h1、h2、h3會依次執行,最終會返回一個promise對象。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖16

tap方法綁定回調,callAsync方法觸發,h1、h2、h3會依次執行,最後會執行callAsync的回調函數。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖17

tapPromise方法綁定回調,promise方法觸發,每個tapPromise回調函數必須返回一個promise對象,這些promise對象的執行是平行的,只有當這些promise都執行完成才會執行hook.promise的回調函數。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖18

tapPromise方法綁定回調,callAsync方法觸發,執行邏輯同圖17。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖19

tapAsync方法綁定回調,promise方法觸發,tapAsync回調函數的最後一個參數都會傳入一個callback,只有每個callback都執行完成,hook.promise返回的promise對象才會執行。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖20

tapAsync方法綁定回調,callAsync方法觸發,執行邏輯同上。

AsyncParallelBailHook

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖21

tap方法綁定回調,promise方法觸發,h1如果有結果返回,h2、h3都不會執行,h1沒有結果返回,才會執行h2,h2有結果返回,h3就不會執行,以此類推。。。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖22

tap方法綁定回調,callAsync方法觸發,執行邏輯同圖21。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖23

tapPromise方法綁定回調,promise方法觸發,無論h1何時返回,只要h1有值,那麼最終的結果就是h1的值,如果h1沒有值,那麼看h2有沒有值,以此類推。。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖24

tapPromise方法綁定回調,callAsync方法觸發,邏輯同圖23。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖25

tapAsync方法綁定回調,promise方法觸發,cb全部執行,hook.promise返回的promise對象才會執行,返回的結果是tapAsync回調的第一個有值的結果。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖26

tapAsync方法綁定回調,callAsync方法觸發,邏輯同圖25。

AsyncSeriesHook

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖27

tap方法綁定回調,promise方法觸發,h1、h2、h3會順序執行。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖28

tap方法綁定回調,callAsync方法觸發,h1、h2、h3會順序執行。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖29

tapPromise方法綁定回調,promise方法觸發,h1先執行,h2再執行,最後h3才執行,順序執行。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖30

tapPromise方法綁定回調,callAsync方法觸發,邏輯同圖29。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖31

tapAsync方法綁定回調,promise方法觸發,邏輯同圖29。

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖32

tapAsync方法綁定回調,callAsync方法觸發,邏輯同圖29。

AsyncSeriesBailHook

想開發webpack插件?先搞懂tapable模塊是如何使用的

圖33

tap方法綁定回調,promise方法觸發,h1先執行,如果h1有返回結果,h2、h3就不會再執行,h1無返回結果,才會繼續執行h2、h3,以此類推。。。

其他的情況作者就不寫了,我相信聰明的你肯定找到了規律。還剩一個hook構造函數AsyncSeriesWaterfallHook,小夥伴們可以自己嘗試寫寫看看有什麼樣的執行邏輯。

總結

如果你想要了解webpack,或者想開發一個webpack的插件,搞清楚tapable模塊是必須的。一部分邏輯綁定事件,一部分邏輯觸發事件,本質是還是發佈訂閱邏輯。


喜歡我的文章就關注我吧,有問題可以發表評論,我們一起學習,共同成長!


分享到:


相關文章: