在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ 如何使Webpack生成穩(wěn)定的Chunkid

如何使Webpack生成穩(wěn)定的Chunkid

有人對Webpack比較了解的嗎?

我這里有個(gè)問題想要請教一下:當(dāng)我們新增模塊(也就是entry加了新東西)的時(shí)候,怎么保證ChunkId保持穩(wěn)定

比如我在entry下新增加了三個(gè)模塊,但是帶動了許多構(gòu)建后的文件Hash也跟著變動,查看構(gòu)建后的代碼發(fā)現(xiàn)是因?yàn)镃hunkId發(fā)生了遞增導(dǎo)致的。項(xiàng)目已經(jīng)配置了HashedModuleIdsPlugin,并且生效。

期望效果 : entry新增模塊后,其他模塊的構(gòu)建后的文件Hash沒有變化,提高緩存命中率。

下面是添加新模塊并打包的前后文件Hash對比

添加新模塊前后對比截圖

添加新模塊之前

添加新模塊之后

clipboard.png

已經(jīng)參考文章與文檔
https://sebastianblade.com/us...

https://doc.webpack-china.org...

回答
編輯回答
貓館

前言

問題解決了,特來反哺社區(qū)

先總結(jié)一下。HashedModuleIdsPlugin用于穩(wěn)定 ModuleId 的,我問的問題核心是 生成穩(wěn)定的ChunkId,這兩者是不一樣的。

如何生成穩(wěn)定ModuleId

表現(xiàn):

只修改了 home/index.js 的代碼,但在最終的構(gòu)建結(jié)果中,vendor.js 的文件指紋也被修改了

原因有兩個(gè):

  1. webpack runtime (運(yùn)行時(shí)) 中包含 chunks ID 及其對應(yīng) chunkhash 的對象,但 runtime 被集成到 vendor.js 中。
  2. entry 內(nèi)容修改后,由于 webpack 的依賴收集規(guī)則導(dǎo)致構(gòu)建產(chǎn)生的 entry chunk 對應(yīng)的 ID 發(fā)生變化,webpack runtime 也因此被改變。

解決辦法:

  1. 使用CommonsChunkPlugin 繼續(xù)將webpack runtime抽離出來
    image
  2. 使用HashedModuleIdsPlugin代替原有的ModuleId根據(jù)依賴的收集順序遞增的正整數(shù)生成規(guī)則。

順便一提,生成穩(wěn)定的ModuleId在官方文檔 - 緩存中有提及

早前經(jīng)過合理的配置(可以參考用 webpack 實(shí)現(xiàn)持久化緩存,實(shí)現(xiàn)了其他模塊變動后,vendor.js的文件指紋不會發(fā)生變化的效果)

效果如下:

其他模塊發(fā)生變動時(shí),抽離的公共代碼vendor.js不會發(fā)生變化

如何生成穩(wěn)定的ChunkId

很多文章都只介紹到如何生成穩(wěn)定的ModuleId,沒有提到生成穩(wěn)定的ChunkId

后來經(jīng)過 @dahoshaw的提醒

可以看下Webpack的源碼,Webpack是根據(jù)模塊的順序遞增chunkid,源代碼中的applyChunkIds函數(shù),所以官方有提供NamedChunksPlugin插件來根據(jù)文件名來穩(wěn)定你的chunkid

webpackJsonp有三個(gè)參數(shù),每次有新的entry加入說明資源數(shù)增加了,Chunk數(shù)量也會跟著增加。ChunkId也會遞增

這有點(diǎn)類似ModuleId遞增變動導(dǎo)致的文件指紋變化而導(dǎo)致的長效緩存失效

他推薦的文章 Predictable long term caching with Webpack確實(shí)寫的不錯(cuò)!

解決辦法:

在生產(chǎn)環(huán)境中的Webpack配置添加plugin: NamedChunksPlugin

// 使用模塊名稱作為chunkid,替換掉原本的使用遞增id來作為chunkid導(dǎo)致的[新增entry模塊,其他模塊的hash發(fā)生抖動,導(dǎo)致客戶端長效緩存失效]
config.plugins.push(new webpack.NamedChunksPlugin((chunk) => {
  // 解決異步模塊打包的問題
  if (chunk.name) {
    return chunk.name;
  }
  return chunk.modules.map(m => path.relative(m.context, m.request)).join("_");
}));

最后驗(yàn)證一下,我們先打包一下項(xiàng)目,打包結(jié)果結(jié)構(gòu)如下:

dist
├── home
│?? ├── haha.dc494f13ed558999751e.js
│?? ├── index.2266d24e04004acaa5a6.css
│?? └── index.2b15fbd2daa6c833f5d5.js
├── manifest.json
├── runtime.1de86da7006780a96879.js
├── static
│?? └── images
│??     ├── logo-ea7f33f9bddceac362c1d7f378043187.png
│??     └── share-icon-881a5a400142ab60684b3cec860611b4.png
├── sub-home
│?? ├── haha.141284e7095f605726ac.js
│?? ├── index.7039775e1ba458814d14.js
│?? └── index.efd6d51187ec8a058fe6.css
└── vendor.dee373a1cd36f461d200.js

4 directories, 11 files

假設(shè)我們打算新增sub-sub-home模塊。新增這個(gè)模塊后打包結(jié)果結(jié)構(gòu)如下:

dist
├── home
│?? ├── haha.dc494f13ed558999751e.js
│?? ├── index.2266d24e04004acaa5a6.css
│?? └── index.2b15fbd2daa6c833f5d5.js
├── manifest.json
├── runtime.1de86da7006780a96879.js
├── static
│?? └── images
│??     ├── logo-ea7f33f9bddceac362c1d7f378043187.png
│??     └── share-icon-881a5a400142ab60684b3cec860611b4.png
├── sub-home
│?? ├── haha.141284e7095f605726ac.js
│?? ├── index.7039775e1ba458814d14.js
│?? └── index.efd6d51187ec8a058fe6.css
├── sub-sub-home
│?? ├── haha.6501ce2d3a138709282b.js
│?? ├── index.c367ca84bd261f36f050.js
│?? └── index.efd6d51187ec8a058fe6.css
└── vendor.dee373a1cd36f461d200.js

5 directories, 14 files

至此,通過Webpack實(shí)現(xiàn)長效緩存實(shí)踐完美收官。

參考

知乎 - webpack 每次打包公用vendor 每次hash都會變化,有辦法解決嗎?

用 webpack 實(shí)現(xiàn)持久化緩存

Predictable long term caching with Webpack

官方文檔 - 緩存

2017年11月10日 12:47
編輯回答
編輯回答
墨小羽

clipboard.png
in webpack 3.8.1

chunk.modules被廢棄了

clipboard.png,

最終使用了新的resource和chunk.mapModules來實(shí)現(xiàn)路徑作為name.js中的name部分

clipboard.png

2018年4月8日 20:23