Webpack學習-工作原理(上)

xiaobin發表於2019-02-17
  • 原文地址: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是序列流水線執行的,工作期間會有很多廣播事件,來供外掛使用,這裡我們介紹了各個階段的事件以及作用,具體程式碼表示形式,後續文章會引入。

相關文章