
接手一个遗留项目或者做代码评审的时候最头疼的不是业务逻辑有多绕而是代码里那些散落的 TODO、FIXME 注释——它们像地雷一样埋在几千个文件里有的写着“后面要改”有的写着“这里可能有 bug”但没有人知道它们到底在哪、对应哪段逻辑、又堆积了多久。我在本地重度依赖一个 VS Code 插件叫 Todo Tree它能把代码里所有 TODO、FIXME 之类的高亮注释自动扫描出来整理成一棵可以点开跳转的“技术债清单树”。这篇文章就围绕 Todo Tree 展开聊聊它的工作思路、核心配置、真实工作流和踩过的坑适合正在做项目维护、代码重构、或者想把自己工作区里的注释债务看明白的开发者。1. 项目整体设计与思路拆解1.1 Todo Tree 到底解决了什么问题先说结论Todo Tree 是一个基于 VS Code 的高亮注释管理工具核心能力是扫描当前工作区内所有代码文件把符合规则的注释标签默认是 TODO、FIXME、HACK 等提取出来按文件路径和标签类型组织成树状列表显示在单独的面板里。点击列表项就能直接跳转到代码对应行同时注释文本中的关键词会被高亮。这个需求听起来小儿科但真正写代码的人都知道IDE 自带的问题面板只管编译错误和警告根本不管注释里写的“待办事项”。代码里的 TODO 注释本质上是一种“给未来的自己留的口信”可一旦项目大了、人员流动了这些口信就成了信息孤岛。Todo Tree 做的事情就是把这些孤岛串联起来变成一个可视化清单让技术债无处可藏。我最早接触这类需求的时候用的是最笨的方法——全局搜索“TODO”然后在搜索结果列表里一条条看。问题很明显搜索结果把注释和正常的字符串混在一起噪音大没有按文件折叠几百个结果滚半天换一个标记词又得重新搜。Todo Tree 的核心思路就是用“约定优先”的方式解决这个痛点把注释标签当作一等公民用正则规则解析再用树形结构组织整个过程不依赖语言语义分析只依赖文本匹配。1.2 设计上高明在哪文本解析而不是语义分析Todo Tree 没有走重型路线。它没有尝试理解你的代码上下文也没有建索引数据库而是基于每个文件的文本内容按行扫描用正则表达式匹配注释标记然后统计结果。这在方法论上很像“日志采集”而不是“代码理解”。这个设计选择非常务实。如果走语义分析路线那就得适配每种编程语言的注释规范成本高不说对动态语言来说准确率也很难保证。基于正则提取的方式有三个明显优势对语言无要求无论是 JavaScript、Python、Go 还是 Markdown、配置文件只要注释语法能被识别就能扫。扫描速度极快因为只是字符串匹配不涉及语法树打开大项目也能很快渲染。规则透明用户可以通过修改正则表达式的配置自定义哪些文本算“待办标记”灵活性很高。我在实际使用中明显感觉到对比那些试图做“全局代码语义索引”的插件Todo Tree 的响应速度是碾压级的。打开一个包含几千个文件的前端工程面板几乎秒开滚动也很顺滑没有那种“等待索引完成”的焦虑感。1.3 工作区范围与符号树的组织逻辑Todo Tree 的面板默认按“文件路径”组织成树每个标签在树里是一个叶子节点。你可以在“视图”面板里展开任意文件夹看到该目录下所有匹配的注释也可以按标签类型TODO、FIXME分组甚至按标签颜色分组。这个树状结构的交互有点像文件资源管理器只是展示的不是文件而是“待办项”。更深一层Todo Tree 还利用了 VS Code 的“符号”能力——它能把 TODO 标签作为工作区符号处理。这意味着你可以通过 CtrlShiftOmacOS 上是 CmdShiftO输入“TODO”来快速搜索整个工作区的标签符号也可以在编辑器标题栏的面包屑里看到当前文件中有哪些待办标记。我在维护一套老旧的电商后端服务时就靠这个符号视图快速定位过一类很隐蔽的问题某个数据迁移脚本里散落了十几个 TODO注释写的是“一个月后需要清理临时表”。正常全局搜索也能搜到但从符号视图点进去会直接聚焦到注释行而且能看到函数上下文排查效率高很多。2. 核心配置解析与实操要点2.1 安装之后先改这五个配置Todo Tree 默认配置对大多数人已经够用但它真正强大的地方在于自定义能力。下面是我每次在新环境里落地这个工具时必调的五个配置项逐个说明用途和背后的逻辑。第一todo-tree.general.tags。这是最核心的配置用来定义哪些标记算“待办标签”。默认值是[TODO, FIXME, HACK]。我会把它改成[TODO, FIXME, HACK, XXX, BUG, NOTE]因为实践中很多人会写“XXX这里逻辑有问题”或者用“BUG”标注已知缺陷。“NOTE”也不是可留可不留它往往能帮你看出代码里哪些地方被反复解释过——解释得越多的地方往往越值得重构。第二todo-tree.highlights.defaultHighlight。这个配置控制高亮效果里面的icon和foreground决定注释在代码里长什么样。我会把 FIXME 单独设置成黑底红字让它比 TODO 在视觉上更刺眼。这种视觉权重划分对“技术债分级”很重要你扫一眼代码就能区分“紧急缺陷”和“后续优化”。第三todo-tree.general.autoRefresh。这个开关决定文件保存时是否自动刷新树。默认是开启的但我建议在打开超大项目时把它关掉改成todo-tree.general.autoRefresh: false然后通过手动刷新按钮或者Todo Tree: Refresh命令绑定快捷键shiftcmdR来控制刷新时机。原因是文件保存触发全量扫描时超大项目会出现明显的卡顿关掉自动刷新后体验会稳定很多。第四todo-tree.filtering.includeHiddenFiles。默认情况下Todo Tree 不会扫隐藏文件和node_modules、.git这类目录。这个默认行为非常正确但要注意如果你在项目里用了.env.example这样的隐藏配置文件想要在里面标 TODO 让它被扫到就需要显式打开 includeHiddenFiles。反之如果发现扫描结果里混进了大量依赖包里的注释就要检查是不是哪个配置把它带出来了。第五todo-tree.regex.regex。如果你对默认标签规则不满意可以直接覆盖这个正则。默认值大致是(//|#|!--|;|/\*|^|--)\s*($TAGS)它的意思是在某些注释符号比如//、#、!--、;、/*、行首、--后面跟着一个或多个空格再跟上你的标签。我强烈建议不要轻易动这个正则因为它要兼容多种语言非常繁琐一旦写错会导致完全认不出注释。2.2 标记的优先级与图标主题除了“能不能扫到”Todo Tree 还解决“扫到了怎么区分”的问题。面板里每个条目都会有图标默认来自内置的图标集但图标风格是可以换的。todo-tree.icons.theme这个配置可以选default、minimal、people等主题后面几个是社区贡献的图标包。图标不只是好看更重要的是帮助你在视觉上快速分类。默认情况下TODO 是一个绿色的小圆圈FIXME 是一个红色的小三角HACK 是一个黄色小锤子。如果你的项目自定义了很多标签建议把标签对应的图标按“严重程度”分级——紧急用实心红色普通用空心黄色优化建议用灰色。这样展开树的时候严重事项一眼就能跳出来。还有一个很隐蔽但非常实用的小功能标签的“匹配大小写”选项。todo-tree.general.tagGroups和matchCase配合可以区分todo和TODO。有些团队约定小写 todo 只是普通备注大写 TODO 才是正式待办这种精细区分在统一代码规范的项目里很有价值。2.3 过滤器的使用逻辑Todo Tree 的过滤器很容易被忽略但恰恰是把这工具推向高级用法的关键。todo-tree.filtering有三组配置include、exclude、excludeGlobs。先说include。它的作用是“只看某些目录”。如果你只想关注src目录下的 TODO不想看test目录里的可以加一条路径包含规则。我用过这个功能来应对“重构工作量评估”——把include限定在被重构模块的目录下看到的结果就是这次重构真正需要处理的待办数量。再说exclude。它用来排除特定路径比如docs目录里大量“待补充说明”的 TODO 对你没有参考价值直接排除。excludeGlobs则支持通配符模式比如排除**/*.min.js这样的压缩文件避免扫描产物的噪音。这里有个实操心得过滤器匹配的是路径字符串不是 gitignore 规则。配置的时候要小心一旦写错规则比如路径分隔符写反了Windows 是反斜杠配置里要统一用正斜杠匹配会全部失效。我踩过这个坑最后把路径全部改成仓库根目录相对的写法并且用/分隔才恢复正常。3. 实操过程与核心环节实现3.1 从零到一首次配置与面板布局我以一个新接手的全栈项目为例演示一遍 Todo Tree 的完整落地过程。项目是一个电商管理后台前端 Vue、后端 Python Flask、数据库迁移脚本若干总文件数大概 3000 个。第一步安装插件。打开 VS Code 扩展市场搜索 “Todo Tree”认准作者是Foojee的那个。安装完成后重启窗口或者直接打开文件面板就能看到侧边栏多出一个“TODO”树。首次打开时会自动扫描全工作区一般几秒到几十秒不等取决于文件数量和磁盘速度。第二步调整视图方式。在 Todo Tree 面板右上角的“视图”按钮或者是视图切换的图标可以选三种展示模式按树形列表、按扁平列表、按标签分组。我推荐第一周先用“树形列表”因为接手项目时你要先建立“哪些目录有债”的空间感后面要清零某个具体类型的标签再切到“按标签分组”。第三步打开设置 JSON。在设置界面搜todo对所有Todo Tree前缀的条目点右上角的“在 settings.json 中编辑”集中管理。这一步很关键如果你用 UI 零散地改回头很难复查到底调了哪些参数。第四步写入我常用的基准配置。下面这份配置可以直接抄走适合大多数 Web 项目{ todo-tree.general.tags: [TODO, FIXME, HACK, XXX, BUG], todo-tree.highlights.defaultHighlight: { icon: check-circle, foreground: #CCCCCC, background: rgba(0, 0, 0, 0.1) }, todo-tree.highlights.customHighlight: { FIXME: { icon: alert, foreground: #FFFFFF, background: #B71C1C, gutterIcon: true, rulerColor: #B71C1C }, TODO: { icon: list, foreground: #2E7D32, background: rgba(46, 125, 50, 0.1), gutterIcon: true, rulerColor: #2E7D32 }, HACK: { icon: tools, foreground: #F57F17, gutterIcon: true }, BUG: { icon: bug, foreground: #D32F2F, background: rgba(211, 47, 47, 0.2), gutterIcon: true } }, todo-tree.general.autoRefresh: false, todo-tree.filtering.enabled: true, todo-tree.filtering.includeHiddenFiles: false, todo-tree.filtering.excludeGlobs: [**/node_modules/**, **/dist/**, **/build/**] }第五步验证效果。打开项目根目录下任意一个.vue文件在 JavaScript 块里写一行// TODO优化这里的表单校验逻辑保存后手动执行Todo Tree: Refresh命令面板里输入或绑定快捷键。正常情况下面板里会出现这一条并且文件行号旁边会出现绿色图标。3.2 重构前如何使用 Todo Tree 做“排雷计划”我实际用得最有价值的一个场景是重构前用 Todo Tree 输出一份“排雷清单”。具体操作方式如下第一步对整个工作区刷新一次 Todo Tree然后把面板里的所有条目导出成清单。Todo Tree 自带“导出”功能在面板右上角的三个点菜单里可以选 Export能生成一个 JSON 文件里面包含路径、行号、标签、注释文本。我一般直接把它拉到一个表格工具里按标签类型统计数量先摸清“这个项目里有多少个 FIXME、多少个 HACK”。第二步按目录分组分析。把导出的 JSON 按一级目录聚合重点看业务模块目录如src/modules/order、src/modules/payment的待办密度。密度高往往意味着这个模块改动频繁、质量欠稳定是重构的重点候选对象。第三步给每个条目按“风险级别”人工打标。这一步不是 Todo Tree 自动做的但它提供的注释原文和上下文跳转能节省大量阅读时间。我会快速浏览每个条目把带有“崩溃”“空指针”“数据不一致”字眼的 FIXME 标为 P0把“后续优化”“可以考虑”标为 P2。最后形成一个有优先级的行动表比打开几十个文件漫无目的地找靠谱得多。第四步把排雷清单纳入迭代计划。每解决一个条目就在代码里删掉对应的注释。这样当前工作区的 Todo Tree 条数会肉眼可见地变少这种“清扫过程可视化”对团队信心有很大帮助也让代码审查更有据可循。3.3 结合 Git 分支做“注释差异审计”Todo Tree 本身不直接和 Git 联动但配合 VS Code 的源码管理面板可以用一套简单的办法做“注释差异审计”在你切换分支、合入新代码之后快速看出这个分支比主干多了哪些 TODO。操作思路是先切到主干分支刷新 Todo Tree导出一份 JSON切回特性分支再刷新导出另一份 JSON用 diff 工具对比两份文件。新增的条目就是这次改动的“新增技术债”已删除的则是改动时顺手还掉的债。我实际用过一次后很震撼。我们团队一个前端伙伴的合入请求代码量不大但对比之后发现他新增了 11 个 TODO、2 个 FIXME全部集中在刚适配的新接口逻辑上。评审的时候我们就有针对性地追问“这几个 FIXME 什么条件下会触发要不要合并前先解决”如果没有这个对比流程这些条目大概率会被忽略等上线后变成线上问题排查时的盲区。这个方法也适用于个人开发每天下班前跑一次对比把今天新增的 TODO 记到自己的任务笔记里第二天开工就能明确优先级。4. 常见问题与排查技巧实录4.1 扫不到注释正则与文件范围的坑最常见的问题就是“我写了 TODO 但面板里没有”。我排查这个问题的顺序是先在设置里确认todo-tree.general.tags是否包含你写的标签原词注意大小写敏感性再看文件是否被excludeGlobs排除最后检查文件类型——Todo Tree 默认不会扫描gitignore中忽略的文件也不会扫描二进制文件。一个很容易忽视的细节是Todo Tree 只认“注释”不认字符串。比如你在console.log(TODO: 修复这个 bug)这段字符串里写了 TODO默认情况下是扫不到的因为正则要求 TODO 前面要有注释标记符。如果你硬要连字符串一起扫需要改todo-tree.regex.regex但我劝你千万别干这种事噪声会大到你怀疑人生。另一个隐蔽问题是“多行注释匹配”。Todo Tree 对/* TODO */这种跨行块注释的支持是有的但只匹配块注释开头那一行。如果你把 TODO 写在注释块中间比如/* * 这里做了一堆操作 * TODO: 后面要拆成函数 */这样也能扫到因为正则匹配的是行首的*加空格加TODO。但如果你用了缩进或者注释风格不规范比如*TODO:中间没空格就认不出来了。遇到这种情况我建议直接改代码规范而不是魔改正则。4.2 面板卡顿与自动刷新冲突在超大项目里Todo Tree 最常见的性能问题是每次保存文件都会触发全量扫描导致编辑器卡顿甚至出现“Todo Tree 面板一直在转圈”。原因是autoRefresh默认开启而扫描范围是当前整个工作区。我的解决办法是不完全关掉自动刷新而是配合“延迟刷新”。新版 Todo Tree 支持一个配置叫todo-tree.general.refreshDelay单位是毫秒。把它从默认值调大一些比如设成 1000~2000ms保存文件后不会立刻全量扫描而是等一小段时间再统一刷新。这个策略相当于给扫描加了“防抖”在体验上既保留了自动更新又避免高频保存时反复全目录匹配。还有一个跟files.exclude相关的坑如果项目里有动态生成的大文件比如 lock 文件、快照文件、mock 数据它们会被扫进 Todo Tree。我建议在.gitignore里忽略它们的同时在 Todo Tree 的excludeGlobs里也同步加一条毕竟插件不会自动读取 gitignore 规则。我后来养成一个习惯每次给项目新增“生成物目录”第一时间同步改 Todo Tree 排除项。4.3 短横线符号和编码相关的边缘案例Windows 环境有个常见的坑路径里有中文或者空格Todo Tree 的路径显示有时会异常但跳转功能不受影响。这是因为树形展示用了相对路径拼接如果仓库根目录名本身有特殊字符面板里的根节点展示会不太对。我不建议为了这个去改配置修复方法很简单直接用“命令面板中的Todo Tree: Open File”输入目标文件名就能定位。另一个案例是“标签被注释符号截断”。比如 Python 里# TODO这里要处理 None 值如果整行前面有缩进而正则模板里的注释符号匹配范围没有覆盖到缩进场景就会漏扫。好在默认正则支持行首空白前缀但如果你自定义了正则务必在测试环境先拿几个不同语言的文件做验证。我这里可以给一份按不同语言的标签写法规范表都是实测能正常识别到 Todo Tree 里的语言类型注释写法示例是否可被默认识别JavaScript/TypeScript// TODO: 优化渲染是Python# TODO: 修复边缘情况是HTML!-- TODO: 补充文案 --是CSS/* TODO: 换变量 */是YAML# TODO: 调整超时时间是Shell 脚本# TODO: 兼容 zsh是Java// TODO: 捕获异常是如果你写的是//TODO:冒号前没有空格默认正则也能匹配因为标签前后允许空格的写法是可选的。但为了团队统一和插件识别率我强烈建议在代码规范里加上一条“TODO 后面必须跟一个空格或冒号”。4.4 树形面板消失或内容不全有段时间我升级了 VS Code发现 Todo Tree 面板不显示了吓得以为是插件坏了。实际原因是新版 VS Code 改了活动栏图标的位置需要手动把 Todo Tree 图标拖到侧边栏或者通过“查看 - 打开视图”手动找回。这种问题不是 Bug但很干扰节奏知道了就很好解决。内容不全的情况多半是todo-tree.general.scheme配置的问题。Todo Tree 能扫描所有 VS Code 能识别的文件 scheme包括file本地文件、untitled未命名临时文件但默认不开 untitled。如果你在未保存的新文件里写了 TODO想让它出现在树里就得把scheme加上untitled。说实话我不太推荐这个用法临时文件的注释进入技术债列表会污染清单但确实有人需要这里提一嘴。5. 同类工具对比与边界思考5.1 和 TODO Highlight、Code TODOs 的取舍市面上和 Todo Tree 功能有重叠的插件不少我在不同阶段都试过。简单对比一下TODO Highlight主要管“高亮显示”它能让你在代码里看到醒目的 TODO、FIXME 标记色块但没有树形列表、没有跨文件的汇总视图。如果你只是浏览单文件时不想漏掉注释它更轻量。Code TODOs走的是铿锵风格把一个 TODO 关联到 GitHub Issue 或 GitLab Issue适合完整工程闭环团队但配置繁琐还需要远程仓库权限。Todo Tree 的定位介于两者之间既有高亮又有树形管理而且不依赖远程服务。适合个人开发者也适合没有强制“注释关联工单”的团队。我自己最终还是长期用 Todo Tree因为它在“轻量”和“可控”之间平衡得最好——我不用被工具绑架去建一堆 Issue也能在需要的时候导出一份清单。5.2 Todo Tree 的边界什么场景它不擅长Todo Tree 不是代码质量检测工具它不判断注释内容的质量也不会主动提醒你“某个目录的 TODO 过剩”。它只是一个索引器把注释变成清单。因此如果团队里根本没人写 TODO 注释装了它也不会变出一朵花。另外Todo Tree 的扫描单位是“文件”不是“函数”。如果你想看到“某个函数里有几个 TODO”只能靠跳转后肉眼观察没有自动聚合到符号级别的能力。这在做细粒度技术债审计时会被折腾一下但对我来说还好——把 TODO 导出后再用脚本按函数上下文聚合也不是难事。最后它默认不做“时间提醒”。注释里写“两周内解决”是纯文本Todo Tree 不会帮你设置 Deadline。真有这种强时效需求应该配合任务管理工具而不是指望 IDE 插件。这个边界想清楚对工具的使用预期就不会跑偏。6. 扩展玩法让 Todo Tree 融入自动化工作流6.1 把 Todo Tree 导出结果接入 CI 门禁前面提到导出 JSON 功能很多团队没意识到这可能是上工程化门禁的好苗子。你可以对导出的 JSON 做简单的统计比如要求“每个新增 MR 里更新的 TODO 数量不得超过 5 个”超出则提醒评审者注意。这个方案不需要引入额外的商业工具只需要一段 Node 脚本或者 Python 脚本解析导出文件。我在一个半夜上线事故后给团队搭过类似的“技术债水位线”脚本每周一早上扫描主干分支的 Todo Tree 导出结果把数量做成趋势图。这条线不卡发布但能让管理者看到债务在涨还是跌。人都有惰性当看到自己手写的 TODO 出现在周报图表里的数据点位上整改意愿会明显提升。6.2 配合代码模板规范注释写法还有一个小窍门在代码片段Snippet里固化 TODO 注释格式。比如在 VS Code 的用户代码片段里为 JavaScript 配置一个tt前缀自动展开成// TODO: [$DATE] $CURRENT_TIME 需要完成的内容描述为什么要带日期因为 Todo Tree 的标签本身不记录时间日期可以帮助你在审计时快速判断这条注释“堆积了多久”。这是我个人认为最有价值的一个自定义扩展。配合todo-tree.highlights.customHighlight对超过一定年份的 TODO 做特殊颜色就能形成“老龄化负债”的视觉冲击。当然更酷一点的方案是写一个 VS Code 扩展扩展或者用 GitHub Actions 每周两次自动跑一个 CLI 版的扫描脚本但那就是另一个项目的范畴了。Todo Tree 的价值恰恰在于它是“最后一公里”的呈现层无论注释是哪里产生的它都能及时反映到开发者的操作界面上。7. 我的最终使用习惯与个人建议到这里Todo Tree 能做的事已经聊得差不多。我个人在使用中最依赖的组合是关闭自动刷新手动用shiftcmdR控制刷新每个周末花十分钟看一下 FIXME 数量有没有增加每次重构一个模块都会先导出一份 TODO 清单作为行动基线。还有一个小心得想分享别为了让面板“好看”而疯狂自定义标签和图标。标签太多会稀释注意力我给团队定的红线是只允许五个标签TODO、FIXME、HACK、BUG、NOTE。颜色控制在三档红黄灰。工具本身提供强大的自定义能力但使用上一定要做减法否则等于把自己的眼力折腾进另一个泥潭。踩过几次坑之后我慢慢理解了一个道理技术债从来不会因为你不看就消失也不会因为一个插件就清零。Todo Tree 能做的是把“我不知道这里有问题”变成“我知道这里有七个问题”。用好它的关键不在于研究多少配置项而在于把它纳入你自己的开发闭环——刷新、查看、导出、清理。坚持半年之后你再看自己的工作区那种清单上的条目越来越少的感觉比任何代码指标都更让人踏实。