AI多Agent协作系统实战(三十六):代码里明明写了,编译完怎么没了?

头像加载失败,排查半天:源码里明明白白写着"域名拼接"的逻辑,编译出来的产物里------这行代码消失了。不是bug,不是网络,是编译器悄悄把我的代码"优化"掉了。

现象:头像一片空白

移动端App更新后,登录进去------右上角头像空白。

正常来说,头像应该显示用户上传的照片。查网络、查接口、查权限......都没问题:

  • 接口正常返回头像路径:/uploads/avatar/1_1785567950217.png
  • 图片文件存在(直接访问200)
  • 但页面上就是不显示

打开浏览器控制台,看到一个404:

ruby 复制代码
GET http://192.168.3.150:8080/mobile/uploads/avatar/1_1785567950217.png → 404

注意看路径------多了一个/mobile 正确的路径应该是 http://192.168.3.150:8080/uploads/avatar/...(根路径),但它被解析成了 /mobile/uploads/...(移动端目录下)。

排查:源码里明明有拼接逻辑

页面在 /mobile/ 目录下,头像用的是相对路径 /uploads/avatar/...------相对路径在子目录页面下会被错误解析。解决办法是在路径前拼上域名(origin)。

打开源码,发现这个逻辑明明写了

javascript 复制代码
// 源码(login/index.vue)
const avatarUrl = computed(() => {
  if (!userInfo.avatar) return ''
  if (userInfo.avatar.startsWith('http')) return userInfo.avatar
  return window.location.origin + userInfo.avatar  // ← 拼接域名,明明在这!
})

window.location.origin------把域名拼到相对路径前面,得到完整的 http://192.168.3.150:8080/uploads/avatar/xxx.png逻辑是对的,代码是有的。

那为什么页面还是404?

根因:编译器把代码"优化"没了

打开编译后的产物(Vite打包生成的JS文件),搜索这段逻辑:

javascript 复制代码
// 产物(编译后的 chunk)
N = computed(() => {
  return userInfo.avatar || ''   // ← 拼接逻辑呢?没了!
})

window.location.origin + 这一段,在编译产物里消失了。 源码里明明有,编译完只剩 userInfo.avatar 直接返回。

这是构建工具(Vite 5.12)的产物生成缺陷------某个构建环节把这段拼接逻辑丢掉了(类似的问题还有:组件事件绑定丢失、输入框属性错乱、文字组件渲染异常------同一批构建事故)。

源码是完整的,产物是残缺的。 我们一直在查"代码有没有写错"------其实代码没错,是编译过程把对的代码弄丢了

修复:改产物 + 修源码,双保险

第一步,直接修复当前产物(生产环境跑的是产物,等不了重新构建):

javascript 复制代码
// 产物修复:把拼接逻辑补回去
N = computed(() => {
  const a = userInfo.avatar || ''
  return a && !/^https?:/.test(a) ? window.location.origin + a : a
})

第二步,源码也要加固 ------但更重要的是:以后每次构建完,必须验证产物和源码一致(关键逻辑在产物里 grep 验证)。

三条教训

第一,源码 ≠ 运行代码。 用户跑的是编译产物,不是你的源码。"我代码里写了"不是结论------"产物里也有"才是。 排查问题永远从产物入手,不要从源码入手------源码是愿望,产物是现实。

第二,构建工具也会出错。 我们默认"编译器是可靠的"------但遇到"源码有逻辑、产物没有"的灵异现象时,要敢于怀疑构建链本身。构建产物是"编译+优化+打包"的产物,任何一环都可能吃掉代码(尤其是tree-shaking、minify这类"优化"环节------优化器觉得"没用"的代码会被删掉,即使它有用)。

第三,修复要落在"运行的东西"上。 当时如果只改源码不修产物------构建一次又可能丢一次。先让线上恢复正常(改产物),再让源码正确(改源码),最后让流程防复发(构建后自动验证)。 三层都要做,只做一层是假修复。

结尾

头像修好后,我们给构建流程加了一步:构建完成后,自动在产物里验证关键逻辑 (比如grep location.origin,找不到就报警)。

从那以后,这种"编译吃掉代码"的事再没发生过------因为构建产物不再是黑盒,每次发布都被验证过

源码是愿望,产物是现实。别问"我是不是写错了"------去问"产物里到底有没有"。

你的代码没丢,只是编译器替你做主了。

(完)


本文是"多Agent派发系统"系列第36篇。第35篇讲AI幻觉(把见过当做过),这一篇讲构建产物丢失(把写过的当没有)------都是"现实与期望不符"的灵异事件,一个出在AI,一个出在编译器。

相关推荐
步行cgn13 分钟前
Maven 中:作为父项目和作为依赖的本质区别
后端
65岁退休Coder1 小时前
LangGraph v1.2.9 节点容错策略 & 流式输出 & 持久化记忆管理
后端·python·langchain
元界metalite3 小时前
SpringBoot整合RocketMQ-毒丸消息还要无限重试吗
后端
SimonKing4 小时前
升级Spring Boot 4后,从 Jackson 2 到 3,到底有哪些变化
java·后端·程序员
YIAN4 小时前
Docker + Nginx 核心原理扫盲:从环境隔离到反向代理,运维面试必考点
后端·docker·面试
万物智能4 小时前
启动链路与分区—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
后端·架构
寒蝉1284 小时前
一个简单操作是怎么在分布式环境下变复杂的
后端
苏三的开发日记4 小时前
Windows宿主机+VMware CentOS虚拟机 + 同一个Wi-Fi下的其他实体电脑,三者可以互相访问
后端
boooooooom4 小时前
手把手做一个图 RAG 烹饪问答系统:Neo4j + Milvus + LLM 的工程实践
前端·javascript·后端
newerp4 小时前
Golang 切片底层结构
后端·程序员·go