您现在的位置是:网站首页 > 代码里留坑(“// TODO: 这里有个 BUG,以后修”)文章详情
代码里留坑(“// TODO: 这里有个 BUG,以后修”)
陈川
【
前端综合
】
8282人已围观
2143字
代码里留坑(“// TODO: 这里有个 BUG,以后修”)
程序员们对这样的注释再熟悉不过了。明明知道有问题,却因为时间紧迫、需求变更或其他原因,选择暂时搁置,留下一个“TODO”标记。这些标记像地雷一样埋在代码里,随时可能引爆。
为什么会出现“TODO”注释
开发过程中,时间压力是最常见的原因。产品经理催着上线,测试团队等着验收,开发者只能先保证主要功能正常,次要问题暂时放一放。比如:
function calculateDiscount(price, coupon) {
// TODO: 这里需要验证优惠券有效期
return price * 0.9; // 临时写死9折
}
技术债务就这样产生了。还有团队协作时的沟通问题:
// TODO: 这个API返回的数据结构不稳定,等后端修复后再调整
interface UserData {
name: string;
age?: number; // 实际有时是字符串
}
“暂时”可能变成“永远”
很多“TODO”注释最终都被遗忘。随着代码迭代,当初的上下文逐渐丢失,后来者要么不敢动这块代码,要么根本不知道这里有坑。一个典型场景:
function formatDate(date) {
// TODO: 时区处理有问题,需要重写
return date.toLocaleString(); // 会使用浏览器时区
}
半年后,国际用户投诉时间显示错误,开发者才想起这个被遗忘的TODO。
什么样的TODO可以接受
并非所有TODO都是坏的。以下几种情况可以接受:
- 明确短期计划的:
/* TODO: 下周设计系统更新后改用新颜色变量 */
.button {
color: #3a86ff; /* 临时色值 */
}
- 需要特定条件才能解决的:
// TODO: 等浏览器支持率超过95%时改用原生dialog
showModal() {
$(‘#modal’).show(); // polyfill
}
更好的处理方式
比起裸TODO,更推荐这些做法:
- 关联任务管理系统:
// JIRA-1234: 输入框在iOS下会闪屏
input.addEventListener(‘focus’, () => {
/* 临时解决方案 */
});
- 使用类型系统标记:
type UnstableApiResponse = {
data: any; // @deprecated 等v2接口上线后移除
};
- 编写跳过测试的说明:
it(‘should work with legacy data’, () => {
// FIXME: 测试偶尔会失败,需要排查内存泄漏
expect(processLegacyData()).toBeTruthy();
});
那些年我们见过的奇葩TODO
真实代码库里的TODO有时让人哭笑不得:
// TODO: 我也不知道为什么要这么写,但改了会出问题
function magicNumber() {
return 42;
}
或是充满无奈的:
/* TODO: 这个!important是PM让加的,他说按钮必须红色 */
.warning {
color: red !important;
}
自动化工具帮忙
现代工具链可以帮助管理TODO:
- ESLint规则可以限制TODO存活时间:
{
"rules": {
"no-warning-comments": ["error", { "terms": ["TODO"], "location": "anywhere" }]
}
}
- 使用git hook防止提交TODO:
#!/bin/sh
if git grep -n "TODO" -- :^documentation; then
echo "ERROR: 代码中包含TODO注释"
exit 1
fi
- 专门的技术债务管理工具,如SonarQube可以追踪TODO注释。
从代码注释到团队文化
比工具更重要的是团队约定:
- 每周固定时间处理积累的TODO
- 代码审查时特别注意TODO注释
- 为每个TODO明确责任人和期限
- 建立技术债务的量化评估机制
一个健康的团队会有这样的注释:
// FIXED-2023-05: 原TODO已由@张三修复
function fixedBug() {
// 新实现
}
上一篇: 关键逻辑不注释(“能看懂的人自然懂”)
下一篇: 不交接工作(离职前删注释、改变量名)