文/墨箏
咱們在使用webpack的時候常常會用到webpackbar或者progress-bar-webpack-plugin之類的webpack插件經過進度條等方式來展現webpack的構建進度,以提高構建過程當中的反饋體驗。對於不一樣的插件來講,它們只是進度條的UI展現形式不一樣而已,但最核心的webpack構建的實時進度的數據來源倒是一致的,均由webpack內部的ProgressPlugin
這個插件提供。下面我會結合源碼來說解該插件是如何計算webpack的構建進度並將進度數據暴露給第三方的進度條插件。在閱讀下文以前能夠試着問下本身:若是是你,你會如何計算webpack的構建進度。前端
該插件主要根據webpack的構建階段來定義當前進度值。webpack的構建過程分爲不少不一樣的階段,在每一個階段webpack都暴露了對應的事件鉤子。ProgressPlugin
正是經過這些事件鉤子對每一個階段都定義了一個基礎進度值,代碼以下所示:
webpack
上述代碼中的interceptHook
方法能夠先忽略,這個後續會提到。git
經過上述代碼你會發現ProgressPlugin
給 compiler
中的每一個鉤子都設置了一個指定的進度值。但這些進度值還不夠細緻到反映webpack的詳細構建過程,中間還差了0.06到0.69以及0.69到0.95兩個階段的數值。webpack構建的具體執行過程主要在compilation
中,這兩個階段的數值由compilation
的鉤子填充。github
0.06~0.69
web
update方法的調用由compilation的鉤子觸發,以下所示:
npm
這個階段的主要工做是module
,entry
以及dependencies
的處理和構建。換個角度從ProgressPlugin
給該階段設置的進度值來看,這部分工做也是webpack最耗時的地方。微信
0.69~0.95
函數
從上述代碼中能夠看出這個間隔段就徹底是根據compilation的hooks來計算和指定當前的構建進度值,從hook的描述中能夠看出這個階段主要是module
, chunk
以及assets
等資源的優化工做。優化
基本上整個webpack構建過程的進度值就是根據上述中的 compiler
和 compilation
的hooks來設置的。插件
webpack的構建進度肯定以後剩下的任務就是將進度數據透出給第三方的進度條插件進行展現。要完成該任務須要ProgressPlugin
完成兩件事情,一是提供回調函數的切入口;二是須要能在對應的hook節點執行該回調函數進行進度的百分比值的傳入。如下是這兩點的實現原理
ProgressPlugin
定義了handler函數來做爲回調函數切入,代碼以下所示:
hook劫持的實現很是簡單,主要利用webpack hook原生提供的intercept
方法,前文中提到的interceptHook
方法只是對於intercept方法的封裝,示例代碼以下:
webpack構建的進度條實現原理就是如此簡單,給每一個構建階段對應的hook設置一個進度值,而後經過handler回調和hook劫持切入到構建環節將進度信息傳入回調函數,最終第三插件經過handler獲取到進度值後將其展現出來。
webpack的不少其餘功能其實也沒有想象中的那麼複雜和高大上,經過閱讀其源代碼瞭解其實現原理後,你極可能會一拍大腿,大嘆一聲原來如此,這自己就是一件挺有意思的事兒。
繼續打招聘廣告,阿里巴巴業務平臺體驗技術團隊招聘資深前端以及前端技術專家,歡迎投遞簡歷。
郵箱:mozheng.sh@alibaba-inc.com微信:longmaost