1. 当项目里散落了上百个待办标记,我是怎么被Todo Tree救回来的
先坦白一个场景:接手一个中大型项目,代码里到处是TODO、FIXME、XXX这类注释。老同事走之前留下“那几块逻辑先这么写着,回头再改”,于是我在仓库里全局搜了一遍,才发现类似标记居然有上百处。挨个点开文件去对行号,效率低到让人头皮发麻。
后来我在 VSCode 扩展市场里装了 Todo Tree,才算真正把这件事理顺。它会在侧边栏生成一棵可展开的树,把当前工作区里所有匹配到TODO、FIXME、XXX的注释按目录层级列出来,哪个文件第几行有什么待办,一眼扫完。同时还会在代码编辑区给对应注释做高亮,比如背景色、前景色、侧边栏标记,不用切文件就能看到“这里有事”。
这篇文章就围绕三件事展开:Todo Tree 插件的安装与配置、TODO/FIXME/XXX 三种注释标记到底什么时候写最合适,以及怎样把默认的图标和颜色改成自己团队喜欢的样式。适合正在为“散落注释”发愁的开发者,也适合想规范团队注释习惯的组长和负责人。我自己从第一天配好到现在,已经离不开这个工具了,下面把配置思路和踩过的坑一起写出来。
1.1 在全局搜索里翻 TODO 的痛苦
拿最简单的例子说,假设你打开了一个有几十个模块的前端项目,想看看有哪些尾巴没收。全局搜索时,结果会按文件分组,但你想知道“哪些文件优先级高”“哪些是真正修 bug”这类信息,只能挨个点开看注释内容。
更麻烦的是,标记本身没有颜色分级。一个带FIXME的严重问题,和一个随手写的TODO: 优化命名,在搜索结果里长得一模一样。你没法快速判断到底哪件事要先处理。
还有一类困扰是“注释被淹没”。有的团队习惯把标记写在函数注释里,有的喜欢写在某一行末尾,有的甚至写进字符串模板。全局搜索虽然能搜出来,但搜索出来的结果没有上下文语境,你根本不知道这个 TODO 出现在哪个函数作用域、是否已经过期。
1.2 Todo Tree 的两种工作形态
Todo Tree 实际上给了两套体验。
第一套是侧边栏的“待办树”。插件会扫描工作区,把包含标记的注释整理成一棵树:第一层是目录,展开后是文件,点开文件能看到具体的注释行。每一条都带文件路径、行号、注释内容摘要,点击后 VSCode 会直接跳到对应行。如果标记里写了issue: #123之类的编号,还可以直接在预览里看到完整注释。
第二套是编辑器里的“高亮”。匹配到标记的注释行会被插件渲染上颜色,比如我习惯把FIXME设成红底,把TODO设成橙底,把XXX设成紫底。开着代码时,哪个文件里藏了雷,扫一眼就能发现。这比单纯依赖搜索框要直观太多。
这两套形态是互补关系:侧边栏管“我有哪些待办”,编辑器高亮管“我正在写的这段代码里有没有待办”。新装插件后,侧边栏默认就会尝试构建整棵树,但配置不给力的话会出现漏扫或乱扫的情况,所以下面从配置开始讲。
2. 十分钟装好插件并配置出第一棵待办树
2.1 安装并唤起插件
安装很简单:在 VSCode 扩展面板搜 “Todo Tree”,找到对应扩展直接安装。装完后左侧活动栏会出现一个树形图标,点击它就能打开待办树面板。
如果你找不到按钮,也可以直接用命令面板(Ctrl+Shift+P),输入 “Todo Tree: Refresh” 或 “Todo Tree: Show Tree” 来刷新和显示。
我第一次用的时候有个误解,以为插件开启后就会自动把所有带TODO的注释都扫出来。实际上它默认就能识别TODO、FIXME、XXX三种标记,但如果你项目里习惯写BUG、HACK、OPTIMIZE,就需要手动加进标记列表。
2.2 三个最值得先动的配置项
Todo Tree 的配置项不少,但刚开始只需要盯住三个:
第一个是todo-tree.general.tags,它决定插件识别哪些单词。不同版本配置路径可能略有差异,但核心逻辑是一样的:这里维护一个标记集合,凡是注释里出现这些单词,就会被纳入待办树。
第二个是todo-tree.highlights.customHighlight,它决定每种标记长什么样。你可以给TODO、FIXME、XXX分别设置图标、前景色、背景色、侧边栏标记等。
第三个是todo-tree.filtering.includeGlobs和todo-tree.filtering.excludeGlobs,它们决定扫描哪些文件。比如你不想扫node_modules、dist、build这类目录,就可以通过 excludeGlobs 排除掉,避免待办树被无意义的文件刷屏。
2.3 给一个能直接复制的初始配置
我现在的初始配置大概长这样,你可以直接写进settings.json里,然后重启或重载窗口:
{ "todo-tree.general.tags": [ "TODO", "FIXME", "XXX", "BUG", "HACK" ], "todo-tree.highlights.defaultHighlight": { "type": "text", "foreground": "#ffcc00", "background": "#3b2f00", "gutterIcon": true, "rulerColour": "#ffcc00" }, "todo-tree.highlights.customHighlight": { "TODO": { "icon": "circle", "foreground": "#ff9900", "background": "#332200", "rulerColour": "#ff9900" }, "FIXME": { "icon": "circle-filled", "foreground": "#e74c3c", "background": "#3d100c", "rulerColour": "#e74c3c" }, "XXX": { "icon": "alert", "foreground": "#c39bd3", "background": "#2a1b33", "rulerColour": "#c39bd3" }, "BUG": { "icon": "bug", "foreground": "#ffffff", "background": "#6c3483", "rulerColour": "#ffffff" } } }配完之后,你会发现侧边栏里每个标记前都有一个小图标,编辑区里不同标记的注释颜色也完全不同。后面我会细讲icon和iconColour这些字段,这里先跑通第一棵待办树。
提示:改完
settings.json不生效时,记得按 Ctrl+Shift+P 执行 “Developer: Reload Window”,这能解决九成“我明明配了但没反应”的问题。
3. TODO、FIXME、XXX:三种注释标记的语义边界与写法规范
3.1 TODO、FIXME、XXX 分别该在什么时候写
很多开发者其实分不清这三个标记的差别,所以经常混着写。时间长了,待办树里堆了一堆意义模糊的注释。我的建议是先把语义边界定清楚。
TODO表示“这里还有一件事要完成”,通常是待增加的功能、待优化的代码、待补全的边界条件。比如写了接口但没接渲染逻辑,就可以写TODO: 接入列表渲染逻辑。它不代表当前代码是错的,只是还没做完。
FIXME表示“这里已知有问题,需要修复”。它比 TODO 更紧急,通常指向一个明确的 bug、异常或不符合预期的行为。比如某个方法在边界情况下会报错,你可以写FIXME: 传空数组时这里会抛异常。
XXX表示“这里有危险信号,需要特别注意”。它既可以指一段自己都看不下去的代码,也可以指容易踩坑的重构点。比如XXX: 这里依赖了外部接口的返回顺序,千万别随便改动。很多人把 XXX 当作“更重要”的 TODO 用,但我更倾向于把它理解为“警告级别”的标记。
3.2 写在高亮注释里的上下文信息
一个孤零零的TODO其实没多少价值,真正有用的是注释里附带的信息。我的个人习惯是,标记后面至少留四类内容:
- 问题描述:这里具体要做什么、有什么问题
- 上下文线索:跟哪个函数/接口/模块相关
- 负责人标识:谁提的、谁打算改
- 关联编号:issue 编号、工单号或需求编号
比如下面这几行注释就比单纯的TODO要清晰得多:
// TODO: 列表超过 1000 条时需要做虚拟滚动,当前一次性渲染会卡顿 // FIXME: id 为 0 时会被误判为“未设置”,导致数据无法展示 / @A同学 // XXX: 这里的排序依赖后端返回顺序,一旦接入新版接口必须先测回归这样的话,哪怕过三个月再回来翻待办树,你也能根据注释里的上下文快速定位问题,而不是对着一个TODO: 修一下发呆。
3.3 用 tagList 扩展你自己的标记类型
有些团队会有自己的内部标记,比如TEMP:表示临时代码、DEMO:表示演示专用、REFACTOR:表示需要重构。Todo Tree 没有强行限定只能用默认的三个词,你可以把团队词汇表配进去。
配置方式还是回到todo-tree.general.tags,把自定义词加进去,然后在todo-tree.highlights.customHighlight里给每个自定义词配上颜色和图标。
默认帮我处理BUG、HACK也是一样的逻辑。我在上个示例里已经加了BUG和HACK,效果是每个标记在侧边栏和编辑器里都会有自己的专属外观。这里有个细节:自定义标记最好只使用常见英文大写词,不要用中文词,否则可能出现匹配异常。虽然部分新版本能支持 Unicode,但从团队规范角度来说,英文大写词更通用、更不容易在切换语言时出问题。
4. 自制图标样式:从改颜色到完全自定义图标
4.1 Todo Tree 的图标体系是怎么运作的
不少人和我一样,第一批需求不是“想扫描待办”,而是“觉得默认图标不够明显”。Todo Tree 的图标体系其实分成几层:
第一层是侧边栏里每条待办前面的小图标。这个图标由customHighlight里的icon字段控制。我能想到的取值包括circle、circle-filled、dot、check、alert、bug等,具体取决于插件版本和主题。
第二层是代码编辑区左侧的边缘标记(gutter icon)。当gutterIcon设为true时,对应注释行左侧会出现一个小图标。它和侧边栏图标遵循同一条配置逻辑,只是渲染位置不同。
第三层是覆盖标尺(overview ruler)里的颜色刻度。rulerColour能让你在右侧滚动条上看到标记位置。
如果你不满足于内置图标,也可以自己去指定图标路径。我见过有人把TODO图标换成一个小旗帜,把FIXME换成一个小感叹号,本质都是给icon传一个图片路径。
4.2 用内置图标和颜色让三类标记一眼可辨
先讲最常用的一组内置配置。在customHighlight里,每个标记都是一个对象,能设置的常见字段包括:
| 字段 | 作用 | 示例 |
|---|---|---|
icon | 标记前的小图标 | "circle"、"alert"、"bug" |
foreground | 注释文字颜色 | "#e74c3c" |
background | 注释整行背景色 | "#3d100c" |
gutterIcon | 是否显示左侧边缘图标 | true/false |
rulerColour | 右侧滚动条刻度颜色 | "#ff9900" |
iconColour | 仅修改图标颜色 | "#ff9900" |
我给团队配的颜色逻辑是:
TODO用橙色,表示“还有事没做完,但不紧急”FIXME用红色,表示“这里有缺陷,一定要修”XXX用紫色,表示“危险区域,小心改动”BUG用深紫色加白色字,表示“已确认的 bug,优先处理”
这套颜色逻辑和语义是对应的。团队里所有人都能凭颜色判断优先级,而不是靠读注释内容。
4.3 完全自定义:把图标指向自己的图片文件
如果你想更进一步,把默认图标彻底换掉,可以这样做。在customHighlight里给某个标记设置图片路径:
"customHighlight": { "TODO": { "icon": "/Users/you/workspace/icons/my-todo.png", "iconColour": "#ff9900", "foreground": "#ff9900", "background": "#332200" } }这里有几个容易踩的坑:
- 路径尽量写绝对路径或工作区内的绝对路径,因为插件解析相对路径时可能会跟当前打开文件所在目录对不上
- 图片尺寸不要太大,建议 16x16 或 32x32,否则会显得很突兀
- 如果你想要的是“同一图标不同颜色”的效果,直接用
iconColour更省事,不必真的去改图片
如果你记不住哪些内置图标可用,有个笨办法:先随便填一个,比如icon: "circle",然后看侧边栏实际渲染的效果,再逐步替换成circle-filled、check、alert这些。配合重载窗口,来回几次就能找到最顺眼的样式。
4.4 侧边栏显示、折叠与排序的小调整
图标只是“自制样式”的一部分,侧边栏树的展示方式同样值得调。我常用到这几个配置:
todo-tree.tree.showBadges:在标签旁显示匹配数量todo-tree.tree.showCounts:统计某个标记在整个目录下出现多少次todo-tree.tree.expandAll:是否默认全部展开todo-tree.sorting.algorithm:排序规则,默认按文件路径排
个人建议把showCounts打开,这样点开目录就能看到哪个模块待办最多,方便安排重构节奏。如果项目非常大,建议把expandAll关掉,避免插件启动时一次性渲染太多节点导致卡顿。
5. 让注释规范在团队里真正落地
5.1 把规范写进仓库而不是写进会议纪要
光自己会用 Todo Tree 还不够,团队规范如果只停留在口头或会议纪要里,很快就会变形。我自己的做法是把规范写进仓库。
第一步是把.vscode/settings.json做成团队共享文件,把todo-tree.general.tags、customHighlight这些配置推进仓库。这样任何同事 clone 完代码,打开 VSCode 就会自动应用同一套颜色和图标,不需要每个人手动配一遍。
第二步是在仓库的CONTRIBUTING.md或者工程文档里写清楚语义要求。比如:
TODO: 未实现的功能,必须有明确描述FIXME: 已发现的缺陷,必须附带触发条件或复现步骤XXX: 高风险区域,改动前必须和模块负责人确认
这样做的好处是,注释不再只是“个人备忘录”,而是一种轻量级的团队沟通载体。
5.2 用 issue 编号挂接待办
我在待办注释里最常见的格式是:
// TODO(#142): 列表页加入筛选功能 // FIXME(#153): 移动端上传时偶现超时在注释中带上 issue 编号后,就能把待办树和项目里的任务管理工具串起来。你可以在 Todo Tree 的配置里给customHighlight配上link相关设置,或直接依赖 VSCode 的链接识别能力。当你看到侧边栏里的#142时,不管过多久都能顺着编号找回完整的任务背景。
如果是XXX这类高风险标记,我建议一定要在注释里写明“联系人”。比如XXX: 这里的缓存策略不建议改 / 联系 @A同学。这能避免未来某天有人无意中踩雷。
5.3 定期清理“僵尸 TODO”
每个项目跑久了都会出现“僵尸 TODO”:任务早就完成了,注释却一直留在代码里。这个问题靠插件本身解决不了,只能靠团队习惯。
我们现在的做法是:
- 代码评审时看到明显的过期 TODO,直接要求移除
- 每次迭代结束,花十分钟过一遍待办树,把已经解决的行删掉
- 凡是无法确认是否过期的,用搜索工具拉出来逐条核实
清理还有一个额外好处:让 Todo Tree 的待办树保持干净。如果一棵树上塞满了几百条过期注释,真正紧急的FIXME反而会被埋没,工具的参考价值就大打折扣。
6. 踩坑记录:Todo Tree 使用中绕不过去的几个细节
6.1 图标不显示,先从这四步查
我遇到过好几次“图标不见了”的情况,每次最后都能归到少数几个原因上。
第一步:确认gutterIcon是否开着。defaultHighlight或customHighlight里如果没写gutterIcon,默认可能不显示编辑器左侧的图标,只显示文字高亮。
第二步:确认主题有没有覆盖图标颜色。某些深色主题会把 gutter 图标压得很暗,看起来像没显示。可以给对应标记单独配iconColour,调成一个亮色。
第三步:确认图片路径是否正确。自定义图片路径写错时,插件会静默失败,侧边栏不报任何错误。这时把路径改成内置图标名,比如icon: "circle",看看是不是立即恢复。
第四步:重载窗口。如果以上都不行,就按 Ctrl+Shift+P 执行Developer: Reload Window。设置改了不重载,样式不刷新是最高频的误判。
6.2 扫描不到预期的注释:搜索范围在作怪
很多初学者会问“为什么我在某个文件里写了 TODO,待办树里却没有”。这时候要检查的是搜索范围。
Todo Tree 默认扫描整个工作区,但它会遵循 VSCode 的 files.exclude 规则,以及todo-tree.filtering.excludeGlobs里配置的目录。如果你的文件被node_modules或dist之类的规则排除掉了,待办树里自然看不到。
还有一种情况是注释写法不符合匹配规则。例如有些标记写在字符串模板里:
const message = "TODO: 处理用户未登录状态"这种字符串内容不一定会被识别为注释,取决于插件配置里是否勾选了字符串范围。如果确实需要扫描字符串里的标记,可以调整todo-tree.regex.regex或者相关配置项,但我不建议这么做,因为会带来大量误报。
6.3 大型仓库的性能优化
我曾在某个大型 monorepo 里把 Todo Tree 的扫描范围开得很宽,结果每次刷新都要转好几秒。后来做了几个优化,效果明显:
- 在
todo-tree.filtering.excludeGlobs中排除**/node_modules/**、**/dist/**、**/build/** - 在
todo-tree.filtering.includeGlobs中只保留源代码目录,比如**/src/** - 关闭不必要的图标渲染,只保留文本高亮
- 按需刷新,而不是每次保存文件都重建整棵树
如果想快速验证到底哪些目录拖慢了扫描,可以先把excludeGlobs配出来,再逐步放行,观察刷新时间的变化。
6.4 另外几个容易被忽略的细节
大小写问题最容易被忽略。默认情况下,Todo Tree 匹配是区分大小写的,也就是说todo不会被识别成TODO。如果你的团队里有同事习惯写小写todo:,就会漏扫。统一规定全部大写,或者在配置里调整大小写敏感性。
还有一个细节是标记边界的处理。如果注释写成TODOS:,有些版本会识别的很别扭。尽量避免在标记后面直接接复数后缀,或使用正则配置精确匹配单词边界。
最后,留意不同 VSCode 版本和 Todo Tree 版本之间的配置项差异。有些老教程里的todo-tree.tags路径,在新版本里可能已经变成了todo-tree.general.tags。看官方文档或者直接点开设置界面的 JSON 提示,比记忆配置路径更稳妥。
我在配好整套样式后最大的感受是:它不只是一个“显示 TODO 的工具”,更是让人敢在代码里留下清晰记录的安全网。以前我怕注释写得太乱没人看,现在知道所有标记都会被自动收集、染色、归类,反而更愿意把没做完的事老老实实标记出来。等哪天你突然要交接项目,或者要从一堆代码里找出真正需要立刻处理的FIXME,就会明白这样一个顺手的小工具能为日常开发省下多少力气。