用途:在 TypeScript 仓库中把每个包改造为“深模块”——大量行为藏在小接口之后。包的公开面是它的入口点(包根目录文件),子文件夹中的内容对外部不可见。该技能安装 dependency-cruiser 并配置规则,使入口点成为唯一进入方式,再通过制造一次违规验证规则确实生效。
强制结构:src/packages/<name>/ 下 index.ts、client.ts 等根文件为入口点(可有多个),lib/ 存放实现(对外隐藏),tests/ 存放同址测试与 fixture(属子文件夹,故私有)。公开面是包根文件而非单一 index.ts;约定实现放 lib/、测试放 tests/,但规则本身基于路径深度,任何子文件夹均为私有,无需为新增文件夹改配置。
四条规则均为 error 级别:入口点边界(包外代码只能导入该包根文件,不得进入其子文件夹);包内自由(同包文件可互相导入);测试经入口点(<pkg>/tests/ 下文件可导入任意包的入口点及自身 tests/ fixture,但不得导入任何包子文件夹内部,跨包集成测试允许,深度导入不允许);禁止循环依赖。
使用步骤:1)检测环境——依 pnpm-lock.yaml/yarn.lock/bun.lockb 判断包管理器(否则 npm),确定包根目录(有 src/ 用 src/packages,否则 packages),检查是否已有 .dependency-cruiser.*,若存在则合并不覆盖并告知用户。2)以 devDependency 安装 dependency-cruiser。3)将 dependency-cruiser.config.cjs 复制到仓库根目录为 .dependency-cruiser.cjs,设置 PACKAGES_ROOT。4)添加 lint:boundaries 脚本 depcruise <packages-root>(或 depcruise src),并入已有的 typecheck 汇总命令;不改 tsconfig、不加路径别名。5)创建示例包 <packages-root>/example/ 作为可复制模板:index.ts 入口、lib/impl.ts 内部实现、tests/example.test.ts。6)验证规则生效——“证明规则咬人”:干净示例下运行通过;临时在 tests/example.test.ts 添加深度导入(如 import { thing } from "../lib/impl")后必须失败(tests-through-entrypoints);还原后再次通过。7)文档化——在包目录写 README.md 说明布局、入口点导入规则、lint:boundaries 用法,并明确不鼓励 barrel 文件;在 CLAUDE.md(否则 AGENTS.md,均无则创建)加一行指向该 README。
注意:配置中的 $1 反向引用(dependency-cruiser 分组匹配)是让包能访问自身内部而外部不能的关键,不要拆成每包单独规则。公开与私有由深度决定。包为扁平结构:根目录下一层直属子项,包内部可任意嵌套,但包不能包含包。使用 .cjs(非 .js)以保证在 "type": "module" 仓库中 module.exports 可用。分层(哪些包可依赖哪些)是另一问题,留作配置中的注释存根。其余如具体安装命令版本、收费情况资料未提供,暂未提供。