搬构建产物之前,先 grep 绝对路径

把一个 Vite dist 从根路径挪到子目录,整站 404。问题不在部署,在搬之前那一步没查。

把一个现成的前端应用挂到站点的子路径下,看起来是纯粹的搬运工作:复制目录,改一行链接,部署。

实际结果是整站 404。

为什么

构建工具默认假设你的应用跑在域名根路径。于是产物里到处是绝对路径:

  • <script src="/assets/index-xxx.js">
  • <link href="/assets/index-xxx.css">
  • CSS 里的 url(/icons/...)
  • Service Worker 注册的 "/sw.js"
  • manifest 里的 "start_url": "/""scope": "/"

在根路径下这些全对。挪到 /tools/some-app/ 之后,浏览器仍然去根目录找 /assets/...——那里什么都没有。

首页 HTML 本身能 200,因为它确实在那个位置。所以「首页打得开」完全不能证明搬运成功,只能证明你搬对了一个文件。

正确的顺序

不是「部署完再看哪里坏了」,是搬之前就查。一条命令的事:

grep -rno 'src="/\|href="/\|url(/' dist/ | head -30
cat dist/manifest.webmanifest
grep -o '"/sw\.js"' dist/assets/*.js

五个高频位置,按坑的深浅排序:

  1. HTML 里的 src / href —— 最显眼,也最容易被误以为是全部
  2. CSS 里的 url() —— 字体和背景图,坏了页面还能用,只是丑
  3. Service Worker 注册路径 —— 注册失败通常静默,控制台不翻不会发现
  4. manifest 的 start_url / scope —— PWA 装到桌面后打开一片空白,离部署已经过去很久了
  5. 代码里手写的 fetch 路径 —— 构建工具的 base 配置管不到这些

更根本的做法

真正的修法是回到源项目改构建配置(Vite 的 base、Next 的 basePath),重新构建。

但如果你手上只有 dist、没有源码,或者不想为一次挪窝重开构建环境,那就 sed 改相对路径。这是补丁,不是修复——记下来,下次构建时把 base 配对,否则每次更新都要重来一遍。

收敛成一句话

「首页能打开」不等于「搬运成功」。绝对路径是构建产物对自己位置的硬编码假设,换了位置这个假设就失效了。

搬之前 grep 一次,比部署后一个个 404 试快得多。