十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

构建工具中的 hash 与 contenthash作用:以 Webpack 和 Vite 为例

构建工具中的 hash 与 contenthash作用:以 Webpack 和 Vite 为例 文章目录前言一、为什么需要 hash二、在 Webpack 中的三种哈希类型1️. [hash]全局构建级别2️. [chunkhash]按入口粒度更新3️. [contenthash]内容级哈希推荐三、在 Vite 中的哈希策略默认规则自定义命名规则四、两者的核心区别总结五、使用场景推荐六、实战示例✅ Webpack 生产配置✅ Vite 生产配置七、最佳实践总结前言在现代前端项目中构建工具如Webpack、Vite、Rollup都会为打包输出的文件生成带有哈希值的文件名例如bundle.4a8f2d.js style.73a0de.css这些hash 值不仅是随机字符串而是前端性能优化的重要组成部分。它们的核心作用是✅实现浏览器缓存的精准控制Cache Busting ✅提高缓存命中率减少重复加载但当我们在配置中看到[hash]、[contenthash]、[chunkhash]时很多人会迷惑这些到底有什么区别 Vite 里也有类似的 hash 吗如下所示一、为什么需要 hash当浏览器加载静态资源JS、CSS、图片时通常会缓存它们。这在性能上是好事但也会带来一个经典问题❌ 文件更新了但浏览器还在用旧缓存。为了解决这个问题我们给文件名添加哈希后缀main.83a6d2.js当文件内容发生变化时构建工具会生成新的 hash 值main.93b7e4.js于是浏览器就会重新请求新文件保证拿到最新版本。这就是所谓的缓存破坏Cache Busting机制。二、在 Webpack 中的三种哈希类型Webpack 提供了三种占位符它们代表不同粒度的哈希策略占位符含义更新范围[hash]整个构建的哈希任意文件变动都会引起所有文件 hash 变化[chunkhash]基于 chunk 的哈希仅当前入口及依赖变动时更新[contenthash]基于内容的哈希仅当文件内容变化时更新最精细1️.[hash]全局构建级别output:{filename:bundle.[hash].js;}任意文件JS、CSS、图片变动都会让所有输出文件的 hash 全部更新。适用场景开发环境每次构建都重新加载无所谓不适合生产缓存命中率太低。2️.[chunkhash]按入口粒度更新output:{filename:bundle.[chunkhash].js;}当某个入口文件chunk内容变化时只更新该 chunk 的文件。但它仍可能受到其他依赖的影响尤其是公共模块。 在使用MiniCssExtractPlugin抽离 CSS 时CSS 改动会影响 JS 的 chunkhash因此后期不常用。3️.[contenthash]内容级哈希推荐output:{filename:bundle.[contenthash].js;}它根据文件自身内容生成哈希值。只要文件内容不变文件名就保持稳定。这也是现代前端构建中最常用、最推荐的方案。三、在 Vite 中的哈希策略Vite 没有[hash]、[contenthash]这样的占位符语法但它的行为与 Webpack 的[contenthash]等价。默认规则Vite 的生产构建vite build输出目录通常是dist/ ├─ assets/ │ ├─ index-BkR8kM3.js │ ├─ index-BkR8kM3.css │ └─ logo-CyT9y0D.png这些BkR8kM3、CyT9y0D就是基于文件内容计算的 hash 值。当文件内容未变化时hash 不会改变。自定义命名规则在vite.config.js中可以使用占位符控制输出格式exportdefault{build:{rollupOptions:{output:{entryFileNames:js/[name]-[hash].js,chunkFileNames:js/[name]-[hash].js,assetFileNames:assets/[name]-[hash][extname]}}}};这里的[hash]实际等价于Webpack 的[contenthash]它同样是根据内容变化生成的稳定哈希。 在 Vite 中并没有全局[hash]或[chunkhash]所有[hash]都是基于内容的即 content-based hash。四、两者的核心区别总结对比项WebpackVite默认行为不带 hash自动生成基于内容的 hash[hash]全局构建 hash文件内容 hash等价于 contenthash[contenthash]内容级别 hash默认行为配置复杂度高简单几乎开箱即用缓存控制精度可配置默认精细五、使用场景推荐场景推荐做法说明开发环境使用[hash]Webpack或关闭 hashVite 默认 dev 不带 hash方便热更新生产环境使用[contenthash]Webpack或默认行为Vite文件内容变化才更新图片、字体使用[contenthash]或 Vite 默认[hash]提升缓存命中率CSS 文件使用MiniCssExtractPlugin[contenthash]Webpack独立缓存控制六、实战示例✅ Webpack 生产配置constMiniCssExtractPluginrequire(mini-css-extract-plugin);module.exports{mode:production,output:{filename:js/[name].[contenthash].js,clean:true},plugins:[newMiniCssExtractPlugin({filename:css/[name].[contenthash].css})]};✅ Vite 生产配置// vite.config.jsexportdefault{build:{rollupOptions:{output:{entryFileNames:js/[name]-[hash].js,chunkFileNames:js/[name]-[hash].js,assetFileNames:assets/[name]-[hash][extname]}}}};两者最终行为一致 只要文件内容不变hash 不会变化浏览器缓存就能命中。七、最佳实践总结目标Webpack 配置Vite 配置开发调试[hash]默认行为不带 hash生产构建[contenthash]默认[hash]内容 hash图片、字体assetModuleFilename: assets/[name].[contenthash][ext]assetFileNames: assets/[name]-[hash][extname]CSS 抽离MiniCssExtractPlugin [contenthash]默认生成 感谢阅读想了解更多 我的博客网站 | 记录思考分享干货 我的个人主页 | 关于我、开源项目
返回列表