跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScriptNode.js大前端

Webpack 与 Vite 构建工具中 hash 与 contenthash 的区别与应用

综述由AI生成对比了 Webpack 和 Vite 构建工具中 hash 与 contenthash 的作用与区别。阐述了 hash 用于浏览器缓存控制(Cache Busting)的原理。详细解析了 Webpack 中 [hash]、[chunkhash]、[contenthash] 三种占位符的粒度差异,指出 [contenthash] 为生产环境推荐方案。介绍了 Vite 默认基于内容生成 hash 的行为及其配置方式。最后提供了两者的生产环境配置示例及最佳实践建议,帮助开发者优化前端资源加载与缓存策略。

莫名其妙发布于 2026/3/26更新于 2026/6/1244 浏览
Webpack 与 Vite 构建工具中 hash 与 contenthash 的区别与应用

前言

在现代前端项目中,构建工具(如 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 中可以使用占位符控制输出格式:

export default {
  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)或关闭 hash(Vite 默认 dev 不带 hash)方便热更新
生产环境使用 [contenthash](Webpack)或默认行为(Vite)文件内容变化才更新
图片、字体使用 [contenthash] 或 Vite 默认 [hash]提升缓存命中率
CSS 文件使用 MiniCssExtractPlugin + [contenthash](Webpack)独立缓存控制

六、实战示例

✅ Webpack 生产配置
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  mode: "production",
  output: {
    filename: "js/[name].[contenthash].js",
    clean: true
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/[name].[contenthash].css"
    })
  ]
};
✅ Vite 生产配置
// vite.config.js
export default {
  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]默认生成

目录

  1. 前言
  2. 一、为什么需要 hash?
  3. 二、在 Webpack 中的三种哈希类型
  4. 1. [hash]:全局构建级别
  5. 2. [chunkhash]:按入口粒度更新
  6. 3. [contenthash]:内容级哈希(推荐)
  7. 三、在 Vite 中的哈希策略
  8. 默认规则
  9. 自定义命名规则
  10. 四、两者的核心区别总结
  11. 五、使用场景推荐
  12. 六、实战示例
  13. ✅ Webpack 生产配置
  14. ✅ Vite 生产配置
  15. 七、最佳实践总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • FPGA 中 XDMA 多通道传输架构:实战解析与工程优化
  • 初识 Git 与安装入门
  • Gdspy Python 芯片设计库安装与使用指南
  • GitLab 个人访问令牌(Token)获取指南
  • 飞书机器人与 Claude Code 交互:从手机指令到 AI 处理的全自动流程
  • Seedance 2.0 飞书机器人深度集成:API 鉴权与上下文感知对话配置
  • VRChat 跨语言交流工具 VRCT 使用指南
  • 基于射频和深度学习的无人机检测识别与开源数据库构建
  • 工业监控系统:C#上位机多PLC采集与Web可视化(WPF+SignalR)
  • AI 编程助手深度对比:OpenCode、Claude Code 与 Kimi Code CLI
  • Qoder AI 编程工具从部署到深度使用实战详解
  • OpenClaw 技能扩展实战:Tavily 联网与多维表格自动化
  • 基于强化学习Q-learning的无人机三维路径规划原理与MATLAB实现
  • Java 17与Spring AI深度解析:RAG架构与Agent智能体
  • 国产主流 AI 智能体平台 OpenClaw 及其竞品对比汇总
  • Java 实现百度地图 SN 权限签名及搜索接口调用实战
  • JavaScript reduce 方法核心原理与实战应用
  • JDK9 及以上版本适配 wsimport 生成的 SOAP 代码
  • Revit 模型 Web 可视化:Revit2GLTF 转换方案详解
  • 全球人工智能行业报告:AI 重塑千行百业

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online