← 学习路线

重构时的隐形依赖

删掉一段"看起来没人用"的代码,为什么会弄坏另一个地方?重构之前,怎样找出那些看不见的依赖?

课型:直觉·约 20 分钟·4 个术语

先看出事的那一刻

2026 年 8 月 2 日,站长请 AI 审查一次大重构。打开一个章节页的截图,示意图里的标签背景和车辆全变成了黑色色块,线条也不见了;再打开术语页,本该是图解的地方,只剩一堆没有样式的文字。而这次重构的状态报告里写着:"Mintlify 视觉检查:通过"。

配图用到的颜色都写成了变量,比如 var(--teal)。搜一遍整个项目才发现,这些变量几乎都已经没有定义了。

这节课要回答的是:删掉一段"看起来没人用"的代码,为什么会弄坏另一个地方?重构之前,怎样找出那些看不见的依赖?

装备几个词

为什么要懂

AI 替你做了

AI 重构起来又快又彻底:按新的设计规范删掉旧变量、换掉整套样式表,一次改几千行,构建照样通过。

留给你的

删之前问一句“还有谁在用它”。样式、变量、共享组件之间的依赖,构建时不会报错,只会在页面上悄悄坏掉。

不懂的代价

删完之后一切看起来正常,测试全绿,报告写着“通过”,直到有人打开那个页面,才发现图全黑了。

分几步消失的变量

没有哪一步是"删掉了配图的颜色"。回头看,变量是这样一点点消失的:

时间发生了什么当时看起来
7 月 30 日新的设计规范要求"全站颜色只使用五个根令牌",另一个 AI 按规范删掉了其中 7 个变量规范执行到位
8 月 2 日一个新皮肤的样式表把这 7 个变量重新定义了一遍,但只在它自己的容器里生效在那个皮肤里,图又正常了
8 月 2 日最终采用的是另一个版本,它挂在那个容器外面,看不到这些定义没人注意到
8 月 2 日旧样式表和那个局部样式表先后被删掉构建通过,报告写"视觉检查 通过"

每一步单看都说得通:按规范删、为新皮肤补、删掉不用的旧文件。坏在这一连串里,没有任何一步问过:"图形组件还在用这些变量吗?"

为什么偏偏是黑色

CSS 里引用一个不存在的变量,又没有写兜底值,这条样式就被当作无效,属性退回默认值。填充色的默认值会一路继承下来,最终落到黑色;描边的默认值是"不画",于是线条消失了。

这也解释了为什么构建和测试都没发现:对 CSS 来说,这不是错误,只是"这个值无效,用默认的"。当时项目的 7 项测试全部通过,因为没有一项测试会去看图是什么颜色。

找出看不见的依赖

这类依赖有个共同点:它们不走 import,编辑器和构建工具都帮不上忙。只能靠三个习惯:

  1. 删之前先搜。变量名、类名、组件名,在整个项目里还有谁在引用。
  2. 看作用域。定义在某个容器里的变量,只在那个容器里生效:搜得到定义,不等于用它的地方看得到它。
  3. 改完拿产物比。这个网站把几个组件抽成共用时,逐字节比对了构建出来的 HTML:95 个页面里 94 个完全一样,唯一不同的那个,恰好修掉了一个旧 bug(/e2e 的"主线"栏目从来没有高亮过)。
深潜兜底值的两面+

