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를 호출하면, 에이전트가 저장소에 경계 체크를 추가하고 규칙이 실제로 위반을 차단하는지까지 확인합니다.
대상은 패키지 내부로의 직접 참조와 순환 의존성입니다.
배포처는 GitHub의 mattpocock/skills(스타 297,465)이며, 라이선스는 MIT입니다.
setup-ts-deep-modules를 사용하여 이 저장소의 패키지에 경계 체크를 추가해 주세요.
에이전트는 먼저 락 파일을 확인하여 패키지 매니저를 판별합니다.
패키지 위치는 src/가 있으면 src/packages, 없으면 packages입니다.
이어서 dependency-cruiser를 개발 의존성에 추가하고, 설정 파일 .dependency-cruiser.cjs를 저장소 루트에 배치합니다.
dependency-cruiser는 파일 간 import를 분석하여 규칙 위반을 보고하는 도구입니다.
작업이 완료되면 각 패키지는 다음 형태로 정리됩니다.
src/packages/
<name>/
index.ts ← 공개 파일(외부에서 import 가능)
client.ts ← 공개 파일은 여러 개 배치 가능
lib/ ← 구현. 외부에서 참조 불가
tests/ ← 테스트. 서브폴더이므로 비공개
아울러 lint:boundaries라는 스크립트가 추가되어, 타입 체크를 실행하는 기존 통합 명령어에 편입됩니다.
그 밖에 생성되는 것은 샘플 example 패키지와 규약을 작성한 README.md입니다.
CLAUDE.md 또는 AGENTS.md에 해당 README로의 안내를 한 줄 추가하는 것까지가 작업 범위입니다.
이 스킬의 핵심은 패키지의 공개 범위를 「직속 파일만」으로 정하고, 그 외 참조를 오류로 처리하는 것입니다.
서브폴더에 있는 것은 이름에 관계없이 모두 비공개로 취급됩니다.
폴더를 추가해도 설정을 다시 작성할 필요가 없습니다.
도입되는 규칙은 4가지이며, 모두 위반 시 오류가 됩니다.
3번째 규칙이 있으므로, 테스트도 이용자와 같은 진입점에서 동작을 확인하는 형태가 됩니다.
여러 패키지를 걸치는 통합 테스트는 작성할 수 있지만, 내부를 직접 읽는 테스트는 작성할 수 없습니다.
경계 체크는 lint:boundaries로 추가되어, 타입 체크를 실행하는 check나 ci 등의 통합 명령어에 편입됩니다.
tsconfig나 경로 별칭에는 손을 대지 않으므로, 기존 빌드 설정은 변경되지 않습니다.
통합 명령어가 없는 저장소에서는 lint:boundaries만 추가하고, CI에 포함하도록 이용자에게 안내하는 흐름입니다.
example 패키지는 새 패키지를 만들 때 복사할 견본입니다.
index.ts가 공개하는 함수는 처리를 lib/impl.ts에 맡기고, 테스트는 ../index만 import하는 구성입니다.
불필요해지면 삭제해도 되는 템플릿으로 만들어집니다.
템플릿을 만든 후, 에이전트는 규칙이 작동하는지를 3회 실행으로 확인합니다.
1회째는 위반이 없는 상태에서 통과하는 것.
2회째는 테스트에 lib/impl로의 직접 import를 일시적으로 추가하여 실패하는 것.
3회째는 원래대로 되돌려 다시 통과하는 것입니다.
2회째에서 실패하지 않으면 설정 오류로 간주하고, 작업을 마치기 전에 수정합니다.
패키지 폴더의 README.md에 정리되는 것은 구성과 4가지 규칙, lint:boundaries 실행 방법입니다.
하나의 index.ts로 하위 전체를 재내보내기하는 「배럴 파일」은 피하고, 작은 공개 파일을 여러 개 배치하도록 명시됩니다.
또한 CLAUDE.md(없으면 AGENTS.md, 둘 다 없으면 AGENTS.md를 새로 생성)에 이 README로의 안내를 한 줄 추가합니다.
이후 작업하는 에이전트가 이 한 줄에서 경계 규약을 찾아갈 수 있는 구조입니다.
설치는 명령어로 추가하는 방법과 에이전트에게 의뢰하는 방법, 두 가지입니다.
명령어의 경우 실행 시 Claude Code나 Codex 등, 설치할 에이전트를 선택할 수 있습니다.
npx skills add https://github.com/mattpocock/skills --skill setup-ts-deep-modules
에이전트에게 의뢰하는 경우, 다음 내용을 그대로 전달해 주세요.
次の 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/ に配置してください。
배치 위치는 모든 프로젝트에서 사용할지, 특정 프로젝트에서만 사용할지에 따라 달라집니다.
| 에이전트 | 모든 프로젝트에서 사용 | 특정 프로젝트에서만 사용 |
|---|---|---|
| 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.*가 있어도 에이전트는 덮어쓰지 않습니다.
4가지 규칙과 설정을 통합하고, 무엇을 추가했는지 보고합니다.
통합 후 lint:boundaries를 실행하면, 현재 코드에 있는 내부로의 직접 참조나 순환 의존성이 오류로 표시됩니다.
setup-ts-deep-modules로 복사용 example 패키지를 만들고, 위반을 감지할 수 있는지 확인해 주세요.
example/에 만들어지는 것은 index.ts, lib/impl.ts, tests/example.test.ts의 3개 파일입니다.
이어서 통과·실패·통과의 3회 실행 결과가 제시되므로, 규칙이 작동하고 있음을 그 자리에서 확인할 수 있습니다.
setup-ts-deep-modules의 절차에 따라 패키지 규약을 README에 정리하고, CLAUDE.md에서 참조할 수 있도록 해 주세요.
패키지 폴더의 README.md에는 구성 견본과 4가지 규칙이 각각 한 단락으로 작성됩니다.
CLAUDE.md에 추가되는 것은 「패키지를 추가·import하기 전에 이 README를 읽는다」는 취지의 한 줄입니다.
먼저 확인하고 싶은 것은 기존 코드에 대한 영향입니다.
4가지 규칙은 모두 오류로 처리되며, 타입 체크와 같은 명령어에 편입됩니다.
기존 코드에 내부로의 직접 참조나 순환 의존성이 있으면, 도입 시점에 통합 명령어가 실패하므로 수정할 시간을 확보해 두세요.
대상으로 하는 구성에도 전제가 있습니다.
패키지는 배치 위치 직하에 1계층으로 나열되는 형태가 전제이며, 패키지 안에 다른 패키지를 넣는 구성은 다루지 않습니다.
어떤 패키지가 어느 것에 의존해도 되는지에 관한 의존 방향 제한도 대상 외입니다.
이 부분은 설정 파일에 주석 초안으로 남겨집니다.
환경 면에서는 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처럼 여러 개 배치할 수 있습니다.
하위 전체를 재내보내기하는 배럴 파일은 피하도록 안내됩니다.
이 스킬의 대상 외입니다.
의존 방향 제한은 별도의 관심사로 취급되며, 설정 파일에 주석 초안이 남겨질 뿐입니다.
필요하다면 저장소에 맞게 직접 추가해 주세요.
setup-ts-deep-modules는 패키지의 진입점을 직속 공개 파일로 제한하고, 내부로의 직접 참조와 순환 의존성을 오류로 처리하는 스킬입니다.
작업 범위는 dependency-cruiser 도입부터, 타입 체크와의 통합, 템플릿 생성, 3회 실행을 통한 검증, 규약 문서화까지입니다.
리뷰에서의 주의력에 의존하지 않고, 구조적으로 모듈 경계를 지키고 싶은 팀에 적합합니다.
도입 전에 SKILL.md를 읽고, 기존 코드의 위반에 대응할 시간을 확보한 후 시도해 보세요.
이 글은 cccskills의 읽을거리 「TypeScriptの循環依存を防ぐ setup-ts-deep-modules」의 전재입니다.
스킬의 상세 내용과 설치 방법은 cccskills의 setup-ts-deep-modules 페이지에 있습니다.