防止 TypeScript 循环依赖的 setup-ts-deep-modules
機械翻訳 / Machine-translated
機械翻訳 / Machine-translated
原文:TypeScriptの循環依存を防ぐ setup-ts-deep-modules(cccskills)
技能页面:setup-ts-deep-modules
本文结论
setup-ts-deep-modules 是一个用于将 TypeScript 包对外暴露的入口限制为直接子文件的技能。
安装后,可一次性完成该结构的配置、校验和文档化。
本文将依次介绍:导入的 4 条规则、如何确认规则是否生效、Claude Code 和 Codex 的安装方法、请求示例,以及安装前需要确认的前提条件。
调用 setup-ts-deep-modules 后,Agent 会在仓库中加入边界检查,并确认规则是否真的能阻止违规行为。
检查对象是对包内部的直接引用和循环依赖。
发布方为 GitHub 上的 mattpocock/skills(⭐297,465),许可证为 MIT。
请使用 setup-ts-deep-modules,为本仓库的包加入边界检查。
Agent 首先会查看锁文件来判断包管理器。
包的存放位置:如果有 src/ 则为 src/packages,否则为 packages。
接着将 dependency-cruiser 添加为开发依赖,并在仓库根目录放置配置文件 .dependency-cruiser.cjs。
dependency-cruiser 是一个分析文件间 import 关系并报告规则违规的工具。
作业完成后,各包将统一为以下结构:
src/packages/
<name>/
index.ts ← 公开文件(允许从外部 import)
client.ts ← 公开文件可以有多个
lib/ ← 实现。不可从外部引用
tests/ ← 测试。因为是子文件夹,所以为非公开
同时会添加名为 lint:boundaries 的脚本,并集成到已有的运行类型检查的汇总命令(如 check 或 ci)中。
此外还会创建示例用的 example 包和记录规范的 README.md,并在 CLAUDE.md 或 AGENTS.md 中添加一行指向该 README 的引用,这些都在作业范围之内。
该技能的核心是将包的公开范围限定为"仅限直接子文件",并将对其他文件的引用作为错误处理。
子文件夹中的内容,无论名称如何,均视为非公开。
增加文件夹时无需修改配置。
导入的规则共 4 条,违反任何一条均会报错:
由于有第 3 条规则,测试也会从与使用者相同的入口来验证行为。
可以编写跨多个包的集成测试,但不能编写直接读取内部的测试。
边界检查作为 lint:boundaries 被添加,并集成到运行类型检查的 check 或 ci 等汇总命令中。
不会修改 tsconfig 或路径别名,因此现有的构建配置不会改变。
对于没有汇总命令的仓库,仅添加 lint:boundaries,并告知用户将其纳入 CI。
example 包是创建新包时可以复制使用的范本。
index.ts 公开的函数将处理逻辑委托给 lib/impl.ts,测试只 import ../index 的结构。
该模板创建后可按需删除。
创建模板后,Agent 会通过 3 次运行来确认规则是否生效:
第 1 次:在无违规的状态下通过;
第 2 次:在测试中临时添加对 lib/impl 的直接 import,应失败;
第 3 次:还原后再次通过。
若第 2 次未能失败,则视为配置有误,会在完成作业前予以修复。
包文件夹的 README.md 中会汇总:结构说明、4 条规则、lint:boundaries 的运行方法。
文件中会明确指出,应避免使用将所有子内容重新导出的"桶文件(barrel file)",改为设置多个小型公开文件。
此外,会在 CLAUDE.md(若不存在则为 AGENTS.md,两者都不存在则新建 AGENTS.md)中添加一行指向该 README 的引用。
后续作业的 Agent 可以通过这一行找到边界规范。
安装方式有两种:通过命令安装,或委托 Agent 安装。
通过命令安装时,可以在执行时选择安装目标 Agent(Claude Code 或 Codex 等)。
npx skills add https://github.com/mattpocock/skills --skill setup-ts-deep-modules
委托 Agent 安装时,请直接发送以下内容:
请安装以下 Agent Skill。
https://github.com/mattpocock/skills/tree/main/skills/in-progress/setup-ts-deep-modules
请先确认 SKILL.md 及附属文件的内容,确认不存在可疑操作(如向外部发送数据、读取认证信息等),然后将其放置于:Claude Code 请放到 ~/.claude/skills/setup-ts-deep-modules/,Codex 请放到 ~/.agents/skills/setup-ts-deep-modules/。
存放位置根据是用于所有项目还是仅用于特定项目而有所不同:
| Agent | 用于所有项目 | 仅用于特定项目 |
|---|---|---|
| Claude Code | ~/.claude/skills/ | 项目的 .claude/skills/ |
| Codex | ~/.agents/skills/ | 项目的 .agents/skills/ |
技能文件夹中除 SKILL.md 外,还包含作为配置基础的 dependency-cruiser.config.cjs 和 agents/openai.yaml。
手动放置时,请将整个文件夹复制过去。
该技能设计为由用户显式调用。
在请求文中写明技能名称,并附上希望重点关注的事项,会更容易传达意图。
请使用 setup-ts-deep-modules,为现有仓库加入边界检查。
由于已有 dependency-cruiser 的配置,请不要覆盖,而是进行集成。
即使已有 .dependency-cruiser.*,Agent 也不会覆盖。
它会整合 4 条规则和配置,并报告添加了哪些内容。
集成后运行 lint:boundaries,当前代码中对内部的直接引用和循环依赖将作为错误被列出。
请使用 setup-ts-deep-modules 创建可复制使用的 example 包,并确认能否检测到违规。
example/ 中会创建 3 个文件:index.ts、lib/impl.ts、tests/example.test.ts。
随后会展示通过→失败→通过的 3 次运行结果,可当场确认规则是否生效。
请按照 setup-ts-deep-modules 的流程,将包的规范汇总到 README 中,并从 CLAUDE.md 引用。
包文件夹的 README.md 中会以各一段的形式写入结构示例和 4 条规则。
CLAUDE.md 中会添加一行,大意为"在新增或 import 包之前请阅读此 README"。
首先需要确认的是对现有代码的影响。
4 条规则均作为错误处理,并集成到与类型检查相同的命令中。
如果现有代码中存在对内部的直接引用或循环依赖,在引入时汇总命令将会失败,请预留修复所需的时间。
适用的结构也有前提条件。
包必须以一层的形式平铺在存放目录的直接子目录下,不支持包内嵌套其他包的结构。
哪个包可以依赖哪个包的依赖方向限制也不在范围之内。
这部分会以注释草稿的形式保留在配置文件中。
在环境方面,会通过 npm、pnpm、yarn 或 bun 之一将 dependency-cruiser 添加为开发依赖。
配置文件为 .cjs 格式,在设置了 "type": "module" 的仓库中也不会有问题。
技能说明是以同一仓库中的 codebase-design 技能被调用、术语统一为前提编写的。
一并安装后,说明中使用的术语将保持一致。
许可证为 MIT。
安装前请阅读 SKILL.md 及附属文件,确认不存在向外部发送数据或读取认证信息等可疑操作。
codebase-design 是一个支持以下设计的技能:保持调用方需要记住的使用方式简洁,将复杂处理集中在内部。
setup-ts-deep-modules 以使用该技能的术语(deep module、interface 等)为前提,因此可以用同一套语言推进设计讨论和边界检查机制的建设。
code-review 是一个以提交或分支为基准确认变更,并分别从开发规范符合性和功能实现两个角度进行审查的技能。
在确定边界规范之后,可用于日常确认变更是否符合规范。
不需要。
技能中附带的配置文件会作为 .dependency-cruiser.cjs 复制到仓库根目录,只需修改包的存放路径。
规则通过文件夹深度判断,无需根据扩展名进行调整。
不限于一个。
包直接子目录下的所有文件均视为公开文件,可以同时放置 index.ts、client.ts、server.ts 等多个文件。
将所有子内容重新导出的桶文件(barrel file)会被建议避免使用。
该功能不在本技能的范围之内。
依赖方向的限制作为单独关注点处理,仅在配置文件中以注释草稿的形式保留。
如有需要,请根据仓库情况自行补充编写。
setup-ts-deep-modules 是一个将包的入口限定为直接子公开文件、并将对内部的直接引用和循环依赖作为错误处理的技能。
作业范围涵盖:引入 dependency-cruiser、与类型检查集成、创建模板、通过 3 次运行进行验证,以及规范文档化。
适合不想依赖代码审查中的注意力,而希望通过机制来守护模块边界的团队。
安装前请阅读 SKILL.md,预留好处理现有代码违规所需的时间后再进行尝试。
本文转载自 cccskills 的文章「TypeScriptの循環依存を防ぐ setup-ts-deep-modules」。
技能详情及安装方法请参见 cccskills 的 setup-ts-deep-modules 页面。