ESModule静态分析识别无用模块的核心是反向可达性分析:从可信入口出发,通过AST解析import/export构建依赖图,标记动态导入中的可推断路径,比对文件系统与可达集合,排除白名单后报告未引用模块。

ESModule 的静态分析检测无用模块,核心在于识别 未被任何入口或动态导入链引用的模块文件。它不依赖运行时执行,而是在构建前通过解析 import/export 语句构建依赖图,再从已知入口(如 main.js、src/index.ts)出发做反向可达性分析——不可达即为“无用存量模块”。
提取完整模块依赖图
需借助能准确解析 ESModule 语法的工具,跳过 CommonJS 混用干扰:
- 使用 acorn 或 esbuild.parse 做 AST 解析,提取所有
import、export、import.meta节点,忽略require()和module.exports - 对每个
import 'path'或import x from 'path',标准化路径(处理 .js/.ts 后缀、/index.js 隐式解析、别名映射),生成精确的模块 ID - 记录每个模块导出的名称(
export const a)、默认导出(export default)、命名空间导出(export * from),并标记 re-export 关系
确定可信入口点并执行反向追踪
入口不能仅靠 package.json#main,需结合项目实际启动逻辑:
- 显式列出 CI 中真正参与构建的入口文件,例如:
src/main.ts、tests/setup.ts、scripts/cli.ts - 从这些入口开始,递归收集所有被
import的模块,构建“可达模块集合” - 特别处理动态导入:
import('./utils/foo.js')必须被 AST 捕获并加入追踪;但import(dynamicPath)这类无法静态推断的,应标记为“潜在引用”,其目标模块不视为无用
比对文件系统与可达集合,报告未引用模块
扫描项目中所有 .ts/.js 文件(排除 node_modules、dist、__tests__ 等目录),执行差集运算:
立即学习“Java免费学习笔记(深入)”;
- 若某模块文件未出现在可达集合中,且不是类型声明(
.d.ts)、纯声明文件或仅含declare module,则判定为“无用存量模块” - 输出带路径和简要上下文的列表,例如:
src/lib/legacy-api-client.ts (no import found, not re-exported) - 支持配置白名单(如
src/polyfills/*.ts)避免误报
集成到 CI/CD 并设置阻断策略
在 lint 或 build 阶段前插入检查,确保增量引入不扩大无用模块规模:
- 用 GitHub Actions / GitLab CI 调用脚本:
npx ts-unused-exports --project tsconfig.json或自研 CLI 工具 - 首次接入可设为 warning,生成报告但不失败;稳定后改为 error,禁止 PR 合并含新增无用模块的提交
- 配合 git diff,只检查本次变更涉及的文件及其依赖子图,提升速度(如:仅分析修改过的
src/features/*下新增/改名的模块)
不复杂但容易忽略的是路径标准化和动态导入边界——错判一个 import('./pages/' + pageName) 就可能让整个 pages 目录“消失”在可达图中,导致大量误报。关键在平衡精度与实用性,优先保障主流程静态可溯。


















