audit-dead-code
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAudit Dead Code
死代码审计
Audit reachability before deleting anything. Build a proof chain from live entrypoint to candidate, then apply the smallest safe removal.
删除任何内容前先审计可达性。从活跃入口点到候选内容构建证据链,再执行最小范围的安全移除操作。
Follow this workflow
遵循以下工作流程
- Map the codebase entrypoints, public surfaces, and dynamic loading surfaces in scope.
- Search for references from public surfaces inward, not just from the candidate itself.
- Classify each candidate as unused export, unreachable code, orphaned file, stale feature flag, dead registration, or legacy compatibility path.
- Build a proof chain with code search, config or registry checks, framework conventions, and typecheck, build, or tests where available.
- Prioritize findings as through
P1.P4 - Auto-fix only local, low-risk removals. Leave broader deletions as findings with a concrete removal plan.
- 梳理范围内代码库的入口点、公共接口和动态加载面。
- 从公共接口向内搜索引用,而非仅从候选内容本身出发。
- 将每个候选内容分类为:未使用导出、不可达代码、孤立文件、过期feature flag、无效注册或遗留兼容路径。
- 通过代码搜索、配置或注册表检查、框架约定,以及可用的typecheck、构建或测试来构建证据链。
- 将发现的问题按至
P1划分优先级。P4 - 仅对本地低风险移除操作进行自动修复。范围更广的删除操作需作为问题记录,并附带具体的移除方案。
Map live entrypoints first
先梳理活跃入口点
Do not start deleting from leaf files without understanding how code can be reached.
Inspect the relevant equivalents of:
- routes, controllers, pages, and API handlers
- package exports, workspace boundaries, and public modules
- CLI commands and scheduled jobs
- queues, workers, and event subscribers
- dependency-injection or service-container registration
- framework auto-discovery and naming conventions
- plugin manifests, registries, and config-driven loading
- dynamic imports, reflection, and string-based dispatch
- tests, fixtures, storybook stories, and demo apps
- build scripts, codegen inputs, and release tooling
Dead code claims are weak until these entrypoints are checked.
在未了解代码可达路径前,不要从叶子文件开始删除。
检查以下对应内容:
- 路由、控制器、页面和API处理器
- 包导出、工作区边界和公共模块
- CLI命令和定时任务
- 队列、工作进程和事件订阅者
- 依赖注入或服务容器注册
- 框架自动发现和命名约定
- 插件清单、注册表和配置驱动的加载
- 动态导入、反射和基于字符串的调度
- 测试、测试夹具、Storybook故事和演示应用
- 构建脚本、代码生成输入和发布工具
未检查这些入口点前,死代码的判定是薄弱的。
Search for dead-code signals
搜索死代码信号
Start with the language-appropriate equivalents of:
importrequireexportpublicfunctionclassinterfacetypeconstenumif (false)if (FLAG)elseswitchdefaultreturnthrowbreakcontinuedeprecatedlegacyTODO removeunusedfeature flagregisterroutecommand
Also inspect:
- files with no inbound imports
- modules imported only by other suspected-dead modules
- modules re-exported but never consumed
- path aliases, barrels, or registries that may hide the last live reference
- duplicate implementations behind old/new paths
- branches gated by flags that are permanently on or off
- code after unconditional ,
return, or exhaustive matchesthrow - adapters kept only for migrations that already finished
从适合当前语言的以下内容入手:
importrequireexportpublicfunctionclassinterfacetypeconstenumif (false)if (FLAG)elseswitchdefaultreturnthrowbreakcontinuedeprecatedlegacyTODO removeunusedfeature flagregisterroutecommand
同时检查:
- 无入站导入的文件
- 仅被其他疑似死代码模块导入的模块
- 被重新导出但从未被使用的模块
- 可能隐藏最后一个活跃引用的路径别名、桶文件或注册表
- 新旧路径下的重复实现
- 被永久开启或关闭的flag限制的分支
- 无条件、
return或穷尽匹配后的代码throw - 仅为已完成的迁移保留的适配器
Build a proof chain
构建证据链
Treat "no references found" as a starting signal, not proof.
Prefer at least two independent pieces of evidence when possible:
- repo search shows no live callers after checking aliases, barrels, generated paths, and test-only consumers
- no route, command, registry, manifest, config, or package export points at the candidate
- framework conventions and auto-discovery rules do not require it by name or location
- removing it keeps typecheck, build, and targeted tests green when those checks exist
- feature-flag source of truth shows the branch is permanently on or off
- public-surface review finds no external or cross-workspace consumers you can verify
If evidence depends on a system you cannot inspect locally, downgrade the claim to a finding with missing proof instead of deleting.
将“未找到引用”视为起始信号,而非证据。
尽可能使用至少两个独立证据:
- 仓库搜索显示,检查别名、桶文件、生成路径和仅测试用的消费者后,无活跃调用者
- 无路由、命令、注册表、清单、配置或包导出指向候选内容
- 框架约定和自动发现规则不要求其名称或位置
- 在存在相关检查的情况下,移除该内容后typecheck、构建和针对性测试仍能通过
- feature flag的可信来源显示分支已永久开启或关闭
- 公共接口审查未发现可验证的外部或跨工作区消费者
如果证据依赖于无法本地检查的系统,将判定降级为缺失证据的问题记录,而非直接删除。
Detect these dead-code patterns
识别这些死代码模式
Unused exports
未使用导出
Flag exported values that have no live consumers.
Common signals:
- exported helper, component, hook, class, or constant with zero references outside its file
- barrel exports that expose symbols never imported anywhere
- public methods required by no interface, subclass, or framework hook
- package exports left behind after an internal refactor
Verify framework conventions before deleting. Some exports are consumed by reflection, auto-registration, templates, external packages, or sibling workspaces.
标记无活跃消费者的导出值。
常见信号:
- 导出的工具函数、组件、Hook、类或常量在文件外无引用
- 桶文件导出了从未被导入的符号
- 无接口、子类或框架Hook要求的公共方法
- 内部重构后遗留的包导出
删除前验证框架约定。部分导出可能被反射、自动注册、模板、外部包或兄弟工作区使用。
Unreachable code
不可达代码
Flag code paths that normal execution cannot enter.
Common signals:
- statements after ,
return,throw, orbreakcontinue - or
ifbranches guarded by impossible conditionsswitch - fallback branches after exhaustive enum or union handling
- code behind version checks or environment gates that can no longer occur
Prefer proving why the branch is impossible, not just that it looks suspicious.
标记正常执行无法进入的代码路径。
常见信号:
- 、
return、throw或break后的语句continue - 被不可能的条件限制的或
if分支switch - 穷尽枚举或联合类型处理后的回退分支
- 被不再可能触发的版本检查或环境限制的代码
优先证明分支为何不可能,而非仅依据外观判断可疑。
Orphaned files
孤立文件
Flag files, directories, or modules with no live entrypoint.
Common signals:
- module not imported, registered, routed, or referenced by config
- page, component, job, or worker replaced by a new implementation but never removed
- fixture, test helper, or mock file not referenced by any tests
- scripts that are no longer invoked by package scripts, CI, cron, or docs
Check for out-of-repo or cross-workspace consumers before deleting shared packages or public artifacts.
标记无活跃入口点的文件、目录或模块。
常见信号:
- 未被导入、注册、路由或配置引用的模块
- 被新实现替代但未被删除的页面、组件、任务或工作进程
- 未被任何测试引用的测试夹具、测试工具或模拟文件
- 不再被包脚本、CI、定时任务或文档调用的脚本
删除共享包或公共产物前,检查是否存在仓库外或跨工作区的消费者。
Stale feature flags
过期feature flag
Flag flags whose rollout is finished but both paths still remain.
Common signals:
- flag is always on or always off in current config
- old branch is still present long after migration or launch
- flag name includes a completed rollout, migration, or temporary workaround
- kill switch exists but no owner, expiry, or current use remains
Confirm the source of truth for the flag. Code search alone is not enough if flags are managed remotely.
标记已完成推出但仍保留双路径的flag。
常见信号:
- 当前配置中flag始终开启或关闭
- 迁移或发布后很久仍保留旧分支
- flag名称包含已完成的推出、迁移或临时解决方案
- 存在终止开关,但无所有者、过期时间或当前用途
确认flag的可信来源。若flag由远程管理,仅靠代码搜索是不够的。
Dead registrations and compatibility layers
无效注册和兼容层
Flag code kept only to support paths that no longer exist.
Common signals:
- event listeners subscribed to events no producer emits
- adapters for old payload shapes after all producers migrated
- deprecated routes, commands, or aliases with no callers
- serializer fields kept for clients that no longer exist
These often survive because the registration site looks live even though the upstream caller is gone.
标记仅用于支持已不存在路径的代码。
常见信号:
- 订阅了无生产者触发的事件的事件监听器
- 所有生产者迁移后保留的旧负载形状适配器
- 无调用者的废弃路由、命令或别名
- 为已不存在的客户端保留的序列化字段
这些代码常留存下来,因为注册站点看似活跃,但其上游调用者已消失。
Guard against false positives
防范误判
Dead-code audits are easy to get wrong where usage is indirect.
Be careful around:
- reflection and runtime method lookup
- DI container resolution by string or class name
- framework auto-discovery by filename or folder
- dynamic imports and lazy loading
- package exports, CLI entries, or monorepo workspace consumers
bin - generated registries, manifests, or codegen that recreate the reference chain
- templates that reference symbols indirectly
- code generation inputs and generated outputs
- public SDK or package APIs consumed outside the repo
- migrations, backfills, and historical one-off scripts that are intentionally retained
- feature flags controlled in remote dashboards or environment management
If reachability depends on conventions or external systems, report the finding with the missing proof instead of deleting speculatively.
在间接使用的场景下,死代码审计容易出错。
需注意以下情况:
- 反射和运行时方法查找
- 通过字符串或类名解析的DI容器
- 按文件名或文件夹自动发现的框架
- 动态导入和懒加载
- 包导出、CLI 条目或单仓库工作区消费者
bin - 重新创建引用链的生成注册表、清单或代码生成
- 间接引用符号的模板
- 代码生成输入和生成输出
- 仓库外使用的公共SDK或包API
- 有意保留的迁移、回填和历史一次性脚本
- 由远程仪表板或环境管理控制的feature flag
若可达性依赖于约定或外部系统,需记录问题并说明缺失的证据,而非推测性删除。
Classify findings
分类问题
P1
P1P1
P1Use for dead paths that actively create risk: stale flags masking security, billing, or data-integrity behavior, duplicate write paths that can diverge, or unreachable rollback logic that operators may believe still works.
用于存在主动风险的死路径:掩盖安全、计费或数据完整性行为的过期flag,可能出现分歧的重复写入路径,或操作员认为仍可用但实际不可达的回滚逻辑。
P2
P2P2
P2Use for dead code in active boundaries: orphaned routes, handlers, jobs, or compatibility layers that increase maintenance cost or hide which path is truly live.
用于活跃边界中的死代码:增加维护成本或掩盖真实活跃路径的孤立路由、处理器、任务或兼容层。
P3
P3P3
P3Use for routine cleanup: unused exports, unreachable local branches, dead helpers, unreferenced tests, or unused files with low behavioral risk.
用于常规清理:未使用导出、不可达本地分支、无效工具函数、未引用测试或行为风险低的未使用文件。
P4
P4P4
P4Use for cosmetic leftovers: comments referencing removed flags, empty barrels, deprecated aliases with obvious replacements, or cleanup that does not materially affect maintenance risk.
用于外观性遗留内容:引用已移除flag的注释、空桶文件、有明显替代方案的废弃别名,或对维护风险无实质影响的清理内容。
Auto-fix only when safe
仅在安全时自动修复
Auto-fix local removals when proof is strong and the blast radius is contained.
Safe examples:
- remove statements after unconditional or
returnthrow - delete a private helper or local constant with zero references in one module
- remove an import/export pair that is unused and not part of a public surface
- collapse a stale flag branch when the live branch is unambiguous and locally verified
- delete an orphaned test helper or fixture with no references
Do not auto-fix without explicit approval when the change affects:
- public APIs, SDKs, or package exports
- framework conventions or auto-discovery
- dynamic loading or reflection
- remote feature-flag systems
- database migrations, backfills, or compliance artifacts
- shared build, CI, release, or deployment scripts
- cross-repo consumers you cannot verify locally
For those, report the finding and recommend the smallest removal plan.
当证据充分且影响范围可控时,对本地移除操作进行自动修复。
安全示例:
- 移除无条件或
return后的语句throw - 删除单个模块中无引用的私有工具函数或本地常量
- 移除未使用且不属于公共接口的导入/导出对
- 当活跃分支明确且已本地验证时,合并过期flag分支
- 删除无引用的孤立测试工具函数或夹具
当变更影响以下内容时,未经明确批准请勿自动修复:
- 公共API、SDK或包导出
- 框架约定或自动发现
- 动态加载或反射
- 远程feature flag系统
- 数据库迁移、回填或合规产物
- 共享构建、CI、发布或部署脚本
- 无法本地验证的跨仓库消费者
对于这些情况,需记录问题并推荐最小范围的移除方案。
Choose the smallest defensible fix
选择最小的合理修复方案
Prefer this order:
- Remove the dead leaf code.
- Remove imports, exports, and registrations that only existed for it.
- Remove stale tests or fixtures tied only to the deleted path.
- Remove the flag or compatibility shim if both sides are now gone.
- Stop once the live path is simpler and still verified.
Avoid broad "cleanup passes" that mix proven dead code with speculative simplification.
优先遵循以下顺序:
- 移除死叶子代码。
- 移除仅为该代码存在的导入、导出和注册。
- 移除仅与已删除路径关联的过期测试或夹具。
- 若双路径均已消失,移除flag或兼容垫片。
- 当活跃路径更简洁且仍可验证时停止操作。
避免将已证实的死代码与推测性简化混合的大范围“清理”操作。
Report findings in this format
按以下格式报告问题
List findings first, highest severity first.
For each finding, include:
- priority: to
P1P4 - dead-code type: unused export, unreachable code, orphaned file, stale feature flag, dead registration, or compatibility layer
- location: file and line or the smallest concrete scope available
- proof chain: what references, registries, conventions, and validation checks were used
- false-positive risk: dynamic loading, external consumers, or unknowns
- recommended fix
- whether it is safe to auto-fix now
If no issues are found, say so explicitly and mention which entrypoints and dynamic-loading surfaces were checked plus any remaining blind spots.
先列出问题,按优先级从高到低排序。
每个问题需包含:
- 优先级:至
P1P4 - 死代码类型:未使用导出、不可达代码、孤立文件、过期feature flag、无效注册或兼容层
- 位置:文件和行号或可用的最小具体范围
- 证据链:使用了哪些引用、注册表、约定和验证检查
- 误判风险:动态加载、外部消费者或未知因素
- 推荐修复方案
- 当前是否可安全自动修复
若未发现问题,需明确说明,并提及检查了哪些入口点和动态加载面,以及任何剩余的盲区。
Default review stance
默认审查原则
- Prefer proof over suspicion
- Prefer deletion over deprecation once reachability is disproven
- Prefer contained removals over broad cleanups
- Prefer preserving live entrypoints over chasing local neatness
- Prefer findings with concrete reference evidence over style commentary
- 优先依据证据而非猜测
- 一旦证实不可达,优先删除而非废弃
- 优先进行可控范围的移除而非大范围清理
- 优先保留活跃入口点而非追求本地整洁
- 优先记录带有具体引用证据的问题而非风格评论