Closed BetaSu closed 2 years ago
hash 是webpack在生成文件时,根据文件内容进行hash运算,得到的一个hash值。导致打包时,只要文件发生变更,则会生成一个新的hash值用来跟之前的打包文件做区分,避免存在由于浏览器的缓存问题导致无法获取新的打包文件
webpack中存在三种hash:hash,chunkhash,contenthash 分类依据还是要从他们生成的方式不同说起:
先说一下背景:通过 Web 缓存可以减少等待时间和网络流量,因此减少了显示资源表示形式所需的时间。关于缓存的mdn链接
而有了web缓存,webpack作为构建工具在需要部署新版本时必须要更新发生变化的资源的文件名,确保浏览器会去请求新的资源,否则浏览器会根据缓存策略去判断可能还是复用着旧的资源。
使用方式:在配置文件名的地方使用对应的 webpack 内置变量,webpack在生成文件的时候会把内置变量替换成计算好的 hash,比如
module.exports = { entry: './src/index.js', output: { // 这的[contenthash]就是内置的关于hash的变量,可以指定长度,比如[contenthash:8]就是8位,默认20位 filename: '[name].[contenthash].js', path: path.resolve(__dirname, 'dist'), }, };
产物里对应资源的文件名就带上了一段哈希值,比如 mail-web.61e2ba31c173a3d30cf2.js,vuecommon-web.19c44d4d7e0db584cb98.js
前置概念:webpack新手可能会对 module、chunk、bundle 的概念不理解,给个简单总结,还不理解可以谷歌一下
分类: 1、hash hash 计算是跟整个项目的构建相关,比如下面的例子里生成文件的 hash 和项目的构建 hash 都是一模一样的
2、chunkhash 因为 hash 是项目构建的哈希值,项目中如果有些变动,hash 一定会变,比如说我改动了 utils.js 的代码,index.js 里的代码虽然没有改变,但是大家都是用的同一份 hash。hash 一变,缓存一定失效了,所以不符合预期。
chunkhash 就是解决这个问题的,它根据不同的入口文件(Entry)进行依赖文件解析、构建对应的 chunk,生成对应的哈希值。
效果:不同 chunk 之间不会相互影响
3、contenthash contenthash是处理属于同一个 chunk 的情况,比如 a.js 和 b.js 都属于同一个 chunk,如果希望 a.js 变化,b.js不变化时,打包之后b.js的缓存未失效,就使用 contenthash。
效果:contenthash 将根据资源内容创建出唯一 hash,也就是说文件内容不变,hash 就不变。
3、对不同类型的hash什么时候使用,你能给出一些最佳实践么? 上一段分类的描述里已经描述了效果对比,根据你的需要选用即可。 留个小作业:楼主可以去看看某些好的开源项目主要用的是哪种hash。
总结 篇幅有限,时间有限,总结得不好,没有举出很多具体的demo来说明,望见谅。 我的经验是,webpack可以抽个周末,自己从简单到复杂去自己写 demo,看效果,遇到不懂的就查官方文档或谷歌,循序渐进就好。
FYI:
module.exports = algorithm => {
if (typeof algorithm === "function") {
return new BulkUpdateDecorator(() => new algorithm());
}
switch (algorithm) {
// TODO add non-cryptographic algorithm here
case "debug":
return new DebugHash();
case "xxhash64":
if (createXXHash64 === undefined) {
createXXHash64 = require("./hash/xxhash64");
if (BatchedHash === undefined) {
BatchedHash = require("./hash/BatchedHash");
}
}
return new BatchedHash(createXXHash64());
case "md4":
if (createMd4 === undefined) {
createMd4 = require("./hash/md4");
if (BatchedHash === undefined) {
BatchedHash = require("./hash/BatchedHash");
}
}
return new BatchedHash(createMd4());
case "native-md4":
if (crypto === undefined) crypto = require("crypto");
return new BulkUpdateDecorator(() => crypto.createHash("md4"), "md4");
default:
if (crypto === undefined) crypto = require("crypto");
return new BulkUpdateDecorator(
() => crypto.createHash(algorithm),
algorithm
);
}
};
createHash
in Webpack source codeschemes/HttpUriPlugin.js
80: const hash = createHash("sha512");
392: const hash = createHash(hashFunction);
optimize/ConcatenatedModule.js
1041: const hash = createHash(hashFunction);
optimize/RealContentHashPlugin.js
345: const hash = createHash(this._hashFunction);
cache/getLazyHashedEtag.js
34: const hash = createHash(this._hashFunction);
asset/AssetGenerator.js
280: const hash = createHash(runtimeTemplate.outputOptions.hashFunction);
css/CssModulesPlugin.js
199: const hash = createHash(hashFunction);
ChunkGraph.js
1557: const hash = createHash(this._hashFunction);
1648: const hash = createHash(this._hashFunction);
CodeGenerationResults.js
132: const hash = createHash(this._hashFunction);
serialization/ObjectMiddleware.js
86: const hash = createHash(hashFunction);
serialization/FileMiddleware.js
52: const hash = createHash(hashFunction);
dependencies/WorkerPlugin.js
279: const hash = createHash(compilation.outputOptions.hashFunction);
ModuleFilenameHelpers.js
64: const hash = createHash(hashFunction);
FileSystemInfo.js
2893: const hash = createHash(this._hashFunction);
3095: const hash = createHash(this._hashFunction);
3168: const hash = createHash(this._hashFunction);
3218: const hash = createHash(this._hashFunction);
3272: const hash = createHash(this._hashFunction);
3350: const tsHash = createHash(this._hashFunction);
3351: const hash = createHash(this._hashFunction);
3434: const hash = createHash(this._hashFunction);
3435: const tsHash = createHash(this._hashFunction);
ids/HashedModuleIdsPlugin.js
61: const hash = createHash(options.hashFunction);
ids/IdHelpers.js
25: const hash = createHash(hashFunction);
NormalModule.js
918: const hash = createHash(compilation.outputOptions.hashFunction);
DefinePlugin.js
289: const mainHash = createHash(compilation.outputOptions.hashFunction);
Compilation.js
3949: const moduleHash = createHash(hashFunction);
3977: const hash = createHash(hashFunction);
4152: const chunkHash = createHash(hashFunction);
4201: const moduleHash = createHash(hashFunction);
4219: const chunkHash = createHash(hashFunction);
javascript/JavascriptModulesPlugin.js
359: const hash = createHash(hashFunction);
DependencyTemplates.js
50: const hash = createHash(this._hashFunction);
发生问题的场景
小明初次接触
webpack
,了解到hash
这一概念,但不清楚他的应用场景及分类。需要解决的问题
你能以如下顺序帮小明解惑么:
hash
,他的应用场景是什么?webpack
中有几种hash
,他们的分类依据是?hash
什么时候使用,你能给出一些最佳实践么?最佳答案评选标准
最佳答案
shenzhim的回答
答题同学须知
答题规范:请在
一次评论
中完成作答,后续修改也请编辑该评论,而不是追加新的评论评选标准:最佳答案由
围观同学
的 👍 和卡颂共同决定评选时间:一般是问题发布24小时后评选,如果问题发布当天回答数较少,问题悬赏金额可能增加,同时悬赏时间也会增加
围观同学须知
对于你满意的答案,请不要吝惜你的 👍,这是评选最佳答案的依据
非答题的评论
会被删除,问题相关讨论请在赏金猎人群中进行