我重构了公司最老的后台,这 5 个教训值 10 万

1 阅读3分钟

我重构了公司最老的后台,这 5 个教训值 10 万

关键词:重构、渐进式迁移、设计系统、接口契约、技术债

一、接手那个"祖传项目"

入职第二周, leader 指着一个跑了 6 年的后台说:"这摊子你接一下。"打开一看:jQuery + 手写模板 + 全局变量满天飞 + 没有任何构建工具。改一个按钮样式,整站抖三抖。

我犯了每个年轻工程师都犯过的错——"干脆重写得了"。然后差点把业务搞崩。这篇文章是我用两周加班换来的 5 条血泪教训。

二、教训 1:永远不要"一次性重写"

我第一版方案:新框架搭好,一次性切。结果:旧功能 200 多个,新系统只还原了 60%,剩下的要么搬错要么漏了,测试同学天天找我。

正确做法: strangler fig(绞杀者)模式。旧系统继续跑,新功能用新框架写,通过路由/iframe 逐步替换,老模块一个个"绞杀"掉。业务零中断,风险可控。

第 1 周:新壳 + 用户管理(新)
第 3 周:订单模块迁新,旧订单路由 301 到新
第 6 周:老系统只剩登录页,最后一刀砍掉

三、教训 2:先建设计系统,再写业务

第二坑:没统一组件就开干,结果三个人写出三种按钮、四种表格。后面返工统一,等于做两遍。

先花 3 天建 design tokens + 基础组件库(Button/Table/Form/Modal),业务组件全基于它。后面加页面是搭积木,不是从和泥开始。

四、教训 3:接口契约先于前端

老后端接口字段命名一言难尽(u_nameisdelcretime)。我直接在后端没改的情况下前端硬接,写满 data.u_name 这样的代码,后期后端规范化时我全网替换,差点出事故。

正确:前后端先定 OpenAPI / TypeScript 类型契约,字段名、必填、枚举先对齐。哪怕后端暂时不改,前端也用一层 adapter 隔离,脏数据不进业务层。

// 前端适配层,隔离老接口脏字段
function adaptUser(raw: RawUser): User {
  return { name: raw.u_name, deleted: raw.isdel === 1, createdAt: raw.cretime };
}

五、教训 4:没有监控的重构是裸奔

重构期间我靠"感觉没报错"判断,直到运营反馈"导出按钮点了没反应"才知道某模块挂了。

必须上监控:前端错误上报(如 Sentry)、关键路径埋点、重构前后核心指标对比看板。每一次模块切换,先看错误率曲线,再放量。

六、教训 5:给回滚留后路

最重要的一条。我曾在周五下午切了订单模块,周一爆出历史订单金额显示错位。幸亏留了开关:

// feature flag,一键回滚
if (flags.useNewOrder) render(NewOrder); else render(LegacyOrder);

有开关,5 分钟回滚;没开关,周末加班背锅。任何重构都要有"一键回到昨天"的能力。

七、写在最后

这 5 条如果早点知道,我能少加班至少 80 小时,也少背几次锅。重构不是炫技,是在不动业务的前提下,悄悄把地基换掉

如果你也在面对祖传代码,记住这句话:别重写,要绞杀;先设计,再契约,带监控,留后路。


关注我,前端干货持续输出。下期想看哪块?评论区告诉我。