webpack整個的建構過程是基于事件流
webpack 就像一條生産線,要經過一系列處理流程後才能将源檔案轉換成輸出結果。 這條生産線上的每個處理流程的職責都是單一的,多個流程之間有存在依賴關系,隻有完成目前處理後才能交給下一個流程去處理。 插件就像是一個插入到生産線中的一個功能,在特定的時機對生産線上的資源做處理。 Webpack 通過 Tapable 來組織這條複雜的生産線。 Webpack 在運作過程中會廣播事件,插件隻需要監聽它所關心的事件,就能加入到這條生産線中,去改變生産線的運作。 Webpack 的事件流機制保證了插件的有序性,使得整個系統擴充性很好。
建構過程
- 優化webpack,初始化構造配置參數,建構compiler對象,挂載Tapable事件流鈎子函數(plugin的apply方法)
- 入口,讀取entries入口配置資訊
- 階段,依次讀取入口檔案,loader内容轉換,AST文法樹轉換,依賴收集,逐個拉取依賴并重複上述過程,最終得到轉換後的内容以及依賴關系
- 資源,根據入口與子產品之間的依賴關系,組裝chunk代碼塊,生成檔案輸出清單
- 成功,根據配置輸出檔案路徑和檔案名,将檔案寫入檔案系統,完成建構
優化
resolve優化
減少 resolve 的解析
- resolve.extensions:用來表明檔案字尾清單,預設查找順序是 ['.js', '.json'],如果你的導入檔案沒有添加字尾就會按照這個順序查找檔案。我們應該盡可能減少字尾清單長度,然後将出現頻率高的字尾排在前面
- resolve.alias:可以通過别名的方式來映射一個路徑,能讓 Webpack 更快找到路徑
- resolve.mainFields:[‘main’],設定盡量少的值可以減少入口檔案的搜尋步驟
- module.noParse,排除不需要掃描的檔案
loader優化
- Loader 的檔案搜尋範圍
- cache-loader(将loader編譯後的結果寫入硬碟緩存)
- HappyPack可以将 Loader 的同步執行轉換為并行的(目前基本棄用了)
- 排除node_modules等不需要編譯的檔案( exclude: /node_modules/ )
- 配置loader緩存參數,例如label( loader: 'babel-loader?cacheDirectory=true' )
plugin優化
- 使用 DLLPlugin打包公共代碼
- ParallelUglifyPlugin開啟多程序壓縮JS檔案
- IgnorePlugin(内置插件) 忽略某些子產品
- LimitChunkCountPlugin合并細小的chunk代碼塊,減少http請求;MinChunkSizePlugin合并細小代碼塊
optimization
- splitChunks分塊,緩存複用率在minChunks上的代碼塊
- minimizer中ParallelUglifyPlugin插件并行壓縮代碼
- concatenateModules串聯到單個子產品中的子產品圖段,production模式下預設開啟
- ...production模式下預設開啟的優化選項