首页 / 资讯中心 / 文章详情

基于AST的代码结构分析工具t3code:快速扫描项目依赖与函数清单

基于AST的代码结构分析工具t3code:快速扫描项目依赖与函数清单 ★ FEATURED ARTICLE
先聊个具体的场景你刚接手一个别人写了三年的后端仓库package.json 里躺着几十个依赖src 目录下嵌套了七八层文件夹你只知道这个系统“大概”是做什么的但完全不知道核心模块有哪些、模块之间怎么调用、哪些函数是公开 API、哪块代码能拆掉重构。这时候如果有个工具能在十几秒内把整个项目的代码结构、依赖关系、函数清单和文档草稿全部扫出来你会不会觉得捡到宝了这就是我为什么花了几周时间折腾 t3code 的原因——一个基于 AST 的终端代码结构分析工具专门用来回答“这个项目的代码到底长什么样”这种看似简单、实际却很麻烦的问题。t3code 这个名字里的 t3不是 T3 Stack 那个 t3而是三个维度的缩写Type类型即结构、Tree树即依赖、Text文本即检索。工具本身没有任何 AI 魔法就是一个老老实实的静态扫描器用 Node.js 写的跑在终端里识别 TypeScript 和 JavaScript 项目的代码结构输出结构树、依赖关系、函数清单还能顺手生成一份 README 文档草稿。对于刚接手历史项目的程序员、准备做重构的技术负责人、想给开源仓库补齐文档的维护者来说这个工具属于“用过一次就回不去”的类型。我自己就是在一次临时救火中手写了几个脚本分析老项目感觉不过瘾索性把脚本沉淀成了一个正经工具于是就有了 t3code。下面从设计思路、技术内核、实操流程、踩坑记录到后续规划完整拆解一遍。如果你正打算给自己的项目做类似的东西或者单纯想找个体面的代码结构分析方案这篇应该能帮到你。1. 先说清楚t3code 到底是个什么东西1.1 为什么是“t3”这个命名很多工具喜欢给自己的名字带上华丽的技术字眼但 t3code 的命名逻辑极其朴素我要在终端里完成对代码的三层理解。第一层是 Type也就是类型和结构。一个函数是 export 的还是私有一个类是抽象类还是普通类接口里定义了哪些成员常规的 grep 和 ripgrep 只能告诉你“这里有一个 foo 函数”但告诉你“foo 是公开 API参数是两个对象返回值是个 Promise”这种信息的必须是能解析语法树的东西。第二层是 Tree也就是目录和依赖树。项目里一共有哪些文件main 模块依赖了哪些子模块有没有循环引用我把这些信息组织成一棵依赖树让你一眼看明白模块之间的上下级关系。这种信息在做模块拆分的时候尤其有用——那些被根节点大量依赖的文件往往是整个系统的核心枢纽。第三层是 Text也就是全文检索与信息抽取。代码里有没有 TODO所有的 API 注册入口分散在哪些文件某个函数在哪些地方被引用过基于 AST 的引用分析比 CtrlF 精确得多因为它理解作用域不会把同名不同作用的变量混为一谈。工具的最终形态就是一个终端命令。没有 GUI没有 Web 管理面板没有常驻后台服务。装完就用用完就走。这是我一开始就定下的原则开发者的日常工作是围绕终端展开的t3code 就应该老实待在终端里。1.2 现有工具解决不了的痛点你可能觉得这活儿用现成工具也能干比如 ctags比如 ESLint 的代码规则比如 IDE 内置的结构化视图。确实能干但都有点隔靴搔痒。ctags 是古老而可靠的符号检索工具但它只会告诉你“某个符号在哪个文件哪一行”然后就没有然后了。标签之间的调用关系、导出范围、依赖网络它一概不管它就是一把特别锋利的刀没错可你需要的是一整套厨房设备。ESLint 做的是规则检查它当然能解析 AST但它的输出是为规则检查服务的。你想让它列出某个模块对外暴露的全部函数签名不好意思这不在它的工作范围内。IDE 内置结构视图通常很好用比如 IDEA 的 Structure 面板、VS Code 的资源管理器大纲。但问题有两个一个是 IDE 需要打开项目并完成索引历史仓库动辄几万行代码等你打开等它索引完可能已经不想看了另一个是 IDE 的结构视图不能批量导出、不能跑进 CI、不能自动生成文档。t3code 的价值就在于它把这些能力全部下沉到命令行用一条命令代替点击十几次鼠标。另外一个常被人忽略的点是t3code 是面向“整个项目”而不是“单个文件”的。传统工具都是单文件维度而现代项目的复杂度恰恰体现在跨文件关系上。某个工具函数被 20 个文件引用这种全局视角只有站在项目级扫描的前提下才能建立起来。1.3 目标用户和使用场景我在设计阶段就给 t3code 圈定了三类用户这让后面的功能取舍变得非常轻松。第一类是新接手的程序员。刚开始看老项目时最怕的就是一头扎进细节里拨开一层又一层最后迷失在代码的海洋里。用 t3code 先扫一遍全貌再顺着依赖树逐层下钻学习路径就自然脱出来了核心模块 → 依赖模块 → 叶子模块。第二类是准备做架构调整的技术负责人。重构最需要的是信息和胆量。信息来自对现状的理解——不要只凭脑补去判断代码边界让工具告诉你边界在哪里。t3code 输出的依赖图谱能直接暴露那些“隐藏的核心节点”和“混乱的循环依赖”这些信息比任何架构评审都更客观。第三类是开源项目维护者。他们通常很头疼 README 里的技术架构部分怎么写——因为 README 是给人看的但你可能已经忘了代码的细节。t3code 的 doc 命令能自动生成一个文档草稿把模块清单、关键函数列表全部列出来。你只需要在这个草稿基础上补充业务语义描述文档工作就完成了 60%。2. 技术选型背后的那点私心2.1 为什么是 Node.js TypeScriptt3code 本身是分析 TypeScript 项目的用 TypeScript 来写它属于顺手为之。但更重要的原因是生态Babel 的解析器、TypeScript 的编译器 API、Recast 的代码打印器这个组合在 JS/TS 工具链领域成熟到不行绕开就是给自己增加复杂度。如果用 Go 或 Rust性能和二进制分发确实更香但那是后话。t3code 的核心工作时长也就是十几秒Node.js 完全扛得住。与其纠结性能不如优先把解析正确性和开发体验做好。用 npx 直接跑也是 Node 生态的天然便利对于开发者用户来说npx t3code 比下载二进制安装包流畅自然得多。依赖选择上我极其克制核心依赖只有几个commander命令行参数解析babel/parser babel/traverseJS/TS 的语法解析与遍历recastAST 的还原打印用于提取函数体等场景chokidar 的可选关联用于 watch 模式的增量监听这个严格来说是 devDependencies 场景没有引入大型框架没有引入 ORM没有引入配置中心。每多一个依赖就多一个出问题的地方。工具本身就是做“结构分析”的自己的结构必须干净。2.2 用 Babel 而不是正则或 ctags这里是我最想展开讲的一个技术决策为什么必须用真正的语法解析器而不是正则表达式或者 ctags 之类的符号索引工具。正则擅长处理的是“形状规整的文本”而代码恰恰是“形状规整但语义复杂”的东西。用正则匹配 function foo() 确实能匹配到函数声明但匹配不到以下几种情况函数声明被注释掉但字符串里存在导出名称是动态计算出来的同样的函数名出现在不同作用域里异步生成器函数、装饰器函数这种加了修饰符的声明。正则的边界天然就不适合做这种事强上正则就是给自己埋雷。Babel 的做法是把你写的代码拆成 AST抽象语法树每一个函数声明、变量定义、导入导出语句都会变成树上的一个节点。在 AST 层面判断“这是一个导出函数”不再依赖文本匹配而是直接读取节点类型的属性。比如 ExportNamedDeclaration 节点下面挂着一个 FunctionDeclaration那么这个函数就是命名导出的没有任何歧义。AST 还有一个隐藏优势支持块级结构与作用域分析。我可以直接通过 Scope 对象查到某个变量的作用域边界可以判断一个标识符引用跳转到的是哪个声明节点。引用计数、依赖追踪这些都是基于这种跳转关系计算出来的。ctags 只是建立了“名称→位置”的索引而 AST 是建立了“语法单元→关系网络”的全量模型。这两者在信息量上是质变不是量变。2.3 整体架构与数据流t3code 的数据流设计很直白一共四步像一个浓缩的数据管道第一步是文件收集。通过 glob 匹配源码目录下的 .ts、.tsx、.js、.jsx 文件按照 .gitignore 规则过滤掉 node_modules、dist、build 等目录。这里有个细节值得说直接忽略 node_modules 是基线要求但要小心项目里的某些文件会引用 node_modules 里的类型定义所以类型信息补全用的是 TypeScript 编译器 API 而不是 Babel原因后面会展开。第二步是语法解析。每个文件交给 babel/parser 解析成 AST解析失败的文件会被记录下来不影响整体流程继续跑。容错设计在这里至关重要一个大项目里总有一两个文件是语法不标准的或者内嵌了特殊模板因为一个文件崩溃整个工具是不可接受的。第三步是信息抽取。遍历 AST提取文件名、行号范围、导出符号、类型签名、依赖模块、注释里的 JSDoc/TSDoc 标记。这个阶段的数据就非常结构化全部存成 JSON。第四步是输出。根据命令参数选择格式化方式终端树状图、JSON 数据包、Markdown 文档、或者简单的纯文本列表。输出层和抽取层分开是后期扩展的底气所在。如果你要在 t3code 基础上做二次开发关注的就是第三步的信息抽取模块和第四步的输出格式模块。这两块是插件化的关键位置。3. 从零跑通 t3code核心命令实操3.1 安装与初始化项目安装非常简单因为就是 npm 生态的标准姿势npm install -g t3code如果你不想全局安装也可以直接用 npxnpx t3code --version首次运行时会检查当前目录是否包含 package.json如果没有会提示你初始化一个配置文件。这个配置文件叫 t3code.config.json放在项目根目录即可。下面是我的一个真实项目中的配置片段拿来自查自用正好{ root: src, include: [**/*.ts, **/*.tsx], exclude: [**/*.d.ts, **/__tests__/**], entryPoints: [src/index.ts, src/main.ts], outputDir: .t3code, maxDepth: 4, ignorePatterns: [*.generated.ts] }几个字段的用意我挨个说一下root 是扫描根目录默认是项目根目录但一般建议指到 src因为依赖和测试文件往往会污染分析结果。include 和 exclude 是文件匹配规则遵循常见 glob 的写法。entryPoints 是入口模块列表在绘制依赖树时入口会出现在最顶层。outputDir 是输出目录默认 .t3code 隐藏文件夹避免污染仓库。maxDepth 是树形展示的最大深度防止那种动辄七八层的嵌套把终端刷屏。ignorePatterns 用来跳过自动生成的代码比如 graphql 生成的 types、API client 的自动生成模板这类文件对结构分析没有帮助。3.2 扫描与树状输出先跑一条最基础的扫描命令看全貌t3code scan命令运行后会在终端打印出项目结构树每一行代表一个模块或一个文件缩进表示层级。输出示例src/ ├── index.ts exports: createApp, startServer ├── config/ │ ├── env.ts exports: loadEnv, EnvConfig │ └── logger.ts exports: createLogger ├── core/ │ ├── app.ts exports: createApp │ ├── router.ts exports: registerRoutes │ └── errors.ts exports: AppError, ErrorType └── services/ ├── auth.service.ts exports: login, logout, refreshToken ├── user.service.ts exports: createUser, getUser, updateUser └── db.ts exports: connectDB, getConnection在文件后面直接列出导出符号是为了解决“看到文件名还要 grep 一把才能确认这个文件干吗”的麻烦。你扫完一遍结构心里基本就有了一张地图。如果你只关心某个子模块可以加路径过滤t3code scan --filter services这个命令只会扫描 src/services 目录下面的内容。配合 --depth 参数能进一步控制展示深度比如只看前两层t3code scan --depth 2在实际现场使用中我最常用的反而是一条组合命令t3code scan --format tree --min-exports 3加了 --min-exports 之后只有导出符号数量大于等于 3 的文件才会出现在输出里。这可以快速过滤掉那些只有一个导出的小文件把注意力集中在核心模块上非常适合用来做架构层级的概览。3.3 按需查询与文档导出scan 是全局视角query 则是定点深挖。比如你想知道某个函数在哪里被引用过t3code query --symbol createApp --refs命令会列出所有引用了 createApp 的文件清单以及每个引用位置的行号。这是基于 AST 作用域分析得到的不会把注释里的单词算进去。如果想看某个模块对外暴露的完整 API 列表可以用 export 子命令t3code export --file src/services/auth.service.ts输出的是一组 Markdown 表格列出每个导出函数的名称、签名、参数类型、返回值类型、JSDoc 注释摘要。这个功能在写接口文档的时候几乎就是救命稻草——你不需要从头读业务代码来理解接口语义只需在注释里补一句人话文档质量就直接到位。导出文档的命令是全套里最有效的t3code doc --format markdown --output README.code.md它会把扫描结果、模块清单、关键函数签名组合成一份完整的代码结构文档。我一般生成的文档加上项目标题、一段业务简介就直接可用了。不过有一点必须提醒一下它生成的是“代码结构文档”不是“业务说明文档”。代码能给你的信息它都能整理出来代码里没写清楚的信息它也变不出来。业务愿景、设计权衡这种内容还是得你自己补。3.4 配置文件与常用参数t3code 的配置设计遵循“零配置可用有配置更强”的原则。默认配置对大多数中小项目已经够用但真实项目总有些怪癖所以配置能力必须铺到位。在配置文件之外优先级最高的是命令行参数。比如配置里写了 exclude**/__tests__/**你在代码评审时突然想看看测试文件的结构可以直接在命令行里临时覆盖t3code scan --no-exclude-tests优先级从上到下依次是命令行参数 项目配置文件 默认配置。这个规则在几乎所有 CLI 工具里都是通行的遵循起来别别扭扭设计就是了不用想太多。还有一个参数容易被忽略但是建议任何第一次跑 t3code 的人都先用一次t3code scan --dry-run这个模式下不解析 AST只输出文件收集清单。先确认扫描范围符合预期再正式跑全量解析可以避免“花了半天解析了一堆不该解析的东西”的尴尬。4. 深入到原理层AST、依赖与缓存是怎么打通的4.1 AST 提取的边界与动作前文提到了 AST这里展开讲一下实战中的细节。Babel 解析出的 AST 节点类型非常多File、Program、ImportDeclaration、FunctionDeclaration、VariableDeclaration、ClassDeclaration、ExportNamedDeclaration……如果你是第一次做 AST 工具面对这么庞杂的节点类型肯定会发懵。我的办法是只抽取自己关心的几类节点其余的一律忽略。t3code 内部定义了一个剪裁后的“语义节点”模型把原始 AST 映射成以下结构{ file: src/core/app.ts, symbols: [ { name: createApp, type: function, params: [], returnType: Server, exported: true, startLine: 18, endLine: 42, doc: 创建并返回 HTTP 服务实例 } ], imports: [ { source: ./router, specifiers: [registerRoutes] } ] }把复杂的 AST 转换成这种扁平语义结构是 t3code 整个分析流程的核心环节。后续的依赖分析、文档生成、引用追踪全都基于这种扁平结构跟 Babel 的 AST 模型解耦让工具更容易扩展支持其他语言。如果未来要支持 Python 或者 Go只需要新增一个“解析器适配层”把不同语言的语法树映射到同一套语义模型上即可。这里有个关键取舍提取符号时要不要提取函数体内容我的答案是默认不要。函数体是执行逻辑对于结构分析而言是噪音你关心的是签名、边界、相互关系而不是它的内部实现。扫描一个 5000 行的核心服务文件时直接把函数体内容撇开速度和噪声都能优化很多。4.2 依赖分析与循环引用检测依赖分析是 t3code 最实用的能力之一。它的实现基于对 ImportDeclaration 节点的收集遍历每个文件的 import 语句把模块路径标准化后映射到具体文件然后建立一张“文件→文件”的依赖邻接表。为了处理路径别名比如 /core/config 映射到 src/core/config.ts配置文件里专门加了 alias 字段{ alias: { : ./src, core: ./src/core } }这样做有两个直接收益一是依赖图更准确二是引用追踪能跨过别名完成跳转。如果你项目里用了 tsconfig 的 paths其实可以直接读取 tsconfig.json 来解析别名t3code 也支持了这种模式省掉一份手工映射的配置。循环依赖的检测走的是深度优先遍历算法每访问一个节点就标记当前路径如果在递归过程中重新遇到路径里已存在的节点说明出现了环。检测完成会输出一条链式提示比如Detected circular dependency: src/core/app.ts → src/services/auth.service.ts → src/services/user.service.ts → src/core/app.ts坦率说绝大多数循环依赖并不至于导致运行时崩溃现代打包器大多能处理但它会让代码的认知负担直线上升你没法单靠读代码判断一个模块的初始化顺序也没法单独提取模块做测试因为一测试就把整个环都拉进来了。t3code 的循环检测在某些团队里已经进化成了一种防守机制在 CI 里挂一个 t3code depcheck --strict 步骤一旦新代码引入环就阻断合并这个玩法我认为比人工评审循环依赖靠谱得多。4.3 增量缓存让二次扫描变快项目第一次全量扫描可能耗时 3~5 秒第二次再跑如果还要这么久体验就有点差了。所以 t3code 内置了增量缓存机制做法如下在 .t3code/cache 目录下为每个扫描过的文件保存一份哈希值文件与解析结果。文件未修改时直接用缓存结果只有文件内容发生变化或新增文件时才重新解析。因为这个 RSS 驱动的机制第二次扫描通常会提速 5~10 倍。这里有个和 git 相关的细节问题要不要把 .t3code 目录加入 .gitignore我的答案是看场景。如果是团队共享模式缓存目录不要入库因为每台机器的路径、依赖版本都不一样缓存的意义不大还容易引发 diff 噪点如果你是做持续集成建议在 CI 里配置一个专门的 cache 目录这样每次构建时缓存还能复用。还有一种埋点思路是把缓存模式和环境变量剥离本地全量扫描CI 只用 --no-cache 强制新鲜。这种策略能保证 CI 拿到的永远是最新状态拖稿几天再跑出来的缓存包根本不可信。提示t3code 的缓存设计不是为了替代全量扫描而是为了辅助开发者的迭代节奏。做长期分析的场景如依赖监控里还是建议定期做一次全量扫描避免因为缓存策略错误导致分析结果长期滞后。5. 真实踩坑记录这些问题你一定也会遇到5.1 扫描时间爆炸文件太多怎么办第一次在真实项目上跑 t3code 的时候我遇到的第一个事故就是扫描时间爆炸。那个项目大概有 1000 多个源文件加上 node_modules 里一堆类型声明全量解析花了快一分钟。虽然不至于不能用吧但对于一个主打“快速扫一眼”的工具一分钟已经算慢了。排查思路是这样的先确认是不是文件收集阶段出了问题——看了 --dry-run 的输出才发现glob 正则把 node_modules 里一些深层嵌套的目录也给收进来了。我的 .gitignore 过滤规则写得过于宽松把排除逻辑做反了。修复规则后文件数量从 2700 骤降到 900 不到耗时随之降到 5 秒左右。如果你的项目文件量更大单仓超过 5000 个源文件建议做两件事第一是给扫描命令加 --exclude-vendor 这类后缀过滤规则明确排除第三方代码第二是考虑把周期性的全量扫描交给 CI 跑本地开发流程全部使用增量缓存模式这样体验就能完全拉开。5.2 结果乱码与编码问题有一次我在一台服务器上跑 t3code输出里的中文注释全部变成了乱码。原因特别基础文件本身的编码是 GBK而工具没有显式指定 UTF-8 解码。Node.js 的 fs 模块默认按 UTF-8 读文件遇到 GBK 编码的字节流就会按替换字符处理结果自然就花了。修复方案分两层。第一层是在配置里显式声明文件编码第二层是提供编码探测机制优先根据文件开头的 BOM 判断其次再根据配置文件指定。如果你接手的是老一代编码混排的项目强烈建议先跑一次批量编码转换把项目统一到 UTF-8 再做结构分析不要让工具替你做编码转码这件事工具的角色应该是正常分析而不是隐式转换。5.3 Windows 路径和符号链接Windows 上用 t3code 有个容易踩的隐形坑路径分隔符和大小写敏感性问题。node_modules 目录结构复杂符号链接junction在 Windows 上随处可见如果用不成熟的过滤逻辑很容易因为循环符号链接导致扫描死循环。我的处理方式是在文件收集阶段就统一转换为 POSIX 风格路径把反斜杠转成正斜杠并且在 glob 匹配时对 Windows 路径做大小写不敏感处理。另外一个更实用的经验是在 Windows 上如果项目本体放在路径很长的深目录下比如 D:\projects\myapp-frontend\目录建议先测一下路径长度确保 file_path 文件名总长不超过 260 字符——这个限制在 Node 的 fs 模块里极容易触到而很多人根本没意识到。5.4 解析失败的兜底方案再稳的解析器也挡不住历史项目里的奇葩文件。有些文件因为年份久远包含 Babel 的新语法都不认识的老代码有些文件则是模板生成器产出的半成品代码语法本身就残缺不全。t3code 的兜底策略是这样的解析失败的单个文件会被记录到 .t3code/errors.json同时跳过该文件继续跑完整个项目。在最后的汇总报告里除了结构分析结果还会给出一个错误文件清单。这样用户不会因为几个坏文件丢掉整份报告也知道还有哪些文件是待修复的。至于是不是要用 TypeScript 编译器 API 来兜底解析这些坏文件我试过但放弃了。TypeScript 的解析器容错能力确实更强但它输出的 AST 属性模型和 Babel 不兼容两套解析器的语义字段对不上强行兼容后整个数据模型会被迫让步维护成本立刻上去。与其追求百分之百的覆盖率不如老老实实保留错误清单让用户自己去处理有问题的文件。5.5 常见问题速查表这里整理一份实际使用中高频出现的问题小结可直接对照排查症状原因解决方式扫描目标比预期多很多glob 规则过宽包进了依赖目录核对 include/exclude用 --dry-run 先确认范围中文注释乱码文件编码非 UTF-8批量转换编码或在配置中显式声明编码Windows 下偶发崩溃路径过长或符号链接循环统一使用正斜杠路径增加路径长度检查二次扫描没有变快缓存配置不对或文件被修改检查 .t3code/cache 目录权限尽量保持输出文件目录稳定有的文件不进结果解析失败被跳过查看 .t3code/errors.json先修复那些文件的语法问题依赖分析有缺失路径别名未解析成功在配置或 tsconfig.json 里正确配置 alias循环依赖提示过多控制器的内部依赖环用 --ignore-circular 定向过滤已知环但别默认关闭检测6. 还能往哪走扩展方向与我的个人心得6.1 插件化迟早要做的架构预留t3code 目前的输出格式比较固定但从结构上我已经预留了插件机制。插件按两个维度扩展一是新提取器比如从 Vue 组件里提取自定义指令、从 Prisma schema 里提取数据模型这类信息都能并入结构分析二是新输出器比如导出 PlantUML 类图文本、生成 C4 模型描述或者输出成 JSON 给自定义脚本二次加工。如果你关注的是如何避免把自己长期锁死在现有实现上——插件接口需要在关键时刻做性能妥协插件接口本身要尽量薄不要设计成什么都提供的万能插件。观察开发者的真实需求看大家反馈最多的是哪类插件然后把官方插件做好才是正循环。6.2 与 IDE 和 CI 的联动t3code 的终点不是终端而是整个开发工作流。往 IDE 方向上最顺手的是把 t3code 的输出注入到编辑器的问题面板里。VS Code 的任务 API 完全可以直接调用 t3code 的 scan 命令把解析错误、循环依赖、冲突点以问题表格的形式呈现出来。这比做一个完整的 IDE 插件成本低得多但体验提升是立竿见影的。你甚至不需要离开编辑器就能看到当前项目的最新结构全貌。往 CI 方向上我强烈建议在每次合并请求里加一道结构分析检查。代码合并时最容易漏掉的就是隐性依赖新增一个 import 就可能导致循环依赖重构时改了一个 export 就会影响下游几十个文件。维护一份结构快照让 CI 对比分支之间的差异在评审阶段就警告“本次改动新增了一个循环依赖”这种机制比口头约定管用太多了。如果你不想搭复杂的 CI 链路可以直接用 t3code 的 JSON 输出配合 jq 写一个简单的检查脚本三五十行就能搞定效果也不差。这类工具的终极正确性是给自动化流程用的不要让它孤零零死在终端里。6.3 我个人最满意的一个小设计最后聊点偏心意的东西t3code 最让我骄傲的不是 AST 解析也不是依赖图谱而是一个小到几乎没人注意的细节——错误文件列表。很多工具遇到解析失败就直接跳过或者直接报错退出。但 t3code 会把所有失败文件写进 errors.json并在汇总报告里给出明确的位置。别小看这个行为——在真实项目里那些语法不标准的“坏文件”往往是最需要重构的痕迹。它们可能是历史包袱的坟场可能是临时补丁留下的垃圾。一套工具如果能把它们的名单自动列出来就已经帮工程师省掉了一大笔人工排查的时间。我当时问自己一个问题t3code 的使命是什么不是分析代码本身而是降低理解项目的成本。错误文件列表本质上降低了“发现坏代码”的成本。从这之后我得到一个做工具的核心心法少做那些看起来厉害的复杂逻辑多想想那些真正减少用户痛感的简单动作。如果你也想做类似的代码分析工具我给三条建议第一先守住最小的使用链路宁可用一条命令跑完整流程也别把功能拆得七零八碎第二输出结果一定要支持 JSON因为自动化的想象空间全在那扇门后面第三多去真实项目上跑你会发现在示例项目里根本遇不到的那些边界情况才是工具真正值钱的地方。
阅读完成 · 觉得有帮助?
咨询建站