【问题解决】webpack 打包 - 用上 contenthash,每次打包后,所有文件的 hashname 依然会变更

2,949 阅读2分钟

问题描述:

  1. 项目中有 前端目录,前端目录下有多个入口(每个入口进行单独的打包),通过 webpack splitchunk 插件,每次打包时,都会把所有入口的 react 库独立抽离出来,抽离后的文件命名为 chunkname.contenthash.js;

  2. 打包后发现,每个入口抽离出来的 react chunk 都不一样,有多少个入口,最终打包 就有 多少个 react chunk文件,每个文件的 hash 名字都不一样;

    理论上,由于单独抽离的只有 react,无论有多少个入口,打包出来的 react chunk 内容应该都是一样的,但实际情况却是有多个 react chunk,这种情况明显不利于客户端的缓存持久化;

问题分析:

  1. 把 uglifyjs 插件去除,重新打包,看看每个 react chunk 有什么不一样

如上图所示,不同的文件,对应位置的数字都不一样,导致文件内容都不一致

  1. 了解 webpack 的原理的话,可以知道,上图所示的两个数字分别是 chunkIdmoduleId

  2. 至此,问题基本清楚了,由于 多个入口 是分别打包的,而 react chunk 分配到的 moduleId 和 chunkId 都是随机生成的,所以不同入口的 react chunk 的 moduleId 和 chunkId 都不一样;同理同一入口多次打包,它的 react chunk 分配到的 moduleId 和 chunkId 也会有可能不一样;

问题解决:

  1. 目的是要固化 chunkId 和 moduleId 的分配,有两种解决路径:a、可以自己写插件和自定义方案进行 id 的分配;b、webpack 官方已经提供了相关插件进行处理;

  2. 了解过 webpack 的官方解决方案后,决定直接使用官方方案(我们自己写插件的话,方案也和官方的方案一样);

官方文档可参考:webpack.js.org/configurati…

  1. 修改 webpack 配置

    a. chunkId 配置为 由包含模块定义的名字,与 splitChunk 共同工作,可以固化 chunkId

    b. moduleId 配置为 对应模块的完整路径 的 hash 值,避免 每次打包时 moduleId 随机分配数字;

  1. 检验成果,重新打包

    如下图,react chunk 收敛到只有一个,不同入口都可以服用该 chunk,解决持久缓存的问题