Files
frontend/apps/_template/app/README.md
T
2026-02-26 11:55:09 +09:00

170 lines
5.3 KiB
Markdown

# 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 (
<QueryClientProvider client={queryClient}>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
{children}
</ThemeProvider>
</QueryClientProvider>
);
}
// app/layout.tsx
import { Providers } from './providers';
import './globals.css';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ko">
<body>
<Providers>
{children}
</Providers>
</body>
</html>
);
}
```
### 글로벌 설정
```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`로 분리
이 접근 방식은 과도한 추상화를 방지하고 코드를 더 쉽게 탐색할 수 있게 합니다.