- 原文地址:http://wushaobin.top/2019/02/12/webpackPrinciple/
對於webpack的認識始終停留在對腳手架的使用,不得不說腳手架既方便又好用,修改起來也方便,只需要知道webpack中各個配置項的功能,於是對於我們來說,webpack始終就是一個黑盒子,我們完全不清楚裡面是如何去運作的。打包時報錯,就只能藉助google來協助幫忙解決問題,至於為什麼要這樣解決,什麼原理,不管,能解決就好。那麼,瞭解一下基本原理也是有必要。
概念
言歸正傳,我們一起了解一下webpack執行基本原理,首先先明白幾個核心概念,
- Entry:入口,webpack構建的起始
- Module:模組,webpack裡面一切皆模組,也是代表著檔案,從Entry配置的入口檔案開始,遞迴找出依賴的模組
- Chunk:程式碼塊,找出遞迴依賴模組經轉換後組合成程式碼塊
- Loader:模組轉換器,也就是將模組的內容按照需求裝換成新內容
- Plugin:擴充套件外掛,webpack構建過程中,會在特定的時機廣播對應的事件,而外掛可以監聽這些事件的發生
流程
webpack構建流程,詳細過程如下:
- 初始化:從配置檔案或是shell讀取與合併引數,得到最終引數,例項化外掛new Plugin()
- 開始編譯:通過上一步初始化得到的最終引數,初始化一個Compiler物件,載入外掛(依次呼叫外掛中的apply方法),通過執行Compiler.run開始編譯
- 確定入口:根據配置中entry找出所有入口檔案
- 編譯模組:從entry出發,呼叫配置的loader,對模組進行轉換,同時找出模組依賴的模組(如何找?見下文),依次遞迴,直到所有依賴模組完成本步驟處理
- 完成模組編譯:這一步已經使用loader對所有模組進行了轉換,得到了轉換後的新內容以及依賴關係
- 輸出資源: 根據入口與模組之間的依賴關係,組裝成一個個chunk程式碼塊,並且生成檔案輸出列表
- 輸出成功:根據配置中的輸出路徑和檔名,將檔案寫入檔案系統,完成構建
事件
整個構建流程會發生很多的事件,來供Plugin監聽,這些事件具體的可以分為三個階段,分別是初始化階段
、編譯階段
、輸出階段
,那麼具體有哪些事件,這裡按階段分別介紹,
初始化階段
事件 | 作用 |
---|---|
初始化 | 從配置檔案或是shell讀取與合併引數,得到最終引數,依次例項化外掛new Plugin() |
例項化Compiler | 通過上一步初始化得到的最終引數,初始化一個Compiler物件,負責監聽檔案和啟動編譯,全域性只有一個Compiler物件 |
載入外掛 | 依次呼叫外掛中的apply方法,同時也會將Compiler例項傳入,就可以呼叫Webpack提供的api,Compiler例項可以說是就是Webpack的例項 |
environment | 將node.js風格的檔案系統應用到compiler物件,便可以直接通過compiler來對檔案進行操作 |
entry-option | 讀取配置中的entry,依次例項化出對應EntryPlugin,為後面該entry的遞迴解析工作做準備 |
after-plugins | 調完所有內建和配置的外掛的apply方法 |
after-resolvers | 根據配置初始化resolvers,resolvers負責在檔案系統中尋找制定路徑的檔案 |
編譯階段
事件 | 作用 |
---|---|
run | 啟動一次新的編譯,呼叫Compiler.run() |
watch-run | 和run類似,區別在於它是在監聽模式下進行編譯的,這個事件可以獲取哪些檔案發生了變化從而導致新的一次編譯 |
compile | 告訴外掛新的一次編譯即將啟動,並且給外掛帶上compiler物件 |
compilation | 每當檢測到檔案的變化,都會有一次新的compilation被建立,一個compilation物件包含了當前的模組資源、編譯生成的資源、變化的檔案等等的屬性和方法,同時記住,在很多事件的的回撥中都會將compilation傳入,以便使用 |
make | 一個新的Compilation建立完畢,那麼就會從entry配置中開始讀取檔案,使用配置好的loader對檔案進行編譯,編譯完後再找出檔案依賴的檔案,遞迴地去編譯和解析 |
after-compile | 一次Compilation執行完成 |
invalid | 檔案編譯錯誤等異常觸發該事件,不會導致webpack退出 |
Compilation的事件
事件 | 作用 |
---|---|
build-moudle | 使用對應的loader去轉換一個模組 |
normal-module-loader | 在用loader轉換一個模組後,會使用acorn解析轉換後的內容輸出對應的抽象語法樹(ast),以便webpack後面分析程式碼使用 |
program | 從配置的入口開始,分析生成的ast,遇到require等匯入語句時,便會將其加入依賴模組列表,並且對找出的依賴進行遞迴分析,最終可以弄清所有依賴關係 |
seal | 所有模組及其依賴的模組都通過Loader轉換完成,根據依賴關係生成chunk |
輸出階段
事件 | 作用 |
---|---|
should-emit | 所有需要輸出的檔案都生成,準備輸出,詢問哪些檔案需要輸出,哪些不需要輸出 |
emit | 確定好要輸出哪些檔案後,並執行檔案輸出,可以在這裡獲取和修改輸出的內容 |
after-emit | 檔案輸出完畢 |
done | 完成一次完整的編譯和輸出流程 |
failed | 編譯和輸出過程中運到異常,導致webpack退出,會直接到這個步驟,可以在這裡獲取具體原因 |
總結
Webpack是很好的前端資源載入和打包工具,在webpack裡一切皆模組
,很好地處理檔案之間的依賴關係,這裡我們介紹的是些理論性的知識,瞭解基本概念,知道整個流程是怎麼樣的,webpack是序列流水線執行的,工作期間會有很多廣播事件,來供外掛使用,這裡我們介紹了各個階段的事件以及作用,具體程式碼表示形式,後續文章會引入。