10 KiB
Folder Structure
📌 Brief Summary
폴더 구조(Folder Structure)는 소프트웨어 프로젝트 내에서 파일과 디렉터리를 논리적으로 조직하는 아키텍처적 기반을 의미합니다 [1, 2]. 최신 프론트엔드 개발에서는 단순한 파일 유형 기반(File-Type Based) 구조의 한계를 극복하기 위해, 비즈니스 도메인이나 기능(Feature)을 중심으로 모듈화하는 방향으로 진화해 왔습니다 [3, 4]. 잘 설계된 폴더 구조는 애플리케이션의 유지보수성, 확장성, 팀 협업 효율을 극대화하고 기술 부채를 줄이는 데 핵심적인 역할을 합니다 [2, 5-9].
📖 Core Content
- 기존 구조의 한계와 진화: 과거에는 컴포넌트, 훅, 스타일 등을 각각의 기술적 파일 유형별 폴더에 모아두는 방식(File-Type Based Structure)을 주로 사용했습니다 [3, 10]. 이 방식은 소규모 앱에서는 설정이 직관적이지만, 애플리케이션이 커질수록 하나의 기능을 수정하기 위해 여러 폴더를 탐색해야 하므로 개발자의 인지 부하를 높이고 스파게티 코드를 유발합니다 [3, 10].
- 기능 기반 조직(Feature-Based Organization): 2025년 현재 업계 표준은 비즈니스 기능(도메인)을 중심으로 코드를 구성하는 방식입니다 [4, 11].
src/features/디렉터리 하위에 특정 기능(예: 인증, 대시보드)과 관련된 컴포넌트, 훅, API 로직, 타입을 모아두어 높은 응집도와 모듈 독립성을 확보합니다 [11, 12]. - 권장되는 하이브리드 폴더 구조: 대규모 확장이 가능한 React 프로젝트는 파일 유형과 기능을 결합한 하이브리드 디렉터리 구조를 권장합니다 [13]. 대표적인
src/하위 구성은 다음과 같습니다:assets/: 이미지, 폰트 등 여러 기능에서 공유되는 정적 미디어 리소스 [13, 14].components/: 버튼, 모달 등 도메인에 종속되지 않고 재사용되는 공통 UI 컴포넌트 [11, 14, 15].features/: 도메인별 특정 비즈니스 로직 및 UI가 캡슐화된 모듈 [11, 12, 15].pages/(또는routes/): 라우팅에 매핑되는 페이지 레벨 컴포넌트 [16, 17].hooks/,services/,utils/: 공통 커스텀 훅, 외부 API 통신 및 비즈니스 로직, 헬퍼 함수 [12, 17-20].store/(또는context/): 전역 상태 관리 로직 [16-18].
- Feature-Sliced Design (FSD): 기능 기반 구조를 더 엄격한 아키텍처 방법론으로 발전시킨 형태입니다 [21, 22]. 코드를
app,pages,widgets,features,entities,shared라는 명확한 계층(Layer)으로 나눕니다 [23, 24]. 상위 계층이 하위 계층에만 의존할 수 있다는 단방향 의존성 규칙을 강제하여 순환 참조와 아키텍처의 붕괴를 막습니다 [22, 23]. - 네이밍 컨벤션과 거버넌스: 폴더 구조는 엄격한 명명 규칙과 결합될 때 효과적입니다. 운영체제 간(Windows/Mac vs Linux) 대소문자 구분 문제로 인한 CI/CD 빌드 실패를 막기 위해 파일과 폴더명은 주로
kebab-case를 사용하며, React 컴포넌트 명칭은PascalCase를 사용하는 것이 표준입니다 [25-30]. Next.js에서는(folderName)형태를 사용하여 URL 경로에 영향을 주지 않고 논리적으로 라우트를 그룹화하는 패턴도 활용됩니다 [31, 32].
⚖️ Trade-offs & Caveats
기능 기반(Feature-based) 구조나 Feature-Sliced Design(FSD)과 같은 고도화된 폴더 구조는 소규모 프로젝트나 초보자에게는 과도한 오버헤드(Overkill)가 될 수 있습니다 [33]. 단순한 앱에 적용할 경우 불필요한 하위 폴더와 중복된 구조를 무수히 생성하게 되어 오히려 개발 속도를 저하시킬 수 있습니다 [33].
특히 FSD 구조를 도입할 경우, 특정 모듈이 어느 계층에 속해야 하는지("이 모듈이 feature인가 widget인가?")를 결정하는 데 있어 의미론적 논쟁과 인지적 오버헤드가 발생합니다 [34]. 또한, 팀 전체가 이 방법론과 계층 규칙을 명확히 이해하고 문서화하지 않으면, 개발자들이 규칙을 무시하고 모든 코드를 최하단인 shared 폴더에 쏟아부어 오히려 버그를 양산하고 코드 변경 시의 영향 범위(Blast radius)를 통제 불능으로 만들 위험이 큽니다 [34, 35].
추가로, 모듈 내부를 캡슐화하기 위해 진입점을 하나로 통일하는 배럴 파일(Barrel files, 예: index.ts를 통한 Public API 노출) 패턴은 내부 리팩토링을 안전하게 만들어주지만, 번들링(Bundling)이나 트리 쉐이킹(Tree-shaking) 과정에서 원치 않는 모듈까지 불러와 성능상 불이익을 초래할 수 있다는 단점이 존재합니다 [34, 36, 37].
🔗 Knowledge Connections
Related Concepts
[아키텍처/기반 기술]
- Feature-Sliced Design
- 연결 이유: Folder Structure를 단순한 디렉터리 분리가 아닌, 계층(Layer)과 슬라이스(Slice) 기반의 엄격한 아키텍처 방법론으로 승격시킨 개념이기 때문입니다 [21-24].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 단방향 의존성 원칙과 모듈 캡슐화를 통해 대규모 React 앱이 어떻게 스파게티 코드를 방지하는지 이해할 수 있습니다 [23, 37].
- Separation of Concerns
- 연결 이유: Folder Structure를 UI 렌더링, 비즈니스 로직, 상태 관리 등으로 나누는 핵심 소프트웨어 공학 원리입니다 [8, 30].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 왜
components/와services/,store/폴더를 분리해야 하는지 그 근본적인 이유를 알 수 있습니다 [30].
- Domain-Driven Design
- 연결 이유: 프론트엔드 코드의 폴더를 기술적 유형이 아닌 비즈니스 도메인(기능) 중심으로 나누는 데 논리적 기반을 제공합니다 [12, 38].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분:
features/폴더 내에 코드를 응집시키는 것이 비즈니스 요구사항 변화에 어떻게 유연하게 대처하게 하는지 파악할 수 있습니다 [38].
[구현/활용 도구]
- Naming Conventions
- 연결 이유: 일관된 명명 규칙은 폴더 구조의 가독성과 예측 가능성을 완성하는 필수 요소입니다 [25, 26, 30, 39].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 왜 폴더명은
kebab-case를 쓰고 컴포넌트는PascalCase를 써야 CI/CD 파이프라인에서 오류가 나지 않는지 이해할 수 있습니다 [25, 40].
- State Management
- 연결 이유: 폴더 구조에서 전역 상태(
store/,context/)와 지역/기능 상태(features/)를 어디에 위치시킬지 결정하는 핵심 요소입니다 [16, 18, 19, 41, 42]. - 이 개념을 통해 더 깊게 이해할 수 있는 부분: Zustand, Context API 등 관리 도구에 따라 전역 인프라 상태와 도메인 상태를 분리 배치하는 전략을 학습할 수 있습니다 [43].
- 연결 이유: 폴더 구조에서 전역 상태(
Deeper Research Questions
- Feature-Sliced Design(FSD)에서 하위 계층이 상위 계층을 참조하지 못하도록 ESLint 규칙을 통해 어떻게 단방향 의존성을 강제할 수 있는가?
- 배럴 파일(
index.ts)을 이용한 Public API 패턴이 Webpack이나 Vite의 트리 쉐이킹(Tree-shaking) 최적화에 미치는 정확한 부작용과 그 해결책은 무엇인가? - '인증(Auth)'과 같이 애플리케이션 전반에 걸쳐 사용되는 교차 절단 관심사(Cross-cutting concerns)는 기능 기반(Feature-based) 폴더 구조에서 어떻게 분리하고 배치해야 코드 응집도를 잃지 않는가?
- 소규모 프로젝트(Flat structure)에서 대규모 프로젝트(Feature-Sliced Design)로 폴더 구조를 마이그레이션해야 하는 구체적인 임계점(컴포넌트 수, 팀 규모 등)이나 코드 스멜 지표는 무엇인가?
- Next.js의 App Router에서 제공하는 Route Grouping
(folder)문법과 기존의 기능 기반 폴더 분리(features/) 패턴을 어떻게 충돌 없이 조화롭게 설계할 수 있는가?
Practical Application Contexts
- Implementation: 운영체제(Windows vs Linux)에 따른 대소문자 구분 이슈를 방지하기 위해 폴더와 파일명 생성 시 일관된
kebab-case를 적용하는 규칙을 프로젝트 린팅 룰에 설정합니다 [25-27]. - System Design: 프로젝트 설계 초기 단계에서
features/폴더를 정의하여 UI 요소와 비즈니스 로직의 경계를 명확히 하고, 공통 컴포넌트는 오직 Presentation 역할만 수행하도록 시스템을 구조화합니다 [11, 44]. - Operation / Maintenance: 새로운 개발자가 팀에 합류했을 때, 기능별로 고립된 폴더 구조를 통해 전체 코드를 파악하지 않고도 자신이 맡은 도메인(
features/auth등)만 분석하여 즉시 유지보수 업무에 투입될 수 있도록 돕습니다 [6]. - Learning Path: 처음 React를 학습할 때는 Flat 구조로 시작하여 기본기를 익히고, 프로젝트가 커짐에 따라 File-Type Based 구조를 거쳐 최종적으로 Feature-Based 또는 FSD 아키텍처로 진화하는 순차적 학습이 권장됩니다 [4, 9, 10, 33].
- My Project Relevance: 현재 진행 중인 또는 계획된 React 프로젝트의 규모와 팀원의 숙련도를 평가하여, 지나치게 복잡한 FSD를 바로 도입하기보다는
features/와components/를 결합한 하이브리드 방식을 적용해 점진적인 모듈화를 시도하는 지표로 삼을 수 있습니다.
Adjacent Topics
- Code Splitting
- 확장 방향: 폴더 구조를 라우트나 기능 단위로 명확히 나누면, Vite나 Webpack을 이용해 해당 모듈들을 독립적인 청크(Chunk)로 나누어 지연 로딩(Lazy Loading)하는 최적화 전략으로 자연스럽게 확장할 수 있습니다 [45, 46].
- Micro-Frontends
- 확장 방향: 모놀리식 단일 폴더 구조가 감당할 수 없을 만큼 거대해진 엔터프라이즈 환경에서, 아예 독립적으로 배포 및 운영 가능한 프론트엔드 애플리케이션으로 분할하는 극단적 아키텍처 방법론으로 확장됩니다 [21].
Last updated: 2026-04-30