Ch2. Workspace 설계와 프로토콜
Yarn/pnpm workspace protocol, 패키지 간 참조, tsconfig 공유 전략
Workspace 프로토콜
패키지 매니저의 workspace 프로토콜은 모노레포 내 패키지를 로컬에서 직접 연결합니다.
| 프로토콜 | 동작 | 사용 시점 |
|---|---|---|
workspace:* | 로컬에 있으면 항상 로컬 사용, 없으면 에러 | 내부 패키지 (권장) |
workspace:^ | 로컬 우선, publish 시 ^버전으로 치환 | 외부 publish 예정 패키지 |
workspace:~ | 로컬 우선, publish 시 ~버전으로 치환 | 패치만 허용할 때 |
// apps/web/package.json
{
"dependencies": {
"@acme/ui": "workspace:*", // 항상 로컬
"@acme/utils": "workspace:*",
"@acme/types": "workspace:*"
}
}workspace:* vs 버전 고정
"@acme/ui": "0.1.0"처럼 버전을 고정하면 Yarn은 npm 레지스트리에서 패키지를 찾습니다.
내부 패키지는 반드시 workspace:*를 사용하세요.
패키지 exports 설계
// packages/ui/package.json
{
"name": "@acme/ui",
"private": true,
"type": "module",
"exports": {
".": {
"types": "./src/index.ts",
"default": "./src/index.ts"
},
"./button": {
"types": "./src/button.tsx",
"default": "./src/button.tsx"
},
"./styles.css": "./dist/styles.css"
},
"files": ["src", "dist"]
}핵심 결정: 내부 전용 패키지는 빌드 없이 소스를 직접 export합니다. Next.js의 transpilePackages나 Turborepo의 --filter가 소스를 직접 처리하므로, 중간 빌드 단계가 불필요합니다.
tsconfig 상속 체계
packages/tsconfig/
├── base.json # 공통 strict 옵션
├── nextjs.json # Next.js 앱용 (extends base)
├── library.json # 패키지용 (extends base)
└── package.json// packages/tsconfig/base.json
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "bundler",
"module": "esnext",
"target": "es2022",
"isolatedModules": true,
"resolveJsonModule": true,
"verbatimModuleSyntax": true
}
}// apps/web/tsconfig.json
{
"extends": "@acme/tsconfig/nextjs.json",
"compilerOptions": {
"plugins": [{ "name": "next" }]
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}ESLint/Prettier 공유
// packages/eslint-config/package.json
{
"name": "@acme/eslint-config",
"private": true,
"exports": {
"./base": "./base.js",
"./next": "./next.js",
"./library": "./library.js"
}
}각 앱은 자신에게 맞는 preset만 import합니다:
// apps/web/eslint.config.js
import nextConfig from '@acme/eslint-config/next';
export default [...nextConfig];신규 패키지 추가 체크리스트
1. packages/{name}/ 디렉토리 생성
2. package.json — name: @org/{name}, private: true, exports 필드
3. tsconfig.json — extends: @org/tsconfig/library
4. src/index.ts — 배럴 export
5. 루트 package.json — workspaces 패턴에 포함 확인
6. 사용할 앱의 package.json — workspace:* 의존성 추가
7. turbo.json — 필요 시 태스크 추가
8. yarn install 실행 (심링크 갱신)