题记:一款工具如果只是“装上了、能弹窗”,那它只是你众多扩展里的一条晾衣绳;如果它能让你在两分钟内定位到仓库里所有欠债现场,它才真正成为开发习惯的一部分。Todo Tree 就是后者。
1. 为什么我要专门写一篇 Todo Tree 的使用详解
先说个场景:你接手一个老项目,git clone 完事,打开 VS Code,一眼望去全是文件。这时候你脑子里最想知道的是什么?不是架构图,不是 README,而是——这个项目里到底还有哪些 TODO、FIXME、HACK 没有处理。这些散落在代码里的标记,才是项目真实的“未完成清单”。
Todo Tree 这个扩展干的事,就是把这些散落在几百个文件里的 TODO、FIXME、XXX 等特殊注释提取出来,统一放在侧边栏的一棵树里展示。它的价值不在于“找到注释”,而在于把“隐性的待办”变成“显性的目录树”,让你一眼看到整个项目的未完成工作全貌。配合自定义匹配规则、文件过滤、高亮标记,它基本就是一个轻量级的项目欠债管理系统。
我最初装上它只是因为看到别人博客里截图有个侧边栏能列 TODO,觉得很酷。真正用起来之后才发现,这东西的便利程度远超想象。所以这篇详解不打算写成官方 README 的中文翻译,而是把我从“装上”到“离不开”这个过程中,所有值得说的配置、技巧、坑,一次性整理出来。适合的人:刚接触 VS Code 的初学者、正在维护老项目的中级开发者、以及想优化团队代码注释规范的工程效率控。
2. 从安装到第一次看到待办树:五分钟上手
2.1 安装与入口位置
在 VS Code 扩展市场里直接搜 Todo Tree,认准作者栏为 Gruntfuggly 的那个,安装量目前相当高,基本不会认错。装完之后,侧边栏会多出一个树形视图图标,是一个带对勾的小树杈(视图标题就叫 TODO)。点击它,当前工作区里所有含 TODO、FIXME 的代码位置就按文件归类列出来了。
这里强调一个细节:Todo Tree 是按“工作区文件夹”扫描的,不是按当前打开的文件。如果你只打开了一个单文件(没有打开文件夹),侧边栏大概率是空的。所以正确姿势是 File -> Open Folder,把项目根目录扔给它。
2.2 第一次点击跳转
树里的每一项,点一下就能直接跳到对应代码行,这个跳转不是简单的文本搜索,而是基于 VS Code 的符号定位机制,所以即使文件被折叠、代码有缩进层级,跳转也准确无误。在树里点右键,还能在“在编辑器中打开”和“复制路径”之间选择,这些基础操作我后面会细说我实际怎么用它们。
2.3 默认配置能干什么
刚装好的默认状态,Todo Tree 已经在后台做了这几件事:
- 扫描所有支持语言的文件,找到
TODO、FIXME开头的注释行。 - 在编辑器里把这些关键词用特殊颜色高亮(默认是橙色底/黄色字那种,看主题)。
- 树里按文件路径分组展示,并附带行号和注释正文片段。
- 点击状态栏的待办计数,能快速开关视图。
这个默认能力已经能覆盖 60% 的使用需求。但真正让它变得好用的,是接下来的自定义。
3. 核心选项详解:正则、过滤、高亮,一条条说清楚
3.1 自定义标签:除了 TODO 还能搜什么
很多人不知道,Todo Tree 默认只匹配 TODO、FIXME,但你完全可以加自己的标签。打开设置,搜todo-tree.general.tags,默认是["TODO", "FIXME", "DONE"]。注意,这个数组不是“全局多关键词匹配”,而是“作者指定的标准标签集”。
我实际项目里常用的自定义标签是:
"todo-tree.general.tags": [ "TODO", "FIXME", "HACK", "BUG", "TEMP", "NOTE", "OPTIMIZE", "XXX", "CLEANUP" ]其中TEMP和CLEANUP是我特别加的。TEMP用来标记临时改动、调试代码,比如本地测试要改一个常量,上线前必须改回来;CLEANUP用来标记“这段代码能跑但很丑,有空重构”。把这些词加进 tags 之后,只要代码里出现// TEMP: ...或// CLEANUP: ...,Todo Tree 就能搜到。
3.2 highlights 定制:让关键词不止是“字面变色”
Todo Tree 还有一个独立的高亮模块todo-tree.highlights,它和树视图是分开配置的。如果要让高亮生效,需要显式开启:
"todo-tree.highlights.enabled": true默认情况下,高亮会把匹配到的整个注释行(从标签到行尾)都加上背景色。如果你只想给标签本身加颜色,而不想让一整行被涂得花花绿绿,可以配:
"todo-tree.highlights.foreground": "#ffffff", "todo-tree.highlights.background": "#e74c3c", "todo-tree.highlights.opacity": 50opacity控制的是背景色的透明度,数值越低越淡。我一般调成 30%-40%,既能一眼看到,又不掩盖代码本身。你要是装了 Material Theme 这类深色主题,这个透明度尤其好用,默认的深色高亮在深色背景上会糊成一片。
3.3 正则匹配:官方默认方案,不推荐瞎改
Todo Tree 本质上是用正则去匹配每一行注释的。它默认的正则是:
(TODO|FIXME):?\s*(.*)匹配规则里的分组很有讲究:第一组匹配标签名(TODO/FIXME),第二组匹配注释内容。如果你想自定义,比如想匹配“中文的待办”一词,可以在设置里加一条:
"todo-tree.general.regex": "(TODO|FIXME|待办|HACK|BUG|TEMP):?\\s*(.*)"但据我实测,改全局正则有风险:一是正则写错会导致树里什么都不显示,排查起来很痛苦;二是它会影响所有文件,某些语言的注释格式带星号、带引号,可能会匹配到一些莫名其妙的内容。所以我的建议是:标签数组能覆盖的需求,就不要再动正则。正则留给那些真正需要“带上下文匹配”,比如只匹配// TODO而不匹配# TODO的场景。
3.4 树视图分组方式:Files 还是 Tags
这是 Todo Tree 里直接影响使用习惯的一个选项:
"todo-tree.tree.groupBy": "file"默认是按文件分组,即每一个文件是一个父节点,文件里的多条 TODO 是子节点。这样适合“我要去这个文件处理它所有待办”的场景。还有一个按标签分组的模式:
"todo-tree.tree.groupBy": "tag"按标签分组适合“我现在只想清理所有的 FIXME,不管它在哪个文件”。我自己平时用按文件分组,但在每周代码审查日会临时切到按标签分组,专门集中看所有HACK。
3.5 文件过滤和排除:别让 node_modules 淹没真正的待办
这个是重点中的重点。默认情况下 Todo Tree 会扫描工作区里所有文件,包括node_modules、dist、build这些目录。一旦项目里依赖的某个第三方包源码里自带 TODO,你的树里就会出现几十条跟你毫无关系的待办,非常烦人。
正确的配置是把这些目录排除掉:
"todo-tree.filtering.excludeGlobs": [ "**/node_modules/**", "**/dist/**", "**/build/**", "**/out/**", "**/.git/**", "**/vendor/**", "**/coverage/**" ]excludeGlobs用的是 glob 通配符语法,**表示任意层级目录。这个配置在首次使用时就值得设置好,否则一段时间后树里塞满垃圾,你的第一反应就是“这插件好卡、好乱”,直接卸载了。
3.6 是否递归搜索 symlink(符号链接)
这个选项容易被忽略:“todo-tree.filtering.useBuiltInExcludes” 和 “todo-tree.filtering.includeHiddenFiles”。前者是把 VS Code 自带的一些文件排除规则(比如.git目录)一并应用过来,默认开启,建议保留。后者控制是否扫描隐藏文件,我碰到过一些人会把.env.example这种隐藏文件里写上TODO: 配置生产环境变量,如果关掉隐藏文件扫描,这条就没了。所以建议:
"todo-tree.filtering.includeHiddenFiles": true4. 在真实项目里的心流实践:从“看树”到“管理树”
4.1 把 Todo Tree 当作个人待办清单
我维护的几个项目里,TODO的实际含义被我限定成了三种:短期内要做的功能补全、性能优化点、代码重构点。为了区分,我会在标签后加冒号和空格,比如// TODO: 增加分页、// TODO: 优化循环,正则的第二个分组会自动把冒号后的内容当作显示文本。这样树里看起来非常整齐,扫一眼就能知道每件事是什么。
4.2 把 FIXME 当作 Bug 藏宝图
处理老项目时,我最先看的就是FIXME。这类标记通常意味着代码作者当时已经意识到有问题,只是暂时没时间修。它们往往是整个项目最值得优先排查的隐患。Todo Tree 的按标签分组模式在这里派上用场:把所有FIXME集中在一屏里,按文件排序,就能梳理出哪些模块的隐患最集中。
4.3 右键菜单:把待办变成真工单
树的每个节点右键菜单里,有几个我常用到的功能:
- “在编辑器打开”:不用解释。
- “复制”:把当前行的完整路径复制出来,比如
src/utils/date.ts:42,可以直接贴到 Git 提交信息或群聊里。 - “在文件管理器显示”:定位到资源管理器面板。
- “排除文件”:相当于临时给这个文件加一条 excludeGlobs,这个功能非常实用,碰到某个不想看的文件,右键一下,它就从树里消失了。
分享一个我的习惯:每天早上打开编辑器,第一件事不是看 Git 状态,而是打开 Todo Tree,看看待办数有没有比昨天少。这比任何项目管理工具都直观——因为代码里的 TODO 是开发者在写代码那一刻的真实意图,无比真实。
4.4 状态栏计数:一个数字带来的心理压力
Todo Tree 默认会在状态栏显示一个数字(总待办数)。这个数字对我来说更像一个“技术债指数”。数字越大,说明项目里攒的未完成工作越多。我给自己定过一个非正式规范:新写的代码里不允许新增TODO,已有的TODO每周至少清掉三个。代码评审时如果候选人代码里有一个大模块全是TODO,我基本会要求他至少把阻塞上线的部分改成FIXME或当场修掉——这也是用工具反向规范团队习惯的一个小技巧。
5. 实测中的意外情况和坑,每个都是真金白银
5.1 项目里的 node_modules 扫描导致卡顿
我之前在一个中型前端项目里,装完 Todo Tree 后侧边栏树要转两三秒才出来,一度以为插件有问题。排查后发现罪魁祸首是nodemodules下某个依赖包源码里带了几百条 TODO 注释。把这些目录加入excludeGlobs之后,树秒开。如果你用的 monorepo(比如 pnpm workspaces),注意node_modules可能散落在多个子包里,glob 写法要写成:
"todo-tree.filtering.excludeGlobs": [ "**/node_modules/**", "**/.turbo/**", "**/dist/**" ]**/node_modules/**能匹配任意层级下的 node_modules,放心用。
5.2 某些场景下出现垃圾的“奇怪”匹配
有一次我在一个 Vue 项目里,发现 Todo Tree 把# TODO这种 CSS 注释、还有<!-- TODO -->这种 HTML 注释外的属性内容也列出来了。看了下是因为当时代码里有句// TODO: 处理 input 的 placeholder,而模板里恰好有个:placeholder="'TODO: 输入内容'",正则把TODO:后面的字面量当成了注释内容。这个不算插件 bug,而是正则的固有缺陷。规避方式是尽量用代码注释写 TODO,而不是写在字符串里,或者在正则的第二个分组限制一些字符。
5.3 高亮和主题冲突,颜色糊成一团
默认高亮在浅色主题下还算清楚,在深色主题下有时会“隐身”。如果你用的主题对注释色做了自定义,Todo Tree 的高亮可能会和主题的注释颜色叠加,导致对比度很低。解决办法是手动指定foreground和background,并配合opacity调整透明度。我目前用的是:
"todo-tree.highlights.foreground": "#f8f8f2", "todo-tree.highlights.background": "#ff5555", "todo-tree.highlights.opacity": 40这个在 Dracula 主题下看起来特别舒服。
5.4 Git 仓库根目录和工作区根目录不一致时
如果你的 VS Code 打开的是仓库的子目录(比如code/而不是整个仓库根),Todo Tree 只会扫描当前打开的那个文件夹。这就可能导致一个问题:你在src/子目录下写的一条 TODO,如果不小心用了相对路径跳转到上一层目录(比如../../other/foo.js),Todo Tree 默认是跟着工作区根走的,扫描不到工作区外的文件。解决办法要么是打开完整仓库根目录,要么用 VS Code 的 multi-root workspace,把多个相关目录加进一个工作区。这个多根工作区功能配合 Todo Tree 还不错:树里会以根目录为顶层分组,互不干扰。
5.5 作者 Gruntfuggly 的捐款提醒
这个必须单独提一下。Todo Tree 虽然本身是免费扩展,但它的作者 Gruntfuggly 在扩展说明里放了一个比较知名的非传统请求——希望你用区块链代币“AR”给他捐款。社区对这个行为有过一些争议,但对功能本身没有影响。如果你在公司内网环境或对加密代币相关的东西比较敏感,看到那一段说明不用困惑,忽略即可,插件照常使用。这也算这个扩展的“梗文化”之一了。
6. 进阶玩法:结合文件监视和正则,把 Todo Tree 变成团队的“欠债看板”
6.1 让扫描结果跟随文件变化实时刷新
Todo Tree 默认是自动监听文件变化的。你新建一条 TODO,树里几乎同步就出现。不过如果你用了一些代码生成器(比如自动生成 mock 文件)或者脚本批量修改代码,可能会导致扫描结果暂时不刷新。这时候可以在命令面板(Ctrl+Shift+P)输入Todo Tree: Refresh,手动刷新。我做 CI 检查时一般会配合这个命令,确保提交前待办树是最新状态。
6.2 结合工作区文件的sortTags和sortTree
当待办多了以后,排序方式直接影响浏览效率。设置里有两个排序相关的选项:
todo-tree.sort.onlyTopLevel: 设为true时,只对一级节点排序,子节点按原文位置排。todo-tree.tree.showCounts: 在标签或文件后面显示计数,比如Foo.ts (4),这个数字一眼能看出哪个文件是“欠债大户”。
我在审查代码时会开showCounts,快速定位到待办最多的文件,优先安排重构。
6.3 正则组的巧妙用法:标记紧急程度
刚才提到默认正则的分组是标签 + 内容。其实你可以在“内容”部分再加标记,实现紧急程度的视觉区分。比如在代码里写:
// TODO [high]: 修复登录状态过期问题 // TODO [low]: 优化某个样式你可以把正则改成:
"todo-tree.general.regex": "(TODO|FIXME|HACK|BUG|TEMP):?\\s*(\\[(high|medium|low)\\])?\\s*(.*)"Todo Tree 会把带优先级标记的待办单独显示[high]前缀,虽然它不会自动排序优先级,但这已经足够你在视觉上区分紧急事项。不过还是那句话:能不折腾正则就别折腾,简单项目用标签数组最稳。
6.4 对比一下同类工具(个人感受)
| 特性 | Todo Tree | Todo+ | Todo Highlight |
|---|---|---|---|
| 树形视图 | 有,且强大 | 有,稍弱 | 无 |
| 自定义标签 | 强,数组+正则 | 中 | 弱 |
| 高亮定制 | 强 | 中 | 强 |
| 文件排除 | 强 | 中 | 弱 |
| 维护活跃度 | 较高 | 一般 | 一般 |
如果只看 TODO 管理,Todo Tree 基本是这个生态位上的首选。Todo+ 的 UI 有些场景更漂亮,但它对排除目录的支持明显没 Todo Tree 灵活;Todo Highlight 更适合只想给注释上色、没有树形视图需求的人。我个人选型考虑里,Todo Tree 赢在“又能看树又能高亮、还能加自己的标签”,一个插件打满全场。
6.5 与 Git 提交记录的配合
我自己有一个小习惯:在准备 commit 之前,先看一眼 Todo Tree,如果树里的待办数比上次 commit 前多了,说明本次迭代引入了新的待办,我会在 commit message 里顺手注明这些待办是“有意为之的临时项”还是“必须下一轮处理”。这对于团队协作非常有帮助——不然队友看到代码里多了个 TODO,还得猜你是忘了还是故意留的。配上 Todo Tree 的视图截图发到 PR 描述里,reviewer 一眼就能知道遗留事项,比在描述里写三行字更直观。
7. 一份可直接粘贴的完整配置
最后把我目前正在用的完整配置贴出来,方便你直接抄。我的使用场景是:中大型 TypeScript/Vue 项目,深色主题,注重“树视图分组 + 高亮不刺眼 + 排除生成目录”。
{ "todo-tree.general.tags": [ "TODO", "FIXME", "HACK", "BUG", "TEMP", "NOTE", "OPTIMIZE", "XXX", "CLEANUP" ], "todo-tree.general.regex": "(TODO|FIXME|HACK|BUG|TEMP|NOTE|OPTIMIZE|XXX|CLEANUP):?\\s*(.*)", "todo-tree.highlights.enabled": true, "todo-tree.highlights.foreground": "#f8f8f2", "todo-tree.highlights.background": "#ff5555", "todo-tree.highlights.opacity": 40, "todo-tree.filtering.excludeGlobs": [ "**/node_modules/**", "**/dist/**", "**/build/**", "**/out/**", "**/.git/**", "**/vendor/**", "**/coverage/**", "**/.turbo/**" ], "todo-tree.filtering.includeHiddenFiles": true, "todo-tree.filtering.useBuiltInExcludes": true, "todo-tree.tree.groupBy": "file", "todo-tree.tree.showCounts": true, "todo-tree.sort.onlyTopLevel": true }说一下几个选型理由:
regex和tags尽量保持一致,避免“标签数组里有但正则不认”的诡异情况。opacity设为 40 是深色主题下的稳妥值,如果浅色主题可以调到 60。showCounts在待办很多时会有点“压力大”,但它确实让我更清楚项目里哪个目录最烂。- 如果你的项目没有前端构建目录,
dist、build的 exclude 可以去掉,不影响性能。
8. 其他容易被忽略的细节和我的最终建议
8.1 它不会帮你写代码,但会帮你“看见”代码里的债
这是我对 Todo Tree 的最终定位。它不是自动化重构工具,也不是项目管理软件,它做的事情非常朴素——帮你把你和同事留在代码缝隙里的“未完成”全部捞出来,排成一排。但就是这个“看见”,能改变一个人对项目质量的感知。用了它之后,我写 TODO 之前会多犹豫几秒,想着“这个能不能现在就做掉”;我 review 代码时也会更敏锐地追着 TODO 问一句“这里为什么先留着”。这种微小的行为改变,比插件本身的价值更值钱。
8.2 一定要记得:树是给“人”看的,不是给“CI”看的
别指望 Todo Tree 能自动阻止代码里有 TODO,它只是把问题暴露出来。如果团队想强制“合并前不允许新增 FIXME”,那得靠 ESLint 插件或 CI 脚本扫描,Todo Tree 不是这个用途。但如果你能在本地开发阶段就看见、处理、清理掉大部分标记,CI 那条检查规则大概率永远用不上——因为大家已经养成了随写随清的习惯。
8.3 最后分享一个小技巧
很多人不知道 Todo Tree 的状态栏计数里,点击它可以直接展开/收拢侧边栏的树视图。这个入口比手动点击图标更快。另外,在树视图顶部的三个小图标里,暂停扫描那个按钮容易误触,我就不小心点过一次,当时以为插件坏了,树全空了,研究了好一会儿才发现只是暂停了自动刷新,点一下恢复就好。你要是也遇到“树突然空了”的情况,先别卸载,看看是不是误触了那个暂停按钮。