# Setup Ts Deep Modules

将 dependency-cruiser 接入 TypeScript 仓库，使每个 package 都是一个深度模块：实现隐藏在子文件夹中，只能通过入口点文件访问。由用户调用。

- Repository: https://github.com/devcxl/mattpocock-skills-zh (522 stars)
- Category: Engineering
- License: MIT
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add devcxl/mattpocock-skills-zh --skill setup-ts-deep-modules -g -a claude-code -y`
Codex: `npx skills add devcxl/mattpocock-skills-zh --skill setup-ts-deep-modules -g -a codex -y`
Cursor: `npx skills add devcxl/mattpocock-skills-zh --skill setup-ts-deep-modules -g -a cursor -y`
Gemini CLI: `npx skills add devcxl/mattpocock-skills-zh --skill setup-ts-deep-modules -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add devcxl/mattpocock-skills-zh`

## Description

将 dependency-cruiser 接入 TypeScript 仓库，使每个 package 都是一个深度模块：实现隐藏在子文件夹中，只能通过入口点文件访问。由用户调用。

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# 设置 TS 深度模块

让此仓库中的每个 package 都成为一个**深度模块**：小接口背后隐藏大量行为。一个 package 的公开表面是其**入口点**：package 根目录下的文件：而其子文件夹中的所有内容都是隐藏的。本技能安装 [dependency-cruiser](https://github.com/sverweij/dependency-cruiser) 与让入口点成为唯一通路的规则，然后验证规则确实起作用。

关于相关词汇（深度模块、接口、接缝、depth），请调用 Skill 工具并传入 "codebase-design"：在后续内容中使用它的术语。

## 它强制形成的结构

```
src/packages/
  <name>/
    index.ts        ← 一个入口点（公开）。外部从这里导入。
    client.ts       ← 另一个入口点。Package 可以暴露多个。
    lib/            ← 实现：对外部隐藏，内部可以自由相互导入。
    tests/          ← 与实现并列的测试与 fixtures（一个子文件夹，所以是私有的）。
```

公开表面是 package 的**根文件**，而不是某个指定的 `index.ts`。按惯例实现放在 `lib/`，测试放在 `tests/`，让每个 package 都拥有相同的"两个子文件夹"结构。不过规则本身是普适的：*任何*子文件夹里的*任何*文件都是私有的，所以你永远不需要为了新增文件夹而扩展配置。

四条规则，全部为 `error`：

1. **入口点边界**：package 外部的代码（应用代码或其他 package）只能导入该 package 的入口点（即其根文件），绝不能导入其子文件夹中的任何内容。
2. **包内自由**：package 自己的文件可以自由地相互导入。
3. **测试通过入口点**：`<pkg>/tests/` 下的文件可以导入任何 package 的入口点以及它自己的 `tests/` fixtures，但不能导入任何 package 的子文件夹内部内容（包括它自己的）。跨 package 的集成测试可以，但深路径导入不行。
4. **无循环依赖**：不允许存在依赖循环。

**入口点，而非桶文件（barrel）。** 由于公开表面是*每个*根文件，所以一个 package 可以暴露多个小型入口点（`index.ts`、`client.ts`、`server.ts`），而不是把一切都集中塞进一个巨大的 `index.ts`。不要用桶文件来再导出整棵子树；保持入口点小而精，把实现藏在子文件夹里。

分层（哪些 package 可以依赖哪些 package）是*另一回事*，本仓库把它以注释桩（commented stub）的形式留在配置里供填充。

## 流程

### 1. 探测环境

- **包管理器**：`pnpm-lock.yaml` → pnpm；`yarn.lock` → yarn；`bun.lockb` → bun；否则 npm。后续所有命令都使用该包管理器（`pnpm` / `yarn` / `npm run` / `bunx`）。
- **packages 根目录**：如果存在 `src/` 则使用 `src/packages`，否则使用 `packages`。如果仓库已经有明显不同的约定，请与用户确认。
- **已有配置**：检查是否存在 `.dependency-cruiser.*` 文件。若已有，**不要覆盖**：把四条规则与 options 合并进去，并告知用户你新增了什么。

**完成条件：**包管理器、packages 根目录、是否有已有配置：这三项都已确认。

### 2. 安装 dependency-cruiser

使用上面探测到的包管理器，把 `dependency-cruiser` 安装为 devDependency。

**完成条件：**`dependency-cruiser` 已出现在 `devDependencies` 中。

### 3. 写入配置

将 [`dependency-cruiser.config.cjs`](./dependency-cruiser.config.cjs) 复制到仓库根目录，命名为 `.dependency-cruiser.cjs`。把 `PACKAGES_ROOT` 设置为步骤 1 探测到的根目录。规则是基于路径深度且与扩展名无关的，所以不需要做其他适配。

The rest: https://github.com/devcxl/mattpocock-skills-zh/blob/HEAD/skills/in-progress/setup-ts-deep-modules/SKILL.md
