패키지 매니저란?
프로젝트에서 사용하는 라이브러리와 의존성을 관리하는 도구.
주요 역할:
대표적인 패키지 매니저
추천:
소규모 팀: npm이나 Yarn.
대규모 팀, 모노레포: PNPM.
상태 관리는 애플리케이션의 데이터 흐름을 효율적으로 관리하기 위해 중요해. 프로젝트의 규모와 복잡도에 따라 적합한 도구와 규칙을 선택해야하고, 아래는 상태 관리를 팀에서 합의하고 정리하는 방식이야.
상태 관리란?
애플리케이션의 데이터(상태)를 저장하고, 이를 컴포넌트와 효율적으로 연결하는 방식.서버와 클라이언트 상태관리를 각각 정해서 시작하는 것이 좋음.
서버 상태 관리 도구
API 호출, 비동기 데이터 처리, 데이터 캐싱 및 동기화를 다루는 도구야.
| 도구 | 특징 | 적합한 상황 |
|---|---|---|
| React Query | - API 데이터 캐싱 및 동기화 - 자동 리페칭 - 로딩, 에러 상태를 자동 관리 | REST API 또는 GraphQL 데이터를 자주 호출하는 프로젝트. |
| Apollo Client | - GraphQL 클라이언트 - 강력한 캐싱 및 데이터 페칭 - GraphQL과 완벽한 통합 | GraphQL API를 사용하는 프로젝트. |
| SWR | - React Query와 유사 - 간단하고 가벼운 사용법 - 데이터 패칭과 캐싱에 강점 | REST API 데이터를 캐싱하고 동기화해야 하는 간단한 프로젝트. |
| Relay | - Facebook에서 만든 GraphQL 클라이언트 - GraphQL을 최적화하여 동작 - 데이터 프래그먼트 지원 | 고도로 최적화된 GraphQL API를 사용하는 대규모 프로젝트. |
| Axios | - HTTP 클라이언트로 API 호출 - 커스텀 상태 관리 가능 | 간단한 API 호출 및 상태 관리가 필요한 경우. |
| Rtk Query | - Redux Toolkit에 내장된 상태 관리 도구 - API 페칭과 캐싱을 자동화 - Redux와 통합 | Redux를 사용하는 프로젝트에서 API 관리가 필요한 경우. |
| 도구 | 특징 | 적합한 상황 |
|---|---|---|
| Redux Toolkit | - Redux의 표준화된 버전 - 전역 상태 관리와 비동기 작업 처리 - Middleware 지원 | 대규모 프로젝트나 복잡한 전역 상태를 관리해야 할 때. |
| Zustand | - 가볍고 간단한 상태 관리 도구 - React와 자연스럽게 통합 - 간결한 API | 중소규모 프로젝트에서 경량 전역 상태 관리가 필요할 때. |
| Jotai | - Atom(원자) 단위로 상태를 관리 - React Hooks와 통합 - 상태의 독립성과 확장성 제공 | 전역 상태가 많지 않은 중소규모 프로젝트. |
| Recoil | - Facebook에서 개발 - 상태를 컴포넌트 단위로 나눠 관리 - 비동기 상태 관리에 강점 | 비동기 상태나 복잡한 전역 상태를 세분화해야 하는 경우. |
| Context API | - React 내장 상태 관리 도구 - 전역 상태 공유 가능 - 외부 라이브러리 필요 없음 | 간단한 전역 상태 공유가 필요한 소규모 프로젝트. |
| MobX | - 관찰 가능한 상태와 반응형 시스템 - 코드가 간결하고 직관적 - 런타임 기반 | UI 상태를 반응형으로 처리해야 하거나, 전통적인 MVC 접근 방식을 선호할 때. |
| 특징 | 서버 상태 관리 | 클라이언트 상태 관리 |
|---|---|---|
| 데이터 위치 | 서버에서 가져오는 외부 데이터(API, GraphQL 등). | 애플리케이션 내부에서 관리되는 데이터(예: 로그인 상태, 테마 설정). |
| 데이터 변경 주체 | 서버(외부 요인으로 변경됨). | 클라이언트(사용자 또는 내부 로직으로 변경됨). |
| 캐싱 및 동기화 | 캐싱, 데이터 리페칭, 실시간 동기화 필요. | 캐싱보다는 UI 상태 변화 관리에 초점. |
| 대표 도구 | React Query, SWR, Apollo Client, Relay | Redux Toolkit, Zustand, Jotai, Recoil, Context API. |
src/
├── components/ # 재사용 가능한 UI 컴포넌트
├── pages/ # 페이지 단위 컴포넌트
├── hooks/ # 커스텀 훅
├── store/ # 상태 관리 (Redux, Zustand 등)
├── utils/ # 공통 유틸리티 함수
├── styles/ # 전역 스타일 및 Tailwind 설정
└── services/ # API 통신 관련 코드
기능별 폴더구조
장점
유지보수 용이: 한 기능의 모든 파일이 한 폴더에 있으므로, 수정 및 확장이 쉽다.
협업 효율성 증가: 팀원이 각자 다른 기능을 작업할 때 충돌이 적음.
독립성 강화: 기능별로 폴더가 독립적이라 의존성이 줄어듦.
단점
공통 코드 관리 어려움: 공통 컴포넌트나 유틸리티 파일이 각 기능에 중복될 가능성이 있음.
작은 프로젝트에 과도: 단순한 구조에서는 폴더 분리가 불필요하게 복잡해질 수 있음.
src/
├── features/ # 기능별 폴더
│ ├── auth/ # 인증 관련 기능
│ │ ├── components/ # 인증 관련 컴포넌트
│ │ │ ├── LoginForm.tsx
│ │ │ ├── SignupForm.tsx
│ │ ├── hooks/ # 인증 관련 커스텀 훅
│ │ │ └── useAuth.ts
│ │ ├── services/ # 인증 관련 API 호출
│ │ │ └── authService.ts
│ │ ├── types/ # 인증 관련 타입 정의
│ │ │ └── authTypes.ts
│ │ ├── index.ts # auth 폴더의 진입 파일 (export 관리)
│ │
│ ├── cart/ # 장바구니 관련 기능
│ │ ├── components/ # 장바구니 관련 컴포넌트
│ │ │ ├── CartItem.tsx
│ │ │ ├── CartList.tsx
│ │ ├── hooks/
│ │ │ └── useCart.ts
│ │ ├── services/
│ │ │ └── cartService.ts
│ │ ├── index.ts
│ │
│ ├── product/ # 상품 관련 기능
│ ├── components/
│ │ ├── ProductCard.tsx
│ │ ├── ProductList.tsx
│ ├── hooks/
│ │ └── useProduct.ts
│ ├── services/
│ │ └── productService.ts
│ ├── index.ts
│
├── shared/ # 공통 컴포넌트, 유틸리티
│ ├── components/ # 재사용 가능한 공통 컴포넌트
│ │ ├── Button.tsx
│ │ ├── Modal.tsx
│ ├── utils/ # 공통 유틸리티 함수
│ │ ├── formatDate.ts
│ │ ├── calculatePrice.ts
│ ├── constants.ts # 상수 정의
│ ├── types.ts # 공통 타입 정의
│
├── App.tsx # 루트 컴포넌트
├── index.tsx # 진입점
페이지별 폴더구조
장점
경로와 구조 일치: URL과 폴더 구조가 동일해 직관적이고 파일을 찾기 쉽다.
초기 설정 간단: Next.js와 같은 프레임워크에서 바로 활용 가능.
작은 프로젝트에 적합: 파일이 적은 프로젝트에서 간단히 관리 가능.
단점
재사용성 낮음: 컴포넌트를 페이지별로 분리하면 코드 중복이 발생할 수 있음.
확장성 부족: 대규모 프로젝트에서는 페이지 간 의존성이 증가해 관리가 복잡해질 수 있음.
src/
├── pages/ # 페이지 단위 폴더
│ ├── index.tsx # 메인 페이지
│ ├── about.tsx # About 페이지
│ ├── login.tsx # 로그인 페이지
│ ├── signup.tsx # 회원가입 페이지
│ ├── cart/ # 장바구니 페이지
│ │ ├── index.tsx # 장바구니 메인
│ │ └── checkout.tsx # 결제 페이지
│ ├── product/ # 상품 관련 페이지
│ │ ├── [id].tsx # 상품 상세 페이지 (동적 라우팅)
│ │ └── list.tsx # 상품 목록 페이지
│
├── components/ # 공통 컴포넌트
│ ├── Button.tsx
│ ├── Header.tsx
│ ├── Footer.tsx
│ ├── Modal.tsx
│
├── hooks/ # 커스텀 훅
│ ├── useAuth.ts
│ ├── useCart.ts
│
├── styles/ # 스타일 관련 파일
│ ├── global.css # 글로벌 스타일
│ ├── theme.ts # 테마 설정
│
├── utils/ # 공통 유틸리티 함수
│ ├── formatDate.ts
│ ├── apiClient.ts
│
├── App.tsx # 루트 컴포넌트
├── index.tsx # 진입점
| 구분 | 기능별 폴더 구조 | 페이지별 폴더 구조 |
|---|---|---|
| 구조 | 관련된 기능끼리 그룹화 | 페이지(URL) 단위로 파일 구성 |
| 장점 | - 기능 중심으로 유지보수가 쉬움 - 독립적인 기능 관리 가능 | - URL과 폴더 구조가 동일 - 파일을 찾기가 직관적 |
| 단점 | - 파일 찾기가 직관적이지 않을 수 있음 - 공통 코드 중복 위험 | - 재사용 가능한 코드 관리 어려움 - 대규모 프로젝트에 비효율적 |
어떤 폴더 구조를 선택해야 할까?
작은 프로젝트:
페이지별 폴더 구조가 적합.
URL 경로와 폴더 구조가 직관적으로 연결되므로 간단한 프로젝트에 적합.
대규모/협업 프로젝트:
기능별 폴더 구조가 적합.
유지보수성과 확장성을 높이고, 각 기능이 독립적으로 관리될 수 있음.
폴더 네이밍 규칙
| 작업 타입 | 작업 내용 |
|---|---|
feat | 기능 개발 |
fix | 버그 수정 |
docs | 문서 작업 (documentation) |
style | CSS 관련 작업 |
refactor | 코드 리팩토링 |
chore | 핵심 내용이 아닌 잡일 (예: package.json 변경, npm 설치 등) |
rename | 파일, 폴더명 수정 |
remove | 파일, 폴더 삭제 |
add | 없던 파일 생성, 초기 세팅 |
comment | 주석 추가 및 변경 |
Git 브랜치 전략:
PR(풀 리퀘스트) 규칙:
코드 컨벤션:
네이밍 컨벤션:
전역 상태 관리란?
애플리케이션 전역에서 공유해야 하는 상태(데이터)를 중앙에서 관리하고, 여러 컴포넌트가 이를 효율적으로 사용할 수 있도록 하는 방식. 클라이언트상태에 속한다.
전역 상태 관리 도구의 역할
중앙 저장소(Store):
상태 데이터를 저장하는 중앙 저장소를 제공합니다.
컴포넌트는 저장소에 저장된 데이터를 읽거나 수정할 수 있습니다.
구독(Subscription):
컴포넌트가 특정 상태를 구독하고 있다가, 상태가 변경되면 자동으로 업데이트됩니다.
비동기 작업 처리:
서버와 데이터를 주고받는 비동기 작업(예: API 호출)을 간단히 관리할 수 있습니다.
전역 상태 관리가 필요한 경우
여러 컴포넌트에서 데이터를 공유해야 하는 경우.
(예) 로그인 상태, 사용자 정보.
데이터가 자주 변경되고 이를 UI에 반영해야 하는 경우.
(예) 쇼핑몰 장바구니 데이터.
상태가 컴포넌트 트리 깊숙이 전달되어야 하는 경우.
(예) 다수의 자식 컴포넌트에서 동일한 데이터를 필요로 할 때.