🛠️기술 스택
언어 | TypeScript |
프레임워크 | Next.js 14 |
상태관리 | Client Side
- Zustand
——————
Server Side
- Tanstack Query |
라이브러리 | React Kakao Maps SDK |
asdasfs | framer-motion, React Bottom Sheet, Nuka Carousel, React Hook form, React-use, React-intersection-observer, React-virtualized or React-window 가벼운쪽은 window, lodash,lodash debounce, lodash throttle, |
번들러 | Next.js |
스타일링 | Styled Components
Tailwind
shadcnUI |
협업 툴 | Notion, Slack, Gather, Discord, Github |
API | Axios |
코드 포맷팅 | eslint, prettier, airbnb Rule + 커스텀 |
노드 버전 | node (20.11.0 LTS) |
라우터 | Next.js App Router |
배포 툴 | Vercel |
패키지 관리 | Yarn |
🚀코딩 컨벤션
📌 코딩 스타일
규칙 | 설명 | 비고 |
풀네임을 사용하도록 한다. | btn (X) button (O) | ㅤ |
함수 표현식 사용 | 변수 혹은 타입
export const func = () => {}
컴포넌트
(React Arrow Function Export 방식)
const Component = () ⇒ {}
export Component | ㅤ |
src alias 경로는 @ 를 사용합니다. | tsconfig.json 설정 필요 | ./ 예외 |
함수 네이밍 규칙_세부항목 | prop 전달 시 -> onChangeHandler
func 호출 시 -> handleChange
init, props 같은 약속된 축약어 허용 | 5어절 이상이면 PR시 의논 |
eslint, prettier 설정 | airbnb 기반 설정, 필요한 경우 airbnb 기반에 추가로 설정 | ㅤ |
css 단위는 rem으로 통일한다. | ㅤ | px 단위가 필요한 경우 예외 |
주석여부 | 필요할 경우 함수 혹은 변수 정의 상단에 기입하기 | 자주 사용되는 컴포넌트, 응용함수의 경우 JSDoc 지향 |
상수 관리 | 공용으로 사용되는 매직넘버 등은 constants 폴더의 파일에서 관리한다.
단일 컴포넌트 등에서 사용하는 상수의 경우 동일 경로의 constants.ts 에서 관리한다. | 쿼리키, API 주소, UI 매직넘버 등 |
스타일 상수 관리 | styles 폴더에 theme.ts 파일을 정의해서 사용한다. | ㅤ |
컴포넌트 export 방식 | 한 디렉토리 폴더에 있는 컴포넌트는 index.ts 파일에서 export 하도록 한다. | ㅤ |
컴포넌트 정의 | React.ReactNode 방식을 사용하도록 한다. | FC 사용 자제 |
조건문은 항상 early return을 사용하고 중첩 조건문 사용을 자제합니다.
2 Deps 초과인 경우 다시 한 번 생각해봅시다!
📌코드 네이밍
상수 | 전체 대문자 + 스네이크 케이스 | TOTAL_USER = 3000 |
변수 | 카멜케이스 | ㅤ |
함수 | 카멜케이스, 동사를 처음에 작성 | getValue, onChange … |
타입 | 파스칼 케이스 | type Post = { … } |
인터페이스 | 파스칼 케이스 | interface ComponentsProps { … } |
ㅤ | 유니언 타입을 사용해야하는 경우에만 타입을 사용하고 이외는 Interface를 지향한다. | 함수의 경우 type
그 외의 경우 interface 사용 지향 |
fetch 함수 | Root API 의 경우 대문자 사용 | GET, POST, DELETE … |
📌브랜치 구조 및 네이밍
feature → dev → main
→ release
- feature - 개별 feature 구현 브랜치
- dev - feature 통합 브랜치
- release - 프로덕트 배포전 테스트 배포 브랜치
- main - 프로덕트 배포 브랜치
prefix/keyword/<이슈번호> → feature/button/#1
📌파일, 폴더 구조 및 네이밍
components 파일 | 파스칼 케이스 | Home.tsx |
hooks | use + 파스칼 케이스 | useHover.ts |
utils | 카멜 케이스 | parseDate.ts |
api | 카멜 케이스 | /api
/ServiceName
/service.ts
/axiosInstance.ts
/endPoints.ts |
client state store | use + 파스칼 케이스 + store | useMeStore, useAuthStore |
types | types 폴더 / serviceName.ts | 서버 데이터 관련 interface, type 은 service 명을 따른다.
/types
/Request
/index.ts - 요청 보내는 타입
/Response
/apiName.ts - 원시타입에 변조가 있는 경우
/OriginDataType
/User.ts
/ Log.ts |
src assets components 공용 types styles lib constants hooks stores utils api app page layout.tsx components sections <- view 가 비대해지면 짜른다. Page.model.tsx Page.controller.tsx Page.view.tsx Page.styles.ts page.tsx <- controller
📌디자인 패턴
Container / Presentational Pattern + Model
state, action 등의 실제 동작을 하는 부분 → Controller
View 와 View 에 대한 애니메이션 제어 부분 → View
Server 로부터 데이터를 받아오는 부분→ Model
요런 느낌?
Compound Pattern
등… 처음부터 패턴을 정하고 가면 좋을 것 같습니다.
📌스타일 네이밍
- 컴포넌트 단위
- 컴포넌트명 + 스타일명
- ex) PostCardContentText, PostCardContainer
엘리먼트 그룹 단위 Layout > Container > Section > Group > Wrapper
global인 경우 스타일명 ex) TitleText, Row, Column
📌브랜치 구조 및 Merge 규칙
신속하고 빠른 개발을 위해 GitHub Flow에 dev 브랜치를 추가하는 형식으로 브랜치 구조를 만들어 진행한다.
Merge 규칙
- 스쿼시 머지를 우선적으로 사용한다.
- 주말제외, 평일 19시 이전에 올라온 PR은 당일 리뷰하고 Merge하는 형식으로 한다.
- 만약 Conflict가 나거나 Approve가 3개 미만일 경우 익일 해당 문제점 해결 후 Merge하도록 한다.
PR 템플릿
* 이슈 링크: ## 💡 핵심적으로 구현된 사항 <-- 문제를 해결하면서 주요하게 변경된 사항들을 "스크린샷"과 함께 적어 주세요 --> * ## ➕ 그 외에 추가적으로 작업한 사항 <-- 주 Task 이외의 작업한 변경 사항 --> * ## 🤔 테스트,검증 && 고민 사항 <-- 배포에서 체크해봐야 할 부분 --> <-- 궁금한 점, 팀원들의 의견이 필요한 부분, 크로스체크가 필요한 부분 등 --> * ## PR 반영사항 <-- PR 요청 사항을 리스트로 표시하고 반영 여부를 표시합니다 --> *
Issue 구현 과제가 모두 완료되기 전까지 close 처리 조심하기.
Issue 템플릿
# 구현 주제 ex) 회원가입 페이지와 회원가입 단계를 구현합니다. --- ## Task List - [ ] SignUp Page 구현 - [ ] Section 간의 transition 구현 - [ ] 닉네임 입력 Section 구현 - [ ] 추가정보 입력 Section 구현 - [ ] 약관 Section 구현
📌코드 리뷰 룰
작은 PR 규칙뱅크샐러드의 코드 리뷰 문화가 성숙해지기 전에는 PR의 코드 라인 수에 대한 규칙이 없었습니다. 개발하는 기능의 복잡도에 따라 짧게는 코드는 수백 줄, 많게는 10,000줄 이상의 PR 이 만들어지기도 했습니다. 코드의 길이가 길어질수록 리뷰어의 집중도는 떨어질 수밖에 없었습니다. 코드를 이해하는 시간이 길어지고, 리뷰는 목표한 일정에 완료되지 못하고, 병목이 되기 시작했습니다. 코드 리뷰가 고객 임팩트를 내는 부분에 있어서 병목이 되지 않도록 ‘작은 PR 규칙’ (1개의 PR은 1,000 Line을 넘을 수 없다“) 을 정했습니다.‘작은 PR 규칙’ 도입 초기에는 “복잡한 기능을 만드는데 1,000줄은 너무 적은 것 아닌가?“, “테스트 코드도 라인 수에 포함해야 하는가?” 등의 원칙에 대한 의문과, 여러 개의 PR을 만들어야 하는 부분이 오히려 생산성을 떨어트리지 않을까 하는 우려도 있었지만, 이후 몇 차례의 코드 리뷰를 진행하면서 규칙을 구체화해 나가고 노하우도 쌓이기 시작했습니다. - PullRequest, Commit의 단위는 최소의 기능 단위로 세분화한다. - 테스트 코드는 Mock json 이 라인 수의 대부분을 차지하므로 제한을 두지 않는다. 코드 리뷰 문화가 성숙해가면서 우리는 리뷰 병목 해소와 조직의 확장성을 얻을 수 있었습니다. 모든 PR은 200 ~ 300줄 내외가 되고 1~2일 이내에 리뷰를 완료하여 리뷰의 병목을 해소할 수 있었습니다. 서비스의 성장과 함께 iOS 챕터의 구성원도 4명에서 8명으로 늘어났고, 개발되는 코드의 양(= PR의 양) 도 증가했지만 ‘작은 PR 규칙’ 아래 병목 없는 성장
Pn 룰
- P1: 꼭 반영해주세요 (Request changes)
- 리뷰어는 PR의 내용이 서비스에 중대한 오류를 발생할 수 있는 가능성을 잠재하고 있는 등 중대한 코드 수정이 반드시 필요하다고 판단되는 경우, P1 태그를 통해 리뷰 요청자에게 수정을 요청합니다.
- 리뷰 요청자는 p1 태그에 대해 리뷰어의 요청을 반영하거나, 반영할 수 없는 합리적인 의견을 통해 리뷰어를 설득할 수 있어야 합니다.
- P2: 적극적으로 고려해주세요 (Request changes)
- 작성자는 P2에 대해 수용하거나 만약 수용할 수 없는 상황이라면 적합한 의견을 들어 토론할 것을 권장합니다.
- P3: 웬만하면 반영해 주세요 (Comment)
- 작성자는 P3에 대해 수용하거나 만약 수용할 수 없는 상황이라면 반영할 수 없는 이유를 들어 설명하거나 다음에 반영할 계획을 명시적으로(JIRA 티켓 등으로) 표현할 것을 권장합니다.
- Request changes 가 아닌 Comment 와 함께 사용됩니다.
- P4: 반영해도 좋고 넘어가도 좋습니다 (Approve)
- 작성자는 P4에 대해서는 아무런 의견을 달지 않고 무시해도 괜찮습니다.
- 해당 의견을 반영하는 게 좋을지 고민해 보는 정도면 충분합니다.
- P5: 그냥 사소한 의견입니다 (Approve)
- 작성자는 P5에 대해 아무런 의견을 달지 않고 무시해도 괜찮습니다.
PR 리뷰 반영 사항의 경우
- P4 ~ P5 사항의 경우 반영 여부를 slack 에 고지한 후 merge 진행 하는 것을 지향합니다.
📌커밋 룰
Git Conventionalcommits 의 내용을 기반으로 구성
Type | 내용 |
✨feat | 새로운 기능 추가 |
🐛fix | 버그 수정 또는 typo |
♻️refactor | 리팩토링 |
🎨style | CSS 등 사용자 UI 디자인 변경 |
🚜change | 로직에 영향을 미치지 않는 변경 사항 (오탈자 수정, 주석 등) |
🔨chore | 빌드 부분 혹은 패키지 매니저 수정사항 |
👶🏻init | 프로젝트 초기 생성 |
🏷️rename | 파일 혹은 폴더명 수정하거나 옮기는 경우 |
🗑️remove | 코드, 파일을 삭제하는 작업만 수행하는 경우 |
📝docs | 문서를 추가하거나 수정하는 경우 |
라우팅 Path
splash → /
auth → /auth
signin → /signin
메인 페이지 → /home
더보기 → /more?keyword=”my_log” | “my_post” | “my_like” | “area_popular” | “total_popular” | “recent_post”
포스트 디테일 → /post/:id
로그 디테일 → /log/:id
로그 기록 → /log_record
포스트 작성 → /post_create
탐색 → /explore?location=”loc1-loc2-loc3”&keyword=”…”
프로필 → /profile/:id
설정 → /profile/:id/setting
나의 산책 일지 페이지 → /user/:id/diary
업적 → /user/:id/reward
메이트 모집 → /mate/:id
메이트 모집 작성 → /mate_create
메이트 채팅 → /chat/:id
알림 → /notification