标红且无调用痕迹的0%覆盖率导出函数大概率是死代码,但需经引用分析、运行时覆盖验证及动态调用排查后,再按注释→测试→搜索→提交四步安全删除。

直接看函数覆盖率,标红且无任何调用痕迹的函数,大概率就是纯垃圾死代码——但“标红”只是起点,“安全剔除”才是关键动作。
盯紧函数覆盖率为 0% 的导出函数
这类函数在 Istanbul/nyc 或 Jest HTML 报告中整块标红,同时满足三个条件时,可初步锁定为死代码:
- 声明在 src/ 下、被
export导出(非内部闭包) - 全局搜索
import.*XXX、XXX(、XXX\.等变体,结果为空(注意大小写、解构导入、字符串拼接调用等漏网情况) - Chrome DevTools Coverage 面板里,该函数所在文件在完整用户路径下全程未执行(红色函数名 + 点击跳转确认是独立工具方法或旧钩子)
排除“假沉默”:不是所有 0% 都该删
有些函数看似没人调,实则藏在运行时动态路径里:
-
事件驱动场景:比如
addEventListener('message', handleExtMsg),若测试没发跨域消息,函数就标红——但它不是死代码,是测试遗漏 -
配置驱动逻辑:如
handlers[config.type]?.(),若 config.type 永远不等于该 handler 名,它就一直红——需查配置源,而非直接删 - tree-shaking 干预:ESM 导出但未被任何模块 import,打包后本就不进产物;开发阶段看到的“未覆盖”不等于运行时存在
安全删除三步走,避免误伤
确认真冗余后,别手快 Ctrl+X。按顺序执行:
-
先注释,再验证:用
// @ts-ignore或临时包裹成/* istanbul ignore next */注释掉整个函数,跑全量单元测试 + E2E,确保无报错、无行为变化 -
再搜字符串,防动态调用:不仅搜函数名,还要搜带引号的字符串形式(
'handleLegacy')、驼峰/下划线变体、正则匹配式调用(fnMap\[.*\]) - 最后提交,留痕可溯:删除时 commit message 明确写清“移除未调用函数 XXX,经引用分析与 Coverage 验证确认无任何调用点”
顺手扫清配套残留
死函数往往带着“寄生代码”,一并清理更彻底:
- 该函数所在文件中,仅被它调用的私有辅助函数(检查调用链是否断在它身上)
- 对应
import语句,以及该 import 带来的多余依赖(如只用了lodash/debounce却 import 了整个 lodash) - 测试文件里为它写的“僵尸用例”——即函数已删,但 test 文件里还保留着
test('should call XXX', ...)


















