webpack構建流程
-
Webpack的運行流程是一個串行的過程,從啟動到結束依次執行
- 初始化參數:從配置文件中讀取合并參數,得出最終參數
- 開始編譯:用最終參數初始化Compiler對象,加載所有配置插件,執行對象的run方法開始執行編譯
- 確定入口:根據配置中的entry找出所有的入口文件
- 編譯模塊:從入口文件出發,調用所有配置的Loader對模塊進行翻譯,通過遞歸找出該模塊依賴的模塊,直到所有入口依賴的文件都處理完成
- 輸出資源:根據入口和模塊之間的依賴關系,組裝成一個個包含多個模塊的Chunk,再轉換成一個單獨的文件加入到輸出列表
- 輸出完成:根據配置確定輸出的路徑和文件名,把文件內容寫入到文件系統
webpack熱更新(HMR)原理
- 第一步,在webpack的watch模式下,webpack會監聽到文件變化,根據配置文件對模塊重新編譯打包,并將打包后的代碼保存在內存中
- 第二步是webpack-dev-server和webpack之間的接口交互,dev-server的中間件middleware調用webpack暴露的API對代碼變化進行監控,并且告訴webpack,將代碼打包到內存中
- 第三步是webpack-dev-server對文件變化的一個監控,變化后會通知瀏覽器端對應用進行live reload
- 第四步也是webpack-dev-server代碼的工作,該步驟主要是通過sockjs在瀏覽器端和服務端之間建立一個websocket長連接,將webpack編譯打包的狀態告知瀏覽器端,服務端傳遞的最主要信息是新模塊的hash值,后面會根據hash值來進行模塊熱替換
- webpack-dev-server并不能夠請求更新的代碼,也不會執行熱更模塊操作,而把這些工作又交回給了webpack,webpack的工作就是根據客戶端傳給它的信息以及dev-server的配置決定是刷新瀏覽器呢還是進行模塊熱更新。如果僅僅是刷新瀏覽器,就沒有后面的步驟了
- HMR.runtime是客戶端HMR的中樞,它接收到傳遞給他的新模塊的hash值,向服務端發送Ajax請求,服務端返回一個json,該json就是更新列表,再次通過請求,獲取到最新的模塊代碼
- HotModulePlugin將會對新舊模塊進行對比,決定是否更新模塊,如果要更新,檢查模塊之間的依賴關系,更新模塊的同時更新依賴
- 最后,當HMR失敗后,回退到live reload操作,也就是進行瀏覽器刷新來獲取最新打包代碼
利用webpack來優化前端性能
- 壓縮代碼,刪除多余的代碼等。可以利用webpack的UglifyJsPlugin和ParallelUglifyPlugin來壓縮JS文件, 利用cssnano來壓縮css
- 利用CDN加速,在構建過程中,將引用的靜態資源路徑修改為CDN上對應的路徑,通過webpack對loader的publicPath參數來修改資源路徑
- 提取公共代碼
vue項目中按需加載實現
- 例如elementUI的babel-plugin-component在.babelrc中配置,即可實現組件按需加載
- 單頁應用的按需加載:通過import()語句來控制加載時機,webpack內置了對于import()的解析,會將import()中引入的模塊作為一個新的入口生成一個Chunk,當代碼執行到import()語句時,會去加載Chunk對應生成的文件