프로젝트 디렉토리 구성
dictionary-app 프로젝트의 실제 디렉토리 구조를 예시로 삼는다.
디렉토리 공통 규칙
Section titled “디렉토리 공통 규칙”- 디렉토리 이름은 소문자를 사용하며 단어 사이 구분은 하이픈(
-)을 쓴다. 언더바(_)는 허용하지 않는다. index.ts파일로 디렉토리 안의 컴포넌트/하위 디렉토리를 export한다. export 경로는 확장자 없이 작성한다(export * from './Domain').- 외부에서 임포트할 때는
@/utils처럼 최상위 디렉토리 별칭(barrel)만으로 참조한다. - 단, 이 최상위 배럴은 그 디렉토리 바깥에서 가져올 때만 쓴다.
hooks/utils/components처럼 배럴이 여러 하위 파일을 재-export하는 디렉토리 내부에서 같은 디렉토리의 다른 파일을 참조할 때는 상대 경로나 더 좁은 하위 배럴(../apis,./stores)로 직접 가져온다 — 자기 배럴을 되돌아 가져오면 순환 참조와 불필요한 번들 그래프 확장이 생긴다. - 디렉토리가 필요할 경우에만 생성한다. 비어 있는 디렉토리는 만들지 않는다.
최상위 디렉토리 구조
Section titled “최상위 디렉토리 구조”Directorysrc/
- main.tsx 엔트리 포인트
- App.tsx 루트 컴포넌트
Directorycomponents/ 컴포넌트(Atomic Design)
- …
Directoryhooks/ 커스텀 훅
- …
Directorylayout/ 레이아웃
- …
Directorypages/ 페이지
- …
Directoryroutes/ 라우팅 설정
- …
Directorytheme/ 테마
- …
Directorytypes/ 공통 타입
- …
Directoryutils/ 공통 함수
- …
- index.css
routes/, theme/, types/, utils/는 내부 구성에 별도 규칙을 두지 않고 자유롭게 생성한다. 단, 위
디렉토리 공통 규칙(index.ts 배럴, @/ 최상위 import)은 동일하게 적용한다.
컴포넌트 디렉토리 (Atomic Design)
Section titled “컴포넌트 디렉토리 (Atomic Design)”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
- atoms/molecules/organisms 하위에는 컴포넌트마다 디렉토리를 만들고, 그 안에 컴포넌트 파일(
ComponentName.tsx)과index.ts를 둔다. - 컴포넌트 디렉토리 이름은 컴포넌트 이름(파스칼 케이스)을 케밥 케이스로 변환한 이름을 쓴다(
DataGrid→data-grid). - 컴포넌트 디렉토리의
index.ts는 해당 컴포넌트만 export한다. - 별도 스타일이 필요하면 같은 디렉토리에
Styled{컴포넌트 이름}.ts를 둔다.
커스텀 훅 디렉토리
Section titled “커스텀 훅 디렉토리”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
apis/queries/mutations/stores에는 여러 기능이 공유하는 공통 훅이 위치한다. 특정 페이지에서만 쓰는 훅은 해당 페이지 디렉토리 하위에 동일한 형식으로 둔다(아래 페이지 디렉토리 참고).- 훅 함수명은
use로 시작한다. apis/queries/mutations/stores디렉토리에 위치하는 훅은 소속 디렉토리를 나타내는 접미사를 이름 끝에 붙인다 — 이 규칙은 공통 훅과 페이지 전용 훅 모두 동일하게 적용된다.apis:Api접미사(useAuthApi,useMenuApi)queries:Query접미사(useMenuRootQuery,useMenuChildQuery)mutations:Mutation접미사(useDomainSaveMutation,useDictionaryDeleteMutation)stores:Store접미사(useSideMenuStore,useSpinnerStore)
queries(조회)와mutations(저장)를 분리하는 이유는 백엔드 API 사용 예제 참고.
페이지 디렉토리
Section titled “페이지 디렉토리”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
- 페이지 경로는 메뉴 구조와 동일하게 중첩될 수 있다(
pages/word/domain). - 페이지 전용 하위 컴포넌트/
apis/queries/mutations/stores는 각각 페이지 디렉토리 하위의 동일한 이름 디렉토리에 위치하며, 공통 훅과 동일하게 훅마다 파일을 나누고index.ts가 재-export한다. - 페이지 전용 타입은
types가 아니라models디렉토리에 둔다 — 최상위@/types(생성된 API 스키마, 공용 인프라 타입)와 이 페이지에서만 쓰는 업무 모델(검색조건 타입 등)을 위치만으로 구분하기 위해서다. - 페이지 전용 커스텀 훅(
useDomain.ts)은 페이지 디렉토리에 바로 위치하며, 상수·헬퍼 메소드를 함께 정의한다. - 페이지 스타일 파일명은
Styled{페이지 컴포넌트 이름}.ts. - 페이지 디렉토리의
index.ts는 페이지 컴포넌트만 export한다 — 하위 컴포넌트/훅은 페이지 안에서만 쓰이므로 외부에 노출하지 않는다.
layout 디렉토리
Section titled “layout 디렉토리”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가
세로로 순서대로 위치한다.