增量发布要求dist/为扁平化一级目录,所有资源引用必须用根相对路径(如/js/main.js),public/仅放不参与构建的固定文件,HTML模板路径须统一且与CDN缓存策略匹配。

增量发布不是靠“改几个文件再上传”就能稳的,关键在目录结构是否支持原子替换、路径不漂移、资源可独立缓存。静态文件一旦混放或路径依赖 HTML 位置,发一个 main.js 就可能让所有页面白屏。
为什么 dist/ 必须是扁平化、无嵌套的最终产物目录
增量发布时,你只会上传变更的文件(比如只更新 js/main.abc123.js),但浏览器加载时仍会按 HTML 中写的路径去请求。如果 dist/ 里还保留 dist/js/modules/ 这类嵌套,而 HTML 写的是 /js/main.js,那新旧文件路径就对不上——旧 HTML 找不到新 JS,或新 HTML 加载了旧 CSS。
-
dist/只允许一级目录:index.html、css/main.css、js/main.js、images/logo.svg—— 不允许dist/js/lib/或dist/css/themes/dark.css - 所有 HTML 中的
href和src必须用根相对路径,如/js/main.js,不能是js/main.js(相对路径基准随 HTML 位置变) - 构建工具(Vite/Webpack)输出必须设为
assetsInlineLimit: 0+rollupOptions.output.inlineDynamicImports = false,否则 chunk 文件名不可预测,无法做精准增量
public/ 里放什么、不放什么,直接影响能否安全跳过发布
public/ 是唯一可以“不走构建流程、直接复制进 dist/”的目录,但它不是垃圾桶。放错东西会导致缓存失效、CDN 回源失败、甚至上线后图标 404。
- 必须放:
public/favicon.ico、public/robots.txt、public/manifest.json—— 它们不参与构建,路径固定为/favicon.ico - 禁止放:
public/css/reset.css或public/js/utils.js—— 这些是源码,该进src/,由构建器处理并哈希命名 - 第三方字体(如
public/fonts/inter.woff2)要确保@font-face中的src路径与实际部署路径一致,推荐用/fonts/inter.woff2,别用../fonts/
HTML 模板中如何写路径才能避免增量发布时路径断裂
模板里写错一个 ./ 或漏掉 /,发布新 index.html 后,老页面引用的 js/app.js 就会去错地方找文件——本地开发没问题,上线就 404。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
立即学习“前端免费学习笔记(深入)”;
- 所有资源引用统一用绝对路径(根相对):
<link rel="stylesheet" href="/css/main.css">,不是css/main.css或../css/main.css - 多页面场景下,
pages/about.html和index.html必须用相同路径规则,否则无法共用同一份 CDN 缓存 - 如果用了模板引擎(Nunjucks/EJS),变量注入路径时要加前导斜杠:
href="{{ VITE_BASE_URL }}/css/main.css",VITE_BASE_URL在生产环境必须为""(空字符串),不能是"./"
图片和图标目录分离的底层原因:缓存策略完全不同
你以为只是“分文件夹看着清爽”,其实 SVG 图标和 banner 图片在 HTTP 缓存头、CDN 配置、甚至构建压缩参数上都必须隔离——混在一起发版,一次图片更新就会让整个 icons/ 目录缓存失效。
-
dist/icons/下只放 SVG / PNG 小图标,全部启用Cache-Control: public, max-age=31536000(1 年) -
dist/images/下放 banner、截图等大图,配max-age=86400(1 天),方便运营随时换图 - 禁止在
dist/里出现dist/assets/images/这种二级嵌套——CDN 的 path pattern 规则很难精准匹配,容易误缓存或漏刷新
真正卡住增量发布的,从来不是打包配置,而是某次随手把 logo.png 放进了 src/images/ 却在 HTML 里写了 images/logo.png;或是改了 webpack.config.js 输出路径,却忘了同步更新 CI 脚本里的 rsync 排除列表。目录结构不是写完就扔的文档,它是每次 rsync -avz --delete dist/ user@server:/var/www/html/ 时,决定哪些文件能动、哪些必须锁死的契约。


