修复时,一部分变量加上了兜底值,比如 var(--teal, #00b48a):变量找不到时,至少还有一个颜色,不会再出现黑块。

但兜底值也会掩盖问题。下次变量又丢了,页面不会变黑,只会悄悄换成兜底的颜色,和设计规范慢慢对不上,而且更难被发现。

所以修复里更重要的是另一条:设计文档里写明了"图形组件依赖哪些变量",并规定删样式前先对照这份清单。只是这条规矩只写在文档里,没有任何自动检查:它能不能被遵守,取决于下一个动手的人或 AI 会不会去读。

找茬

下面是这条依赖链上的几段真实代码和文档(节选)。配图组件用 CSS 变量取颜色,没有兜底值。找出让这份依赖“看不见”、或者让它断掉却没人发现的地方。

这段 JSX / Markdown / CSS 里埋了 6 处问题。点击你觉得有问题的行,至少找出 3 处再揭晓。

查看代码与答案(6 处问题)
 1  // IntersectionScene.jsx(路口场景图,节选)
 2   * input:  chapter(1-8)
 3  const TEAL = "var(--teal)";  const RED = "var(--red)";  const AMBER = "var(--amber)";
 4  
 5  // MechanismFigures.jsx(机制图,节选)
 6   * input:  无(纯静态图)
 7  
 8  // docs/DESIGN.md(7 月 30 日,节选)
 9  全站颜色只使用以下五个根令牌。组件不得另起 `--red`、`--teal`、`--accent` 或品牌色体系。
10  
11  /* wired.css(8 月 2 日一个新皮肤的样式表,节选) */
12  .wired-experience {
13    --teal: #000000;
14  
15  # STATUS.md(删掉最后一个样式表的同一个提交)
16  | Mintlify 视觉检查 | 通过 |
  • 第 2 行 · 中危 · 文件头只写了一个输入,漏了真正的依赖:文件头说这个组件的输入只有章节号,可它还依赖 8 个 CSS 变量。只看文件头的人(或 AI),不会知道删掉那些变量会影响这里。 该问的话:这个组件依赖哪些外部的东西?文件头注释里都写了吗?
  • 第 3 行 · 中危 · 用变量,却不给兜底值:变量一旦没有定义,填充色就退回默认的黑色,描边直接消失。至少要在删除变量之前,确认这些引用都有着落。 该问的话:这些变量要是没有定义,图会变成什么样?
  • 第 6 行 · 中危 · 写着“无输入”,其实依赖一串变量:"纯静态图"听起来和外界毫无关系,可它同样要读 8 个颜色变量。这句注释让依赖彻底隐身了。 该问的话:这个“纯静态”的组件,真的不依赖任何外部定义吗?
  • 第 9 行 · 中危 · 按规范删变量,没问还有谁在用:规范本身没有错:统一颜色,是好事。问题在于执行时直接删掉了 7 个变量,没有先搜一遍,是谁在用它们。 该问的话:按规范删掉这些变量之前,有没有搜过它们在哪里被引用?
  • 第 12 行 · 中危 · 定义只在这一个容器里生效:变量补回来了,但只写在这个皮肤的容器里。挂在容器外面的另一个版本看不到它们;而在项目里搜索,却能搜到定义,看起来一切正常。 该问的话:这些定义的作用域覆盖了所有用到它们的地方吗?
  • 第 16 行 · 高危 · 删掉样式的同一个提交,写着视觉检查通过:把最后一个样式表删掉的那个提交,同时在状态报告里写下了"视觉检查 通过"。这份报告没有人真的去看过页面。 该问的话:这个“通过”是怎么检查出来的?看了哪些页面?

快测

1. 你删掉了一个 CSS 变量的定义,构建通过、测试全绿。可能出什么问题?

查看选项与答案
  • A. 引用它的地方退回默认值,比如颜色变黑、线条消失(正确)——这正是它难发现的原因:没有报错,只有页面变了。填充色的默认值一路继承成黑色,描边的默认值是“不画”。
  • B. 引用它的地方仍会沿用删除之前的值,页面外观保持不变——定义没了,引用它的那条样式就被当作无效,属性退回默认值,不会沿用旧值。
  • C. 浏览器控制台会报出未定义的变量,一打开页面就能发现——CSS 里引用一个不存在的变量,不算错误。控制台里没有任何提示,构建照样通过,页面只是悄悄变样。

CSS 的依赖断了,不会报错,只会悄悄变样。

2. 在项目里搜索,找到了这个变量的定义。能说明用它的地方都没问题吗?

查看选项与答案
  • A. 能,只要引用处和定义处的变量名拼写完全一致——拼写一致,只说明名字对得上,不说明看得到。定义写在某个容器里,就只有那个容器里面的元素读得到它。
  • B. 不一定,还要看定义生效的范围有没有盖住每一处引用(正确)——搜得到定义,不等于用它的地方看得到它。这次补回来的定义只写在一个皮肤的容器里,挂在容器外面的版本读不到。
  • C. 能,只要定义所在的样式表已经被加载到页面里——加载了样式表还不够。定义写在某个容器里,容器外面的引用照样是无效的。

查依赖时,既要看有没有定义,也要看定义在哪里生效。

3. 重构之后,怎样最快确认页面外观没变?

查看选项与答案
  • A. 跑一遍项目里的全部测试,全绿就可以放心合并——这次的测试也全绿:当时的 7 项测试都通过,因为没有一项会去看图是什么颜色。
  • B. 重构前后各构建一次,再比对构建产物或页面截图(正确)——这个网站抽组件时,就是逐字节比对了构建出来的 HTML:95 个页面里 94 个完全一样,唯一不同的那个,恰好修掉了一个旧 bug。
  • C. 让 AI 把这次的改动逐行复查一遍,没发现问题就行——隐形依赖出在没被改动的地方:引用变量的组件不在这次的改动里,复查改动看不到它。

重构的承诺是外面看不出变化:用前后对比来证明。

判断时刻

新的设计规范要求全站只用五个颜色变量。AI 准备删掉其余的变量定义,它给了三种做法。

你会选哪一个?

三个选项各自的代价
  • A. 按规范直接删掉,构建通过就行——考察信任构建:最快,也最危险:CSS 里引用不存在的变量不会报错,构建永远通过。这次就是这样删掉的,配图全变成了黑块。
  • B. 删之前先搜遍整个项目,把还在用的地方改成新的变量——考察先找依赖:多花一些时间,但每个用到旧变量的地方都有了着落。搜的时候要注意作用域:搜得到定义,不等于用它的地方看得到它。
  • C. 给所有引用加上兜底值,然后放心删——考察兜底的两面:再删变量时不会出现黑块了。代价是变量丢了也没人发现,颜色悄悄变成兜底值,和设计规范慢慢对不上。兜底能防事故,也能掩盖事故。

删东西之前,先问还有谁在用它。构建和测试只能告诉你代码能不能跑,告诉不了你页面还是不是原来的样子。

带走

下次让 AI 做这件事时,问它

  1. 这次要删或要改的变量、类名、组件,在整个项目里还有谁在引用?请全部列出来。
  2. 这些定义的作用域是什么?用到它们的地方都在作用域里面吗?
  3. 有哪些看不见的依赖(样式变量、全局类名、文件路径)?文件头注释里写清楚了吗?
  4. 改完之后,用构建产物或截图比对证明外观没变。

自己验证

  • 全项目搜索要删的名字,比如 grep -rn "var(--teal" src,确认每一处引用都有着落。
  • 改动前后各构建一次,逐个文件比对构建产物,看哪些页面变了、为什么变。
  • 打开用到这些样式的页面,在开发者工具里看计算后的颜色,是不是预期的值。

删东西之前先问一句:还有谁在用它?