Knip Catalogs 全面指南:检测与清理 pnpm、Yarn、Bun 未使用的目录版本引用
【免费下载链接】knip✂️ Find unused files, dependencies and exports in your JavaScript and TypeScript projects. Knip it before you ship it!项目地址: https://gitcode.com/gh_mirrors/kn/knip
Catalogs(依赖目录)允许你在 monorepo 中一次性定义依赖版本范围,并在各个 workspace 中通过catalog:协议统一引用。本指南聚焦 Knip 对 catalog 的专项支持:如何定位已定义但不再被引用的 catalog 条目(unused catalog entries)、如何报告引用不存在的条目(unresolved catalog references),以及如何用--fix自动清理。读完本文,你将掌握 catalog 的四种来源配置、引用解析范围、过滤与自动修复的完整工作流。
什么是依赖目录(Catalogs)
在大型 monorepo 中,不同 workspace 常常需要锁定同一依赖的相同版本范围。与其在每个package.json中重复维护版本号,不如在根级配置文件中集中定义一次版本范围,再在各处用catalog:协议引用。Knip 会对这套机制进行专项静态分析:把"定义了但没人引用"的条目报告为catalog类型问题,把"引用了但目录中不存在"的条目报告为catalogReferences类型问题,并可借助 auto-fix 自动删除无用条目。
以packages/app/package.json为例,catalog:引用默认目录,catalog:validation引用名为validation的命名目录:
{ "dependencies": { "react": "catalog:", "zod": "catalog:validation" } }支持的目录来源
Knip 按优先级从以下位置的第一个适用位置读取目录(参考 util/catalog.ts 中的getCatalogContainer实现):
| 位置 | 键 | 说明 |
|---|---|---|
pnpm-workspace.yaml | catalog(默认)、catalogs(命名) | pnpm 的标准 catalog 配置 |
.yarnrc.yml | catalog、catalogs | Yarn 的 catalog 配置 |
package.json | catalog、catalogs | 根package.json中的目录 |
package.json#workspaces | catalog、catalogs | Bun 场景下随workspaces字段定义 |
从源码看,选择逻辑是:若存在pnpm-workspace.yaml则优先使用;否则若存在.yarnrc.yml则读取该 YAML 文件;最后回退到 manifest(package.json)。命名空间判断上,若workspaces字段不是数组(即 Bun 的workspaces对象形式),则从中读取catalog/catalogs。
命名目录(Named Catalogs)
除了默认目录,catalogs键可定义多个命名目录,用于按用途分组管理版本。源码parseCatalog(util/catalog.ts)会同时展开默认目录条目(标记为default:<包名>)和命名目录条目(标记为<目录名>:<包名>),统一进入条目集合。
未使用的目录条目(Unused Catalog Entries)
当某个目录条目没有被任何 workspace 通过catalog:协议引用时,Knip 将其报告为catalog类型问题。
引用解析覆盖以下字段(见 util/catalog.ts 的extractCatalogReferences):
dependenciesdevDependenciespeerDependenciesoptionalDependenciesresolutionspnpm-workspace.yaml#overrides- 根
package.json的pnpm.overrides(pnpm 10 及更早版本)
在源码extractCatalogReferences中,前五个字段统一遍历收集引用,CatalogCounselor的addWorkspace会额外处理根 workspace 的pnpm.overrides(CatalogCounselor.ts)。overrides 中的 selector 支持package@range、parent>child等复杂写法,通过getOverrideCatalogReferences解析目标包名与目录引用(util/catalog.ts)。
仓库测试夹具 catalog-pnpm 展示了完整的 pnpm catalog 与 overrides 组合场景:默认catalog定义了react、typescript、lodash、left-pad、ms、bar、kleur等条目,其中left-pad@^1: 'catalog:'、debug>ms: 'catalog:'这类 selector 形式的 overrides 引用,以及foo@3 \|\| >=2>kleur的多条件 selector,都会计入引用集合。
未解析的目录引用(Unresolved Catalog References)
当catalog:引用指向的目录中没有定义该包时,Knip 报告catalogReferences类型问题。这些 issue 会指向消费方package.json或pnpm-workspace.yaml——也就是包管理器在安装时将会解析失败的位置。
CatalogCounselor.addWorkspace的逻辑是:先登记所有被引用的条目(<目录名>:<包名>),随后逐一检查该条目是否存在于目录条目集合中;不存在则生成一条catalogReferencesissue,并通过PackagePeeker精确定位引用在文件中的行列位置。对于根目录中来自pnpm-workspace.yaml#overrides的引用(如missing@^1: 'catalog:'),若对应目录无此条目,则由YamlCatalogPeeker定位到 YAML 文件对应行(CatalogCounselor.ts)。
测试夹具 catalog-references 中,overrides里的missing@^1: 'catalog:'指向默认 catalog 不存在的missing包,同时子包 package.json 中express: "catalog:backend"指向并不存在的命名目录backend,二者均属于典型的未解析目录引用场景。
过滤与聚焦
catalog和catalogReferences两个 issue 类型已包含在--dependencies快捷标志中(详见 rules-and-filters.md),因此只需专注于依赖类问题时无需单独罗列。你也可以像对待其他 issue 类型一样单独聚焦或排除:
knip --include catalog,catalogReferences knip --exclude catalog,catalogReferences也可以写入配置文件,例如"exclude": ["catalog"]。在 issue-types.md 的问题类型总表中,catalog(未使用的目录条目)标注为可自动修复(🔧),catalogReferences(未解析的目录引用)暂不可自动修复。
自动修复未使用的目录条目
Auto-fix 支持删除未使用的 catalog 条目,通过--fix-type指定:
knip --fix --fix-type catalogKnip 只会删除未被引用的条目,保留仍在使用的部分。以pnpm-workspace.yaml为例,假设unused-package已无任何 workspace 引用:
packages: - 'packages/*' catalog: react: ^18.0.0 - unused-package: ^1.0.0package.json中的 catalogs 同样支持自动修复。在源码层面,settleCatalogIssues会在修复模式下为 YAML 文件中的无用条目附加行级修复位置(fixes数组),再交由 IssueFixer 执行删除(CatalogCounselor.ts)。修复前建议使用 Git 等 VCS 审查改动,修复后可配合--format让项目自带格式化器(Prettier、Biome、dprint、deno fmt)统一输出格式。
在配置中启用目录分析
Knip 对 catalog 的分析随依赖分析默认开启,无需额外安装插件。一个完整的 monorepo 根配置(knip.json)可以是:
{ "workspaces": ["packages/*"], "rules": { "catalog": "error", "catalogReferences": "error" } }rules支持"error"(计入错误总数)、"warn"(仅打印、灰显、不计错误)与"off"(等价于 exclude)三档(rules-and-filters.md),可按团队口径决定目录问题的严重级别。
小结
- Knip 从
pnpm-workspace.yaml、.yarnrc.yml、package.json及其workspaces字段读取目录,catalog为默认目录、catalogs为命名目录。 - 无引用的目录条目报告为
catalog,引用不存在的条目报告为catalogReferences;两者均包含在--dependencies快捷标志中。 - 引用来源覆盖
dependencies、devDependencies、peerDependencies、optionalDependencies、resolutions以及 pnpm overrides。 - 使用
knip --fix --fix-type catalog可自动删除未使用的目录条目;package.json中的目录同样受支持。
【免费下载链接】knip✂️ Find unused files, dependencies and exports in your JavaScript and TypeScript projects. Knip it before you ship it!项目地址: https://gitcode.com/gh_mirrors/kn/knip
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考