Skip to content

프로젝트 디렉토리 구성

dictionary-app 프로젝트의 실제 디렉토리 구조를 예시로 삼는다.

  1. 디렉토리 이름은 소문자를 사용하며 단어 사이 구분은 하이픈(-)을 쓴다. 언더바(_)는 허용하지 않는다.
  2. index.ts 파일로 디렉토리 안의 컴포넌트/하위 디렉토리를 export한다. export 경로는 확장자 없이 작성한다(export * from './Domain').
  3. 외부에서 임포트할 때는 @/utils처럼 최상위 디렉토리 별칭(barrel)만으로 참조한다.
  4. 단, 이 최상위 배럴은 그 디렉토리 바깥에서 가져올 때만 쓴다. hooks/utils/components처럼 배럴이 여러 하위 파일을 재-export하는 디렉토리 내부에서 같은 디렉토리의 다른 파일을 참조할 때는 상대 경로나 더 좁은 하위 배럴(../apis, ./stores)로 직접 가져온다 — 자기 배럴을 되돌아 가져오면 순환 참조와 불필요한 번들 그래프 확장이 생긴다.
  5. 디렉토리가 필요할 경우에만 생성한다. 비어 있는 디렉토리는 만들지 않는다.
  • Directorysrc/
    • main.tsx 엔트리 포인트
    • App.tsx 루트 컴포넌트
    • Directorycomponents/ 컴포넌트(Atomic Design)
      • …
    • Directoryhooks/ 커스텀 훅
      • …
    • Directorylayout/ 레이아웃
      • …
    • Directorypages/ 페이지
      • …
    • Directoryroutes/ 라우팅 설정
      • …
    • Directorytheme/ 테마
      • …
    • Directorytypes/ 공통 타입
      • …
    • Directoryutils/ 공통 함수
      • …
    • index.css

routes/, theme/, types/, utils/는 내부 구성에 별도 규칙을 두지 않고 자유롭게 생성한다. 단, 위 디렉토리 공통 규칙(index.ts 배럴, @/ 최상위 import)은 동일하게 적용한다.

  • Directorycomponents/
    • Directoryatoms/ 최소 단위 컴포넌트(버튼, 인풋, 아이콘 등)
      • Directorybutton/
        • Button.tsx
        • StyledButton.ts
        • index.ts
      • index.ts
    • Directorymolecules/ atom을 조합한 재사용 단위(검색창, 폼 필드, 모달 등)
      • Directorymodal/
        • Modal.tsx
        • index.ts
      • index.ts
    • Directoryorganisms/ atom·molecule을 조합한 독립 UI 영역(헤더, 그리드, 토스터 등)
      • Directorydata-grid/
        • DataGrid.tsx
        • index.ts
      • index.ts
    • index.ts
  1. atoms/molecules/organisms 하위에는 컴포넌트마다 디렉토리를 만들고, 그 안에 컴포넌트 파일(ComponentName.tsx)과 index.ts를 둔다.
  2. 컴포넌트 디렉토리 이름은 컴포넌트 이름(파스칼 케이스)을 케밥 케이스로 변환한 이름을 쓴다(DataGrid → data-grid).
  3. 컴포넌트 디렉토리의 index.ts는 해당 컴포넌트만 export한다.
  4. 별도 스타일이 필요하면 같은 디렉토리에 Styled{컴포넌트 이름}.ts를 둔다.
  • Directoryhooks/
    • Directoryapis/ 백엔드 연결 훅 (Api 접미사, 예: useMenuApi)
      • index.ts
    • Directoryqueries/ react-query 조회(useQuery) 훅 (Query 접미사, 예: useMenuRootQuery)
      • index.ts
    • Directorymutations/ react-query 저장(useMutation) 훅 (Mutation 접미사, 예: useDomainSaveMutation)
      • index.ts
    • Directorystores/ zustand 스토어 훅 (Store 접미사, 예: useSpinnerStore)
      • index.ts
    • useApi.ts 별도 디렉토리로 분류되지 않는 공통 훅
    • index.ts
  1. apis/queries/mutations/stores에는 여러 기능이 공유하는 공통 훅이 위치한다. 특정 페이지에서만 쓰는 훅은 해당 페이지 디렉토리 하위에 동일한 형식으로 둔다(아래 페이지 디렉토리 참고).
  2. 훅 함수명은 use로 시작한다.
  3. apis/queries/mutations/stores 디렉토리에 위치하는 훅은 소속 디렉토리를 나타내는 접미사를 이름 끝에 붙인다 — 이 규칙은 공통 훅과 페이지 전용 훅 모두 동일하게 적용된다.
    • apis: Api 접미사(useAuthApi, useMenuApi)
    • queries: Query 접미사(useMenuRootQuery, useMenuChildQuery)
    • mutations: Mutation 접미사(useDomainSaveMutation, useDictionaryDeleteMutation)
    • stores: Store 접미사(useSideMenuStore, useSpinnerStore)
  4. queries(조회)와 mutations(저장)를 분리하는 이유는 백엔드 API 사용 예제 참고.
  • Directorypages/word/domain/
    • Directorycomponents/ 페이지 전용 하위 컴포넌트
      • DomainFormModal.tsx
      • index.ts
    • Directoryapis/ 페이지 전용 백엔드 연결 훅
      • useDomainApi.ts
      • index.ts
    • Directoryqueries/ 페이지 전용 조회 훅
      • useDomainListQuery.ts
      • index.ts
    • Directorymutations/ 페이지 전용 저장 훅
      • useDomainSaveMutation.ts
      • index.ts
    • Directorymodels/ 페이지 전용 타입
      • DomainFilter.ts
      • index.ts
    • useDomain.ts 페이지 전용 커스텀 훅(상수·헬퍼 포함)
    • Domain.tsx 페이지 컴포넌트
    • StyledDomain.ts
    • index.ts 페이지 컴포넌트만 export
  1. 페이지 경로는 메뉴 구조와 동일하게 중첩될 수 있다(pages/word/domain).
  2. 페이지 전용 하위 컴포넌트/apis/queries/mutations/stores는 각각 페이지 디렉토리 하위의 동일한 이름 디렉토리에 위치하며, 공통 훅과 동일하게 훅마다 파일을 나누고 index.ts가 재-export한다.
  3. 페이지 전용 타입은 types가 아니라 models 디렉토리에 둔다 — 최상위 @/types(생성된 API 스키마, 공용 인프라 타입)와 이 페이지에서만 쓰는 업무 모델(검색조건 타입 등)을 위치만으로 구분하기 위해서다.
  4. 페이지 전용 커스텀 훅(useDomain.ts)은 페이지 디렉토리에 바로 위치하며, 상수·헬퍼 메소드를 함께 정의한다.
  5. 페이지 스타일 파일명은 Styled{페이지 컴포넌트 이름}.ts.
  6. 페이지 디렉토리의 index.ts는 페이지 컴포넌트만 export한다 — 하위 컴포넌트/훅은 페이지 안에서만 쓰이므로 외부에 노출하지 않는다.
  • Directorylayout/
    • Directoryapp-layout/
      • AppLayout.tsx
      • index.ts
    • Directoryheader/
      • Header.tsx
      • index.ts
    • Directoryside-menu/
      • SideMenu.tsx
      • index.ts
    • Directorycontent/
      • Content.tsx
      • index.ts
    • Directoryfooter/
      • Footer.tsx
      • index.ts
    • index.ts

app-layout이 전체 레이아웃을 정의한다 — 왼쪽에 side-menu, 오른쪽에 header → content → footer가 세로로 순서대로 위치한다.