死逻辑处理是同步静态编译期行为,分三层协作:Babel插件剔除硬编码分支、Webpack/Vite插件隔离未引用模块、ESLint规则辅助识别;所有死代码归档至src/dead/并生成可审计报告。

“异步隔离并剔除死逻辑”这个说法容易引起误解——死逻辑的识别与剔除本身是**同步、静态、编译期**行为,不存在真正意义上的“异步执行”。所谓“异步”,实际是指在构建流程中**非阻塞式地介入多个阶段**(如解析、转换、优化),或**跨工具链协同分析**(如 Babel + Webpack + ESLint),从而实现更全面、可收敛的死逻辑处理。关键不是时间上的异步,而是流程上的分层协作。
用 Babel 插件做第一层:静态可判定分支的即时剔除
这是最安全、最直接的一环,聚焦于语法明确、无需运行时信息即可下结论的代码:
- 匹配 IfStatement、ConditionalExpression(三元)、LogicalExpression(
&&/||)节点,对test子表达式调用evaluate()静态求值 - 只处理
process.env.NODE_ENV === 'development'这类硬编码环境判断(需插件配置envMap: { NODE_ENV: 'production' }),不碰config.debug或window.__DEV__等动态值 - 遇到
console.log、debugger、if (false) { ... }直接移除,但前提是path.isPure() === true或已确认无副作用 - 所有修改使用
path.replaceWith()而非path.remove(),避免破坏语句层级结构
用 Webpack/Vite 插件做第二层:模块级与导出级的上下文感知隔离
Babel 看不到文件间依赖,这一层补足语义缺失,把“未被引用的导出”和“未被 import 的模块”纳入隔离范围:
- 在
compilation.hooks.optimizeChunks(Webpack)或buildEnd(Vite)钩子中遍历模块图,识别export function utilsA()却全项目无import { utilsA }的命名导出 - 扫描 JSDoc 标记,如
/** @dead-code reason="deprecated" */,自动将整块代码提取到src/dead/目录,并在原位置插入占位注释 - 对
import('./pages/' + route)这类动态导入,仅处理字符串字面量(如import('./pages/home')),其余留白供人工审核 - 生成
unused-exports.json和orphan-modules.json报告,供后续流程复用
用 ESLint + 自定义规则做第三层:辅助识别潜在死逻辑
ESLint 不参与打包,但它能提前发现 Babel 和 Webpack 难以覆盖的语义问题,作为前置校验和人工复核依据:
- 启用
eslint-plugin-unused-imports扫描未使用导出,输出 JSON 结果供 Babel 插件读取后精准删除 - 自定义规则检测
if (DEBUG_MODE) { ... }中DEBUG_MODE是否为字面量或常量声明,否则标黄提醒“无法静态剔除” - 标记
try/catch中空catch块、永远不抛错的throw new Error('')等可疑模式 - 该层不自动删代码,只提供
/* eslint-disable dead-code/no-implicit-dead */等开关,由开发者确认后交由构建脚本执行
归档而非删除:保障可审计与可回滚
真正健壮的死逻辑处理,从不追求“一键清零”,而是让每一步操作可追溯、可还原:
- 所有被判定为死逻辑的代码,统一移动至
src/dead/目录,按日期+模块名归档,保留原始文件路径结构 - 原位置替换为标准化注释,例如:
/* DEAD: utilsA removed on 2026-05-08 — reason: unused export */ - 构建产物中加入
dead-code-report.html,列出本次隔离的所有条目、触发规则、原始行号及归档路径 - CI 流程中增加比对检查:若某文件在
src/dead/中存在但 Git 记录里无对应删除提交,则中断发布,防止误操作










