聊聊 webpack 異步加載(三):webpack 如何做到持久化緩存

作者 | vayne
轉載請註明出處

前兩篇文章我們基本清楚了在兩種不同情況下,webpack 如何處理拆包後的代碼:

1、庫代碼與業務代碼分離

2、import() 與 code spliting

默認情況下 chunks 與 modules 都以順序的數字作為其唯一 id。由於 chunk 中的 module 需要緩存到入口文件的 modules 變量中,為了保證 id 的唯一,多個 chunk 之間的 module id 也是連續的

Chunk 0:

聊聊 webpack 異步加載(三):webpack 如何做到持久化緩存

Chunk 1:

聊聊 webpack 異步加載(三):webpack 如何做到持久化緩存

這種方式有一個缺點,一個 chunk 增刪 module,會導致其他 chunk 中的 moduleId 發生改變,增刪 chunk,更會導致其他 chunk 的 chunkId 和 包含的 moduleId 同時改變,也就是說一個 chunk 文件無法使用穩定的 hash 作為標識,也就沒法使用穩定的瀏覽器文件緩存了。

第一次打包:

聊聊 webpack 異步加載(三):webpack 如何做到持久化緩存

某個文件增加了一個模塊:

聊聊 webpack 異步加載(三):webpack 如何做到持久化緩存

不出所料,全部的 hash 都改變了,現在知道了原因,解決起來就容易了,webpack 官方(https://webpack.docschina.org/configuration/optimization/#optimization-moduleids)提供了優化選項:

聊聊 webpack 異步加載(三):webpack 如何做到持久化緩存

顧名思義,namedChunks 就是為 chunk 命名,moduleIds 可以為 module 取 hash 值(看打包出來的代碼,只是按照模塊順序設置了一個不會變的 hash 值,跟內容沒有關係),除了固定 chunkId 和 moduleId,還需要做這些配置:

  • output 配置 chunkFileName: '[name].[contenthash:8].js',推薦閱讀這篇文章(https://juejin.im/post/5cede821f265da1bbd4b5630)來了解為什麼需要使用 contenthash 以及 webpack 中容易混淆的知識點
聊聊 webpack 異步加載(三):webpack 如何做到持久化緩存

  • import() 時,使用 /* webpackChunkName: "admin-manage" */ 為 chunk 命名,可以閱讀 webpack文檔(https://webpack.docschina.org/api/module-methods/#magic-comments)來了解 Magic Comment 的作用。也可以使用 webpack 提供的插件 webpack.NamedChunksPlugin 自己配置 chunkName。
聊聊 webpack 異步加載(三):webpack 如何做到持久化緩存

看下打包後的文件

聊聊 webpack 異步加載(三):webpack 如何做到持久化緩存

某個文件增加了一個模塊:

聊聊 webpack 異步加載(三):webpack 如何做到持久化緩存

成為優秀的前端工程師之前不得不成為優秀的 webpack 配置工程師。(我太難了。。。)

實踐中發現,上面的方法也不是穩定的。通常我們可能還要把各個 chunk 中的 common 部分單獨拆出來,這樣 chunk 改來改去,可能會形成新的 common 部分,一個 chunk 改動也可能會引起別的 chunk 更改。另外,webpack 還提供了 optimization.usedExports 選項,用來標識模塊中哪些部分沒有被別的模塊使用,壓縮代碼時會根據標識來去除沒有用的部分,其實也就是 tree-shake。這種情況下,一個 chunk 改動也可能會引起別的 chunk 更改。希望 webpack5 可以解決這個問題,不過想想感覺難度還是不小的,牽扯的部分有點多。

(本系列完)


分享到:


相關文章: