如果让你重构现有项目你会怎么做
问题
如果让你重构一个遗留前端项目,你的思路是什么?
回答思路
1. 重构的核心原则
重构黄金法则
渐进式重构 > 推倒重来。在不停止业务开发的前提下,逐步改善代码质量。
2. 重构前的评估
第一步:理解现状
## 项目现状评估清单
### 代码层面
- [ ] 技术栈版本(React 16? Vue 2? jQuery?)
- [ ] TypeScript 覆盖率
- [ ] 测试覆盖率
- [ ] ESLint 规则数量和违规数
- [ ] 包体积分析
### 架构层面
- [ ] 目录结构是否合理
- [ ] 组件粒度是否适当
- [ ] 状态管理是否混乱
- [ ] API 调用是否统一
### 业务层面
- [ ] 哪些模块变化频率高
- [ ] 哪些模块有已知 Bug
- [ ] 哪些模块是核心业务路径
### 团队层面
- [ ] 团队对现有代码的熟悉程度
- [ ] 团队对新技术的接受度
- [ ] 可投入重构的人力和时间
第二步:确定重构目标
| 目标类型 | 示例 | 衡量标准 |
|---|---|---|
| 可维护性 | 统一代码规范、引入 TypeScript | 新功能开发速度提升 |
| 性能 | 首屏优化、包体积减小 | LCP < 2.5s |
| 开发效率 | 统一组件库、改善构建速度 | 构建时间减少 50% |
| 技术栈升级 | Vue 2 → Vue 3、CRA → Vite | 使用最新特性 |
3. 重构执行策略
Phase 0:准备阶段(不动代码)
添加测试保护网
// 在重构前,先给核心功能加上 E2E 测试
// 确保重构过程中不破坏现有功能
// playwright/core-flows.spec.ts
test('用户登录流程', async ({ page }) => {
await page.goto('/login');
await page.fill('[name=email]', 'test@example.com');
await page.fill('[name=password]', 'password');
await page.click('button[type=submit]');
await expect(page).toHaveURL('/dashboard');
});
test('核心业务流程', async ({ page }) => {
// 覆盖最关键的业务路径
});
Phase 1:基础设施
渐进式引入 TypeScript
// tsconfig.json —— 宽松模式起步
{
"compilerOptions": {
"strict": false, // 先不 strict
"allowJs": true, // 允许 JS 文件
"noImplicitAny": false, // 先允许隐式 any
"skipLibCheck": true
},
// 先只对新文件强制 TS
"include": ["src/**/*.ts", "src/**/*.tsx"]
}
// 逐步收紧:
// 第1月:allowJs + 不 strict
// 第2月:noImplicitAny: true
// 第3月:strict: true(对新文件)
// 第6月:全量 strict
Phase 2:核心模块重构
优先重构的模块选择矩阵:
| 修改频率高 | 修改频率低 | |
|---|---|---|
| Bug 多 | 🔴 最优先 | 🟡 次优先 |
| Bug 少 | 🟡 次优先 | 🟢 最后/不动 |
4. 风险控制
| 风险 | 缓解措施 |
|---|---|
| 重构引入新 Bug | E2E 测试保护网 + 灰度发布 |
| 业务开发被阻塞 | 并行工作,不停业务 |
| 进度失控 | 小步提交,每个 PR 独立可部署 |
| 团队抵触 | 展示收益、让大家参与决策 |
| 半途而废 | 项目化管理,设里程碑 |
重构的最大风险
不是技术风险,而是组织风险——失去管理层支持、业务压力导致重构被搁置。所以需要持续展示重构成果。
常见面试问题
Q1: 重构和重写有什么区别?什么时候该重写?
答案:
| 维度 | 重构 | 重写 |
|---|---|---|
| 定义 | 不改变功能,改善代码结构 | 从零开始重新开发 |
| 风险 | 低(渐进式) | 高(可能丢失功能细节) |
| 耗时 | 分散在日常开发中 | 需要专项投入 |
| 适用 | 代码有救、架构可优化 | 代码彻底不可维护 |
什么时候该重写:
- 技术栈已经完全过时(如 IE-only 的代码)
- 修改任何功能的成本都比重写高
- 有足够的时间和人力
- 能完整梳理所有业务需求
Q2: 如何说服管理层投入时间重构?
答案:
- 量化技术债成本:"当前每个需求平均开发 5 天,其中 2 天在处理历史代码兼容"
- 预测趋势:"如果不重构,6 个月后开发效率会再降 30%"
- 渐进方案:"不需要停业务,每个迭代投入 20% 时间"
- 展示收益:"重构后新功能开发速度提升 40%,Bug 率下降 50%"
Q3: Vue 2 迁移到 Vue 3 你怎么做?
答案:
关键步骤:
- 先用
@vue/compat兼容层让项目在 Vue 3 上跑起来 - 逐个组件迁移到 Composition API
- 状态管理从 Vuex 迁移到 Pinia
- 所有迁移完成后移除兼容层