# Shared Layer **Shared**는 애플리케이션의 기반을 형성하는 레이어입니다. 외부 세계(백엔드, 서드파티 라이브러리, 환경)와의 연결을 생성하고, 높은 응집력을 가진 자체 라이브러리를 정의하는 곳입니다. ## 목적 - 외부 시스템 및 라이브러리와의 통합 - 프로젝트 전체에서 사용되는 공통 코드 제공 - 비즈니스 로직이 없는 재사용 가능한 유틸리티 및 UI 제공 - 글로벌 설정 및 환경 변수 관리 ## 특징 - **슬라이스 없음**: Shared 레이어는 비즈니스 도메인이 없으므로 슬라이스로 나뉘지 않습니다 - **세그먼트 구성**: 기술적 목적에 따라 세그먼트로 직접 구성됩니다 - **자유로운 import**: Shared 내의 모든 파일은 서로를 참조하고 import할 수 있습니다 ## 구조 ``` shared/ ├── ui/ # 애플리케이션 UI Kit │ ├── button/ │ ├── input/ │ ├── modal/ │ └── index.ts ├── api/ # API 클라이언트 및 백엔드 엔드포인트 함수 │ ├── client.ts │ └── index.ts ├── lib/ # 내부 라이브러리 모음 │ ├── dates/ # 날짜 관련 유틸리티 │ ├── colors/ # 색상 관련 유틸리티 │ ├── text/ # 텍스트 처리 유틸리티 │ └── index.ts ├── config/ # 환경 변수, 글로벌 feature flags │ ├── env.ts │ └── index.ts ├── types/ # 공통 타입 정의 │ └── index.ts ├── i18n/ # 번역 설정, 글로벌 번역 문자열 │ └── index.ts └── routes/ # 라우트 상수 또는 패턴 └── index.ts ``` ## 세그먼트 설명 ### 📁 ui 애플리케이션의 UI Kit로, 비즈니스 로직을 포함하지 않는 재사용 가능한 UI 컴포넌트들입니다. - Button, Input, Modal 같은 기본 컴포넌트 - 비즈니스 로직은 없지만 UI 로직은 포함 가능 (예: Autocomplete, SearchBar) - 비즈니스 테마 컴포넌트도 허용 (예: 회사 로고, 페이지 레이아웃) ### 📁 api API 클라이언트 및 특정 백엔드 엔드포인트 요청 함수입니다. - HTTP 클라이언트 설정 (Axios, Fetch 등) - 인증 인터셉터 - 공통 에러 핸들링 ### 📁 lib 내부 라이브러리 모음으로, 각 라이브러리는 **하나의 관심사**에 집중해야 합니다. > ⚠️ **중요**: `helpers`나 `utils` 폴더처럼 덤프 폴더로 만들지 마세요. 각 라이브러리는 명확한 초점 영역(예: dates, colors, text)을 가져야 하며, README로 문서화해야 합니다. ### 📁 config 환경 변수, 글로벌 feature flags 및 앱 전체 설정입니다. ### 📁 types 프로젝트 전체에서 사용되는 공통 타입 정의입니다. ### 📁 i18n 번역 설정 코드 및 글로벌 번역 문자열입니다. ### 📁 routes 라우트 상수 또는 라우트 매칭 패턴입니다. ## 예시 ```typescript // shared/ui/button/button.tsx interface ButtonProps { children: React.ReactNode; variant?: 'primary' | 'secondary'; onClick?: () => void; } export function Button({ children, variant = 'primary', onClick }: ButtonProps) { return ( ); } // shared/api/client.ts import axios from 'axios'; export const apiClient = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_URL, timeout: 10000, }); // shared/lib/dates/format-date.ts import dayjs from 'dayjs'; export function formatDate(date: Date, format: string = 'YYYY-MM-DD'): string { return dayjs(date).format(format); } // shared/config/env.ts export const ENV = { apiUrl: process.env.NEXT_PUBLIC_API_URL!, isDev: process.env.NODE_ENV === 'development', } as const; ``` ## 레이어 의존성 규칙 ✅ **허용되는 의존성**: - 같은 `shared` 레이어 내의 다른 세그먼트 (자유로운 cross-import) - 외부 라이브러리 및 패키지 ❌ **금지된 의존성**: - `entities` 레이어 - `features` 레이어 - `widgets` 레이어 - `pages` 레이어 - `app` 레이어 > 💡 **원칙**: Shared는 가장 낮은 레이어이므로 상위 레이어에 의존하지 않습니다. ## 세그먼트 명명 규칙 세그먼트 이름은 **내용의 목적**을 설명해야 하며, **본질**을 설명하면 안 됩니다. ❌ **나쁜 예시**: `components`, `hooks`, `types` (본질을 설명) ✅ **좋은 예시**: `ui`, `api`, `lib/dates`, `config` (목적을 설명) ## 주의사항 1. **비즈니스 로직 없음**: Shared는 순수한 기술적 코드만 포함 2. **높은 재사용성**: 앱 전체에서 사용될 수 있어야 함 3. **명확한 라이브러리 구조**: `lib` 내부는 관심사별로 명확하게 분리 4. **문서화**: 각 라이브러리는 README로 사용법과 목적을 문서화