# App Layer **App**은 애플리케이션 전체에 영향을 미치는 기술적, 비즈니스적 사항을 다루는 최상위 레이어입니다. ## 목적 - 애플리케이션의 진입점(entrypoint) 제공 - 전역 Context Providers 설정 - 라우터 구성 - 글로벌 스타일 정의 - 전역 상태 저장소 설정 - 애널리틱스 및 모니터링 설정 ## 특징 - **슬라이스 없음**: App 레이어는 Shared처럼 슬라이스가 없고 세그먼트로만 구성됩니다 - **전체 앱 관심사**: 특정 비즈니스 도메인이 아닌 앱 전체와 관련된 코드만 포함 - **최상위 레이어**: 모든 하위 레이어의 모듈을 자유롭게 import 가능 ## 구조 (Next.js App Router) Next.js를 사용하는 경우, App 레이어는 주로 `app/` 디렉토리로 표현됩니다: ``` app/ ├── (routes)/ # 라우트 그룹 및 페이지 │ ├── (auth)/ │ │ ├── login/ │ │ │ └── page.tsx │ │ └── register/ │ │ └── page.tsx │ └── (main)/ │ ├── dashboard/ │ │ └── page.tsx │ └── settings/ │ └── page.tsx ├── layout.tsx # 루트 레이아웃 ├── page.tsx # 홈 페이지 ├── globals.css # 글로벌 스타일 ├── providers.tsx # 전역 Providers 설정 └── error.tsx # 글로벌 에러 핸들러 ``` ### 일반적인 FSD 세그먼트 구조 FSD 표준 세그먼트를 사용하는 경우: ``` app/ ├── entrypoint/ # 애플리케이션 진입점 (프레임워크별) │ └── index.tsx ├── providers/ # Context Providers │ ├── query-provider.tsx │ ├── theme-provider.tsx │ └── index.tsx ├── styles/ # 글로벌 스타일 │ ├── globals.css │ └── theme.css ├── store/ # 글로벌 상태 저장소 설정 │ └── index.ts └── routes/ # 라우터 설정 └── index.tsx ``` ## 예시 ### Next.js Providers 설정 ```typescript // app/providers.tsx 'use client'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { ThemeProvider } from 'next-themes'; import { useState } from 'react'; export function Providers({ children }: { children: React.ReactNode }) { const [queryClient] = useState(() => new QueryClient({ defaultOptions: { queries: { staleTime: 60 * 1000, }, }, })); return ( {children} ); } // app/layout.tsx import { Providers } from './providers'; import './globals.css'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( {children} ); } ``` ### 글로벌 설정 ```typescript // app/config/analytics.ts export function initAnalytics() { if (typeof window !== 'undefined') { // 애널리틱스 초기화 } } // app/config/monitoring.ts export function initMonitoring() { // 에러 모니터링 설정 } ``` ## Next.js App Router와 FSD Next.js의 `app/` 디렉토리는 FSD의 **App 레이어**와 **Pages 레이어**를 동시에 담당합니다: - **루트 레벨 파일들** (`layout.tsx`, `providers.tsx`, `globals.css`): App 레이어 - **라우트 폴더들** (`dashboard/`, `login/` 등): Pages 레이어 각 페이지별 비즈니스 로직은: - 재사용되지 않는 UI는 페이지 슬라이스(`app/dashboard/` 등) 안에 유지 - 재사용되는 기능은 `features/` 레이어로 분리 - 여러 페이지에서 재사용되는 큰 UI 블록은 `widgets/` 레이어로 분리 ## 레이어 의존성 규칙 ✅ **허용되는 의존성**: - 모든 하위 레이어 (`pages`, `widgets`, `features`, `entities`, `shared`) - 같은 `app` 레이어 내의 다른 세그먼트 - 외부 라이브러리 ❌ **금지된 의존성**: - 없음 (App은 최상위 레이어) ## 주의사항 1. **비대화 방지**: App 레이어가 너무 커지면 관리가 어려워집니다. 대부분의 로직은 하위 레이어에 배치하세요 2. **전역 관심사만**: 특정 페이지나 기능에만 관련된 코드는 해당 레이어로 이동 3. **라우터 레벨 로직**: 라우터 및 서버 레벨 로직은 이 레이어에 유지 4. **Processes 레이어 사용 지양**: Processes 레이어는 deprecated되었으므로 해당 로직은 `app`이나 `features`에 배치 ## FSD v2.1 권장사항 최신 FSD 버전(v2.1)은 **"pages-first"** 접근 방식을 권장합니다: - 더 많은 코드를 페이지 슬라이스에 유지 - 큰 UI 블록과 재사용되지 않는 비즈니스 로직은 즉시 추출하지 말고 페이지에 보관 - 실제로 재사용이 필요할 때만 `features`나 `widgets`로 분리 이 접근 방식은 과도한 추상화를 방지하고 코드를 더 쉽게 탐색할 수 있게 합니다.