webpack常用知識點

巨大星星星發表於2019-10-16

預設配置

webpack 4 引入了零配置的概念,提供的預設配置來減少重複工作。
development 模式下,預設開啟了NamedChunksPlugin 和NamedModulesPlugin方便除錯,提供了更完整的錯誤資訊,更快的重新編譯的速度。
在這裡插入圖片描述

production 模式下,自動開啟splitChunks和minimizer,所以基本零配置,程式碼就會自動分割、壓縮、最佳化,同時 webpack 也會自動幫你 Scope HoistingTree-shaking
注:v4.26後,minimizer等於true預設使用的外掛已由UglifyJsPlugin變為TerserPlugin。
主要預設配置:
在這裡插入圖片描述
詳細的mode預設配置,可以看這裡

幾種hash

hash

hash 和每次 build有關,沒有任何改變的情況下,每次編譯出來的 hash都是一樣的,但當你改變了任何一點東西,它的hash就會發生改變。

chunkhash

chunkhash是根據具體每一個模組檔案自己的的內容包括它的依賴計算所得的hash,所以某個檔案的改動只會影響它本身的hash,不會影響其它檔案。

contenthash

當一個vue檔案打包成一個js時,使用MiniCssExtractPlugin會讓css樣式單獨提取為一個css檔案,這個提取出的css檔案,與vue編譯的js檔案,有相同的chunkid。而contenthash是根據css內容決定的,內容不變,contenthash不變,所以應該使contenthash作為部分檔名。

  new MiniCssExtractPlugin({
            filename: "static/css/[name]-css-[contenthash:5].css"
  })

output:path 與 publicPath

path:指定輸出檔案的目標路徑
publicPath:用於在生產模式下更新內嵌到css、html檔案裡的url值。
舉個例子:
css中,這樣引用一個圖片

.image { 
  background-image: url('./test.png');
 }

但在生產環境下,需要引用cdn中的圖片,這時透過定義publicPath來改變引用路徑。

module.exports = merge(baseConfig, {
    mode: "production",
    output: {
        publicPath:'https://someCDN'
    }
 }

打包後

.image { 
  background-image: url('https://someCDN/test.png');
 }

程式碼分割

webpack 4 的Code Splitting 它最大的特點就是配置簡單,如果你的 mode 是 production,那麼 webpack 4 就會自動開啟 Code Splitting。
webpack內建分包策略:

  • 新程式碼塊可以被共享引用,或者這些模組都是來自node_modules資料夾裡面
  • 新程式碼塊大於30kb(min+gziped之前的體積)
  • 按需載入併發最大請求數, 應該小於或者等於5
  • 初始載入的程式碼塊,最大數量應該小於或等於3

配置

optimization: {
  splitChunks: {
     chunks: "async", // 必須三選一: "initial" | "all"(推薦) | "async" (預設就是async)
     minSize: 30000, // 最小尺寸,30000
     minChunks: 1, // 最小 chunk ,預設1,只要被引用一次就分割出來
     maxAsyncRequests: 5, // 最大非同步請求數, 預設5
     maxInitialRequests : 3, // 最大初始化請求書,預設3
     automaticNameDelimiter: '~',// 打包分隔符
     name: function(){}, // 打包後的名稱,此選項可接收 function
     cacheGroups:{ // 這裡開始設定快取的 chunks
         vendor: { // key 為entry中定義的 入口名稱
             chunks: "initial", // 必須三選一: "initial" | "all" | "async"(預設就是async) 
             test: /react|lodash/, // 正則規則驗證,如果符合就提取 chunk
             name: "vendor", // 要快取的 分隔出來的 chunk 名稱 
             priority: 0, // 快取組優先順序
             minSize: 30000,
             minChunks: 1,
             enforce: true,
             maxAsyncRequests: 5, // 最大非同步請求數, 預設5
             maxInitialRequests : 3, // 最大初始化請求書,預設3
             reuseExistingChunk: true // 可設定是否重用該chunk
         }
     }
  }
 }
minChunks

最小 被引用的次數 ,預設1,只要被引用一次就分割出來。

maxAsyncRequests

表示能非同步請求的最大數量。比如非同步請求一個檔案,檔案中還非同步請求另一個檔案,這時兩個檔案會分開打包,如果設定為1,兩個非同步請求檔案會打包在一起。詳細解釋可以看webpack4 maxAsyncRequests記錄

maxInitialRequests

程式碼分割以後,除去runtime所能生成的最多指令碼數量。

chunks

表示參與程式碼分割的模組型別

demo裡,如果chunks賦值為:

  • initial:將所有非動態載入的模組放到vendor 裡
  • async:將所有動態載入的模組打包到vendor
  • all:把動態和非動態模組同時進行最佳化打包,放到vendor裡

詳細講解可以看這裡

cacheGroups

cacheGroups:快取組,可以設定快取的chunks。
注意:

  • cacheGroups 會繼承和覆蓋splitChunks的配置項,但是test、priorty和reuseExistingChunk只能用於配置快取組。
optimization.runtimeChunk

透過optimization.runtimeChunk: true選項,webpack會新增一個只包含執行時(runtime)額外程式碼塊到每一個入口。
打包後的js包括webpackJsonp,checkDeferredModules,__webpack_require__,__webpack_require__.e等用於模組載入的方法。
其中jsonpScriptSrc,函式中存在chunkid與chunkname的對映,用於根據chunkid得到chunks的載入路徑。因為這個對映會受chunk增加或減少的影響,經常變化,不單獨打包會生成到每個非非同步載入的chunk裡,使得本來沒變的chunk也不能快取了。所以一般會單獨打包或內嵌到html裡。

非同步載入打包模組

正常情況下,透過非同步引用的模組會打包成一個chunk。如果引用路徑是動態的,比如:

 ret.component = () => import("@/views" + ret.path + ".vue");

會把views檔案下,所有沒有被引用的元件(被引用的是子元件),單獨打包成chunk。

參考資料

手摸手,帶你用合理的姿勢使用webpack4
Webpack——解決疑惑,讓你明白
沒有了CommonsChunkPlugin,我們拿什麼來分包(譯)

相關文章