文章目錄
webpack 的作用是將源代碼編譯(構建、打包)成最終代碼
整個過程大致分爲三個步驟:
- 初始化
- 編譯
- 輸出
1、初始化–融合CLI參數、配置文件、默認配置
此階段,webpack會將CLI參數、配置文件、默認配置
進行融合,形成一個最終的配置對象。
對配置的處理過程是依託一個第三方庫yargs完成的
此階段相對比較簡單,主要是爲接下來的編譯階段做必要的準備
目前,可以簡單的理解爲,初始化階段主要用於產生一個最終的配置
2、編譯–生成總的資源列表
1、創建chunk - 根據入口模塊創建一個chunk
chunk是webpack在內部構建過程中的一個概念,譯爲塊,它表示通過某個入口找到的所有依賴的統稱
,eg:通過入口文件./src/index.js 找到依賴./src/a.js 又找到./src/b.js, 這3個模塊統稱爲一個chunk
。
根據入口模塊(默認爲./src/index.js)創建一個chunk
每個chunk都有至少兩個屬性:
- name:
默認爲main
- id:
唯一編號,開發環境和name相同,生產環境是一個數字,從0開始
每一個chunk都有名字的,這意味着chunk有可能有多個
的;
2、構建所有依賴模塊 -生成模塊列表(模塊id:轉換後代碼)
- 這個
編譯的過程,不會運行模塊裏的代碼,只是讀取文件內容,記錄成表格
- AST抽象語法樹–樹形結構遍歷,找到所有依賴,以數組的形式["./src/a.js","./src/b.js"]存到dependencies裏
- 替換依賴函數,eg:把
require("./a")
改成_webpack_require("./src/a.js")
,我們改動後的代碼叫轉換後的代碼
–字符串格式 - 通過找依賴,最終形成chunk中模塊記錄表格,裏面存了所有
模塊id(模塊路徑)
和模塊轉換後的代碼
AST在線測試工具
簡圖
在chunk中生成多個模塊,每個模塊包含了模塊id和模塊轉換後的代碼
3、產生chunk assets - 根據模塊列表生成文件列表
在第二步完成後,chunk中會產生一個模塊列表,列表中包含了模塊id和模塊轉換後的代碼
接下來,webpack會根據配置爲chunk生成一個資源列表,即chunk assets
,資源列表可以理解爲是生成到最終文件的文件名和文件內容
chunk hash
是根據所有chunk assets的內容生成的一個hash字符串
hash:一種算法
,具體有很多分類,特點是將一個任意長度的字符串轉換爲一個固定長度的字符串
,而且可以保證原始內容不變,產生的hash字符串就不變
,用來驗證一個文件內容有沒有變化;
簡圖
- 通過入口創建一個chunk
- 編譯出模塊列表(所有依賴的模塊id:轉換後的代碼)
- 根據模塊列表 生成文件列表(資源列表)–
bundle(捆)
,可以認爲資源列表中每一個資源就是一個bundle
4、合併chunk assets
將多個chunk的assets
合併到一起,併產生一個總的hash
多個入口就有多個chunk
3、輸出emit
此步驟非常簡單,webpack將利用node中的fs模塊
(文件處理模塊),根據編譯產生的總的assets
,生成相應的文件。
總過程
涉及術語
- module:模塊,分割的代碼單元,webpack中的模塊可以是任何內容的文件,不僅限於JS,可以是圖片,css等
- chunk:webpack內部構建模塊的塊,
一個chunk中包含多個模塊
,這些模塊是從入口模塊通過依賴分析得來的,一個chunk 對應一個入口模塊 - bundle:chunk構建好模塊後會生成chunk的
資源清單
,清單中的每一項就是一個bundle
,可以認爲bundle就是最終生成的文件
- hash:
最終的資源清單
所有內容聯合生成的hash值 - chunkhash:chunk生成的資源清單內容聯合生成的hash值
- chunkname:chunk的名稱,如果沒有配置則使用main
- id:通常指chunk的唯一編號,如果在開發環境下構建,和chunkname相同;如果是生產環境下構建,則使用一個從0開始的數字進行編號
打包結果解讀
如上圖:
- hash–
最終的資源列表
內容生成的hash - version–webpack版本
- Time–構建時間
- 表格裏:
asset – 資源,下面的項時資源列表裏的每個資源項
size–資源大小
chunks – chunk id ,開發環境下id 和 名字一樣都是main
chunk Name – chunk名稱 Entrypoint 表示入口
, Entrypoint main 這個main 表示入口的chunk 的名字
, = 等號右邊是輸出
- 遞歸加載了2個模塊,這是構建過程中依次加載的模塊
注意:如果開啓了watch–監控文件變化,每次文件變化後從2階段–編譯 開始重新走,不會再初始化了