Files
2nd/00_Raw/Folder Structure.md
T

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

[아키텍처/기반 기술]

  • 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