App下載

webpack 構建進度條 ProgressPlugin 源碼剖析

猿友 2020-09-07 11:59:45 瀏覽數 (4901)
反饋

文章轉載自公眾號:墨箏

前言

我們在使用 webpack 的時候經常會用到 webpackbar 或者 progress-bar-webpack-plugin 之類的 webpack 插件通過進度條等方式來展示 webpack 的構建進度,以提升構建過程中的反饋體驗。對于不同的插件來說,它們只是進度條的 UI 展示形式不同而已,但最核心的 webpack 構建的實時進度的數據來源卻是一致的,均由 webpack 內部的 ProgressPlugin 這個插件提供。下面我會結合源碼來講解該插件是如何計算 webpack 的構建進度并將進度數據暴露給第三方的進度條插件。在閱讀下文之前可以試著問下自己:如果是你,你會如何計算 webpack 的構建進度。

構建進度的計算

該插件主要根據 webpack 的構建階段來定義當前進度值。webpack 的構建過程分為很多不同的階段,在每個階段 webpack 都暴露了對應的事件鉤子。ProgressPlugin 正是通過這些事件鉤子對每個階段都定義了一個基礎進度值,代碼如下所示:

webpack 構建進度條 ProgressPlugin 源碼剖析

上述代碼中的 interceptHook 方法可以先忽略,這個后續(xù)會提到。 通過上述代碼你會發(fā)現(xiàn) ProgressPlugincompiler 中的每個鉤子都設置了一個指定的進度值。但這些進度值還不夠細致到反映 webpack 的詳細構建過程,中間還差了 0.06 到 0.69 以及 0.69 到 0.95 兩個階段的數值。webpack構建的具體執(zhí)行過程主要在 compilation 中,這兩個階段的數值由 compilation 的鉤子填充。

0.06~0.69 webpack 構建進度條 ProgressPlugin 源碼剖析

update 方法的調用由 compilation 的鉤子觸發(fā),如下所示:

webpack 構建進度條 ProgressPlugin 源碼剖析

這個階段的主要工作是 module,entry 以及 dependencies 的處理和構建。換個角度從 ProgressPlugin 給該階段設置的進度值來看,這部分工作也是 webpack 最耗時的地方。

0.69~0.95 webpack 構建進度條 ProgressPlugin 源碼剖析

從上述代碼中可以看出這個間隔段就完全是根據 compilation 的 hooks 來計算和指定當前的構建進度值,從hook 的描述中可以看出這個階段主要是 module, chunk 以及assets等資源的優(yōu)化工作。 基本上整個 webpack 構建過程的進度值就是根據上述中的 compilercompilation 的 hooks 來設置的。

進度數據的透出

webpack 的構建進度確定之后剩下的任務就是將進度數據透出給第三方的進度條插件進行展示。要完成該任務需要ProgressPlugin完成兩件事情,一是提供回調函數的切入口;二是需要能在對應的 hook 節(jié)點執(zhí)行該回調函數進行進度的百分比值的傳入。以下是這兩點的實現(xiàn)原理

回調函數

ProgressPlugin 定義了 handler 函數來作為回調函數切入,代碼如下所示:

webpack 構建進度條 ProgressPlugin 源碼剖析

hook 劫持

hook 劫持的實現(xiàn)非常簡單,主要利用 webpack hook 原生提供的intercept方法,前文中提到的interceptHook方法只是對于 intercept 方法的封裝,示例代碼如下:

webpack 構建進度條 ProgressPlugin 源碼剖析

結語

webpack 構建的進度條實現(xiàn)原理就是如此簡單,給每個構建階段對應的 hook 設置一個進度值,然后通過 handler 回調和 hook 劫持切入到構建環(huán)節(jié)將進度信息傳入回調函數,最終第三插件通過 handler 獲取到進度值后將其展示出來。 webpack 的很多其他功能其實也沒有想象中的那么復雜和高大上,通過閱讀其源代碼了解其實現(xiàn)原理后,你很可能會一拍大腿,大嘆一聲原來如此,這本身就是一件挺有意思的事兒。

以上就是W3Cschool編程獅關于webpack 構建進度條 ProgressPlugin 源碼剖析的相關介紹了,希望對大家有所幫助。

0 人點贊