前言
问题解决了,特来反哺社区
先总结一下。HashedModuleIdsPlugin
用于稳定 ModuleId 的,我问的问题核心是 **生成稳
ChunkId
**,这两者是不一样的。 问题描述
有人对Webpack比较了解的吗?
我这里有个问题想要请教一下:当我们新增模块(也就是entry加了新东西)的时候,怎么保证ChunkId保持稳定
比如我在entry下新增加了三个模块,但是带动了许多构建后的文件Hash也跟着变动,查看构建后的代码发现是因为ChunkId发生了递增导致的。项目已经配置了HashedModuleIdsPlugin
,并且生效。
期望效果 : entry新增模块后,其他模块的构建后的文件Hash没有变化,提高缓存命中率。
下面是添加新模块并打包的前后文件Hash对比
添加新模块前后对比截图
如何生成稳定ModuleId
表现:
只修改了 home/index.js
的代码,但在最终的构建结果中,vendor.js
的文件指纹也被修改了
原因有两个:
- webpack runtime (运行时) 中包含 chunks ID 及其对应 chunkhash 的对象,但 runtime 被集成到 vendor.js 中。
- entry 内容修改后,由于 webpack 的依赖收集规则导致构建产生的 entry chunk 对应的 ID 发生变化,webpack runtime 也因此被改变。
解决办法:
- 使用
CommonsChunkPlugin
继续将webpack runtime抽离出来 - 使用
HashedModuleIdsPlugin
代替原有的ModuleId根据依赖的收集顺序递增的正整数生成规则。
顺便一提,生成稳定的ModuleId在中有提及
早前经过合理的配置(可以参考,实现了其他模块变动后,vendor.js
的文件指纹不会发生变化的效果)
效果如下:
如何生成稳定的ChunkId
很多文章都只介绍到如何生成稳定的ModuleId,没有提到生成稳定的ChunkId
后来经过 @dahoshaw的提醒
可以看下Webpack的源码,Webpack是根据模块的顺序递增chunkid,源代码中的applyChunkIds函数,所以官方有提供
NamedChunksPlugin
插件来根据文件名来稳定你的chunkid
webpackJsonp
有三个参数,每次有新的entry加入说明资源数增加了,Chunk数量也会跟着增加。ChunkId也会递增
这有点类似ModuleId递增变动导致的文件指纹变化而导致的长效缓存失效
他推荐的文章 确实写的不错!
解决办法:
在生产环境中的Webpack配置添加plugin: NamedChunksPlugin
// 使用模块名称作为chunkid,替换掉原本的使用递增id来作为chunkid导致的[新增entry模块,其他模块的hash发生抖动,导致客户端长效缓存失效]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("_");}));
最后验证一下,我们先打包一下项目,打包结果结构如下:
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.js4 directories, 11 files
假设我们打算新增sub-sub-home
模块。新增这个模块后打包结果结构如下:
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.js5 directories, 14 files
至此,通过Webpack实现长效缓存实践完美收官。