5.3 KiB
5.3 KiB
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 설정
// 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>
);
}
글로벌 설정
// 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은 최상위 레이어)
주의사항
- 비대화 방지: App 레이어가 너무 커지면 관리가 어려워집니다. 대부분의 로직은 하위 레이어에 배치하세요
- 전역 관심사만: 특정 페이지나 기능에만 관련된 코드는 해당 레이어로 이동
- 라우터 레벨 로직: 라우터 및 서버 레벨 로직은 이 레이어에 유지
- Processes 레이어 사용 지양: Processes 레이어는 deprecated되었으므로 해당 로직은
app이나features에 배치
FSD v2.1 권장사항
최신 FSD 버전(v2.1)은 "pages-first" 접근 방식을 권장합니다:
- 더 많은 코드를 페이지 슬라이스에 유지
- 큰 UI 블록과 재사용되지 않는 비즈니스 로직은 즉시 추출하지 말고 페이지에 보관
- 실제로 재사용이 필요할 때만
features나widgets로 분리
이 접근 방식은 과도한 추상화를 방지하고 코드를 더 쉽게 탐색할 수 있게 합니다.