一、为什么需要依赖检查?
前端项目随着迭代,依赖(dependencies)会越积越多:
- 早期引入的库后来换了实现方式,旧依赖忘了删
- 多人协作时每个人安装了不同的包
- 重构后某些依赖不再使用了,但没人清理
devDependencies和dependencies放错了位置
这些幽灵依赖不仅让 node_modules 越来越大,还可能隐藏安全漏洞(无人使用的包不会收到安全更新通知)。手动检查几百个依赖既不现实也容易遗漏,这时候就需要专门的工具——depcheck。
二、depcheck 是什么?
depcheck 是一个 CLI 工具,可以分析项目中 JavaScript / TypeScript / 前端框架的依赖关系,找出:
| 检测类型 | 说明 |
|---|---|
| 未使用的依赖 | package.json 中声明了但代码里从未 import/require 的包 |
| 缺失的依赖 | 代码里使用了但 package.json 中没有声明的包 |
| 未使用的 devDependencies | 开发依赖中声明了但实际没有用到的包 |
它支持超过 50 种框架和工具的解析规则,包括 React、Vue、Webpack、Babel、ESLint、TypeScript 等。
三、安装
全局安装:
npm install -g depcheck或者作为项目开发依赖:
npm install --save-dev depcheck使用 npx 直接运行(无需安装):
npx depcheck四、基本使用
4.1 默认扫描
在项目根目录下运行:
depcheck默认会扫描以下文件:
package.json(读取依赖列表)*.js、*.jsx、*.ts、*.tsx、*.vue、*.svelte等源文件- 支持
import、require()、import()等引用语法
4.2 输出示例
$ depcheck
Unused dependencies
* lodash
* moment
Unused devDependencies
* @types/jquery
Missing dependencies
* react-dom每行为一个包名,直接对应 package.json 中需要清理的条目。
4.3 指定目录和文件
# 指定扫描目录
depcheck --rootDir=./src
# 跳过某些文件
depcheck --ignore-patterns="dist/*,test/fixtures/*"
# 忽略特定依赖(全局安装的 CLI 工具等)
depcheck --ignores="eslint,prettier"五、高级用法
5.1 使用配置文件
在项目根目录创建 .depcheckrc:
ignores:
- eslint
- prettier
- "@types/*"
- autoprefixer
ignore-patterns:
- dist
- "*.test.js"
- coverage
skip-missing: true然后直接运行 depcheck 即可自动读取配置。
5.2 JSON 输出(适合 CI 集成)
depcheck --json输出:
{
"dependencies": ["lodash", "moment"],
"devDependencies": ["@types/jquery"],
"missing": {
"react-dom": ["src/App.tsx"]
},
"using": {
"react": ["src/App.tsx"],
"axios": ["src/api/index.ts"]
}
}可以配合 CI 脚本实现自动化检查:
// package.json
{
"scripts": {
"check-deps": "depcheck --json | node -e \"process.stdin.resume();let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const r=JSON.parse(d);if(r.dependencies.length||r.devDependencies.length){console.error('未使用的依赖:',[...r.dependencies,...r.devDependencies]);process.exit(1)}else{console.log('✅ 依赖检查通过')}})\""
}
}5.3 指定特殊解析器
对于非标准文件类型,可以指定解析器:
# 强制使用特定解析器
depcheck --parsers="*.scss:scss"内置解析器覆盖:
- JavaScript / TypeScript(默认)
- React JSX / TSX
- Vue SFC(单文件组件)
- CSS / SCSS / Less
- 模板引擎(EJS、Handlebars 等)
六、集成到工作流
6.1 Git Hooks(husky + lint-staged)
npm install --save-dev husky lint-staged在 package.json 中配置:
{
"lint-staged": {
"*.{js,ts,jsx,tsx,vue}": [
"depcheck",
"eslint --fix"
]
}
}6.2 CI 流水线(GitHub Actions)
# .github/workflows/depcheck.yml
name: Dependency Check
on: [pull_request]
jobs:
depcheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npx depcheck --json
- run: |
REPORT=$(npx depcheck --json)
if echo "$REPORT" | grep -q '"dependencies":\[\]'; then
echo "✅ 依赖检查通过"
else
echo "❌ 发现未使用的依赖"
echo "$REPORT" | npx json
exit 1
fi6.3 定期清理任务
在 package.json 中添加脚本:
{
"scripts": {
"clean-deps": "depcheck --json | node -e \"
const d=require('fs').readFileSync('/dev/stdin','utf8');
const r=JSON.parse(d);
const unused=[...r.dependencies,...r.devDependencies];
if(unused.length){console.log('可删除:',unused.join(', '))}else{console.log('无需清理')}
\"",
"purge-deps": "npm run clean-deps && rm -rf node_modules && npm install"
}
}七、常见场景与处理
7.1 CLI 全局工具被误报
像 eslint、prettier、webpack 这些 CLI 工具在 devDependencies 中,但在代码里不通过 import 使用——depcheck 会误报。通过 .depcheckrc 忽略:
ignores:
- webpack
- webpack-cli
- eslint
- prettier7.2 TypeScript 类型包
@types/* 系列包是类型定义,不在运行时代码中 import,也会被误报。建议统一忽略:
ignores:
- "@types/*"7.3 CSS / 图片资源依赖
某些 CSS 框架(如 Tailwind CSS)或图片资源通过配置文件或 PostCSS 插件引用,depcheck 可能检测不到。可手动补充:
depcheck --ignores="tailwindcss,autoprefixer,postcss"7.4 Monorepo / Workspaces
对于使用 npm/yarn/pnpm workspaces 的 monorepo 项目,depcheck 需要分别在每个子包中运行:
npm run -w packages/* depcheck八、注意事项
| 场景 | 建议 |
|---|---|
| 第一次使用 | 从开发环境开始,不要直接删依赖,先确认 |
| CI 集成 | 建议只警告不阻断,等人工确认后再清理 |
| 大项目 | 扫描时间较长,建议配置 --ignore-patterns 跳过无关目录 |
| Monorepo | 每个子包单独扫描,注意 root 级别的公共依赖 |
九、总结
depcheck 是前端工程化中容易被忽视但非常有价值的一环。它解决的不是「能不能跑」的问题,而是代码健康度的问题——一个没有幽灵依赖的项目,依赖关系更清晰、node_modules 更轻量、安全漏洞面更小。
配合 CI 或 Git hooks 定期运行,可以让依赖始终保持整洁,不给技术债留下积累的空间。