안녕하세요. 성공적으로 '두잇투게더'를 끝마치고 저희 팀이 열심히 정한 컨벤션을 정리하기 위해 오랜만에 블로그에 글을 적습니다.
두잇투게더는 무려 프로젝트 1등, 인기 프로젝트 1등을 했는데요. 노력한만큼 결과가 너무 좋아서 정말 기분이 좋았습니다.
Git Convention
Git Branch 전략
https://s2ylvia.tistory.com/26
우리 프로젝트에 제대로 된 Git 브랜치 전략을 세우는 게 어때요?
안녕하세요. 이 포스트는 제가 프론트엔드 개발자로 참여 중인 가사분담 플랫폼 '두잇투게더'의 Git 브랜치 전략을 팀원들과 함께 세우기 위해 정리한 내용입니다. 나, 지금까지 Git branch를 어떻
s2ylvia.tistory.com
Commit
Gitmoji를 사용하여 시각적으로 구분을 쉽게 하고, 각 항목을 세부적으로 나누어 최대한 커밋을 세세하게 남기도록 하였습니다.
✨ Feat: 기능 추가
🐛 Fix: 오류 수정
📝 Docs: 문서 업데이트
💄 Style: 스타일 파일 추가, 수정
♻️ Refactor: 리팩토링
📝 Rename: 파일명 변경
🔥 Remove: 파일, 폴더 삭제
🚚 Move: 폴더, 파일 경로 이동
📦 Build: 패키지.json 업데이트
➕ Add: 파일 추가
🚀 Deploy: 배포
💬 Comment: 코드 주석 추가
🎉 Tada: 프로젝트 시작
🔧 Wrench: 분류하기 어려운 수정
GitHub: Issues template, PR template, Label
저희 팀은 GitHub의 Project 기능을 활용해 작업을 분담하고, 각자가 맡은 기능에 대해 이슈를 생성하여 관리했습니다.
Issues template
- 기능 이슈
---
name: issue template
about: 이슈 템플릿
title: "[ISSUE]"
labels: Issue Report
assignees: ''
---
## ✨ **이슈 템플릿** ✨
### ✅ 이슈 설명
<!--이슈에 대해 명확하고 간결하게 설명해주세요-->
### 🚩 예상 완료 기간
<!--ex) ~ 10.27(일) 12:00. 시간은 선택사항-->
### ℹ️ 참고할만한 자료(선택)
- 버그 이슈
---
name: Bug template
about: 버그 템플릿
title: "[BUG]"
labels: Bug Report
assignees: ''
---
🐞 **버그 리포트 템플릿** 🐞
## 🪲 버그 설명
<!--발생한 버그에 대해 명확하고 간결하게 설명해주세요-->
## 🔄 재현 방법
<!--버그를 재현하기 위한 단계를 설명해주세요-->
1. Go to '...' 🔍
2. Click on '....' 🖱️
3. Scroll down to '....' 🖱️
4. See error ❌
## ✅ 예상되는 동작
<!--의도한 정상 동작을 설명해주세요)-->
## ❌ 실제 동작
<!--실제 발생한 버그 동작을 설명해주세요-->
## 📷 스크린샷/비디오
<!--버그를 설명하는데 도움이 되는 스크린샷이나 비디오가 있다면 첨부해주세요-->
## 🚨 우선순위
<!--이 버그가 사용자에게 미치는 영향을 고려했을 때 수정 우선순위가 어느정도인지 높음, 중간, 낮음 중에 선택해주세요-->
## ℹ️ 추가 정보
<!--버그에 대한 추가적인 정보가 있다면 남겨주세요-->
PR template
Pull Request의 merge는 1명 Approve 승인 시 가능하도록 rulset을 세웠습니다.
- PR Title
Feature/#이슈번호-내용요약
- PR template
## 📄 작업 페이지 및 내용 요약
> ex) 메인페이지 - 라우트 연결
## 📌 이슈 넘버
> ex) #이슈번호, #이슈번호
## 📝 작업 내용
## 📸 스크린샷(선택)
## 💬리뷰 요구사항(선택)
> 리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요
>
> ex) 메서드 XXX의 이름을 더 잘 짓고 싶은데 혹시 좋은 명칭이 있을까요?
Label
[
{
"name": "⚙ Setting",
"color": "e3dede",
"description": "개발 환경 세팅"
},
{
"name": "✨ Feature",
"color": "a2eeef",
"description": "기능 개발"
},
{
"name": "🚀 Deploy",
"color": "C2E0C6",
"description": "배포 관련"
},
{
"name": "💄 Style",
"color": "FEF2C0",
"description": "마크업 & 스타일링"
},
{
"name": "🐛 BugFix",
"color": "d73a4a",
"description": "Something isn't working"
},
{
"name": "💻 CrossBrowsing",
"color": "C5DEF5",
"description": "브라우저 호환성"
},
{
"name": "📝 Docs",
"color": "1D76DB",
"description": "문서 작성 및 수정 (README.md 등)"
},
{
"name": "📬 API",
"color": "D4C5F9",
"description": "서버 API 통신"
},
{
"name": "♻️ Refactor",
"color": "f29a4e",
"description": "코드 리팩토링"
},
{
"name": "🙋♂️ Question",
"color": "9ED447",
"description": "Further information is requested"
},
{
"name": "🥰 Accessibility",
"color": "facfcf",
"description": "웹접근성 관련"
},
{
"name": "✅ Test",
"color": "ccffc4",
"description": "test 관련(storybook, jest...)"
}
]
Code Convention
- 화살표함수 사용
- props에서 함수가 있는 경우 handle{ 액션 }으로 사용
- api 타입 정의할 때 타입 이름은 response인 경우 Res로 끝나게, request인 경우 Req로 끝나게 작성
interface BaseRes {}
interface CreateGroupRes extends BaseRes
.prettierrc
- prettier 설치
npm i -D prettier
npm i -D eslint-config-prettier
- .prettierrc 파일 추가
{
"printWidth": 100,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"tabWidth": 2,
"quoteProps" : "as-needed",
"bracketSpacing": true,
"endOfLine": "auto",
"useTabs": false,
"arrowParens": "avoid",
"jsxSingleQuote": true,
"plugins": ["prettier-plugin-tailwindcss"]
}
code-snippets
{
"Typescript React component with no props": {
"prefix": "rfcn",
"body": [
"const ${1:${TM_FILENAME_BASE}} = () => {",
" return (",
" <div>",
" ${1:${TM_FILENAME_BASE}}",
" </div>",
" );",
"};",
"",
"export default ${1:${TM_FILENAME_BASE}};"
],
"description": "Creates a React Functional Component with no props"
},
"Typescript React component with props": {
"prefix": "rfc",
"body": [
"import React from 'react'",
"",
"interface ${1:${TM_FILENAME_BASE}}Props {",
" $2",
"};",
"",
"const ${1:${TM_FILENAME_BASE}}: React.FC<${1:${TM_FILENAME_BASE}}Props> = ({ $2 } ) => {",
" return (",
" <div>",
" ${1:${TM_FILENAME_BASE}}",
" </div>",
" );",
"};",
"",
"export default ${1:${TM_FILENAME_BASE}};"
],
"description": "Creates a React Functional Component with props"
}
}
const Test = () => {
return (
<div>
Test
</div>
);
};
export default Test;
type TestProps = {
};
const Test = ({ }: TestProps) => {
return (
<div>
Test
</div>
);
};
export default Test;
폴더 구조 및 네이밍 컨벤션
- 네이밍
이름 | 규칙 |
파일/폴더 | camelCase |
함수/변수 | camelCase |
컴포넌트 | PascalCase |
상수 | UPPER_SNAKE_CASE |
- 폴더 구조
src/
├── assets/ # 로고 등 함께 빌드 될 이미지 파일들
├── components/ # 컴포넌트
├── layout/ # 레이아웃
├── pages/ # 라우터별 페이지
├── mock/ # 더미 데이터
├── hooks/ # 커스텀 훅
├── utils/ # 유틸 기능 제공하는 함수
├── services/ # 실제 서비스 로직 (API 호출 하는 함수, 로컬스토리지 데이터 저장/삭제 등)
├── constants/ # 상수
├── types/ # 타입스크립트 타입 정의
├── store/ # 전역변수 정의
이렇게 정리하니깐 뿌듯하네요.
프로젝트를 진행하면서 처음으로 컨벤션을 문서화하고 적용했는데, 미리 정해두니 개발 과정에서 혼란이 줄어들었고, 결과도 매우 좋았습니다. 앞으로 여러분도 꼭 컨벤션을 정리해 원활한 협업을 하시길 바랍니다. 감사합니다.
'⚡️etc.' 카테고리의 다른 글
퍼널 패턴 적용기: 잘못 구현된 페이지 흐름 개선하기 (0) | 2025.01.26 |
---|---|
우리 프로젝트에 제대로 된 Git 브랜치 전략을 세우는 게 어때요? (3) | 2024.11.24 |
[chart.js/react-chartjs-2] React 프로젝트에 chart.js 적용해보자👋(+Typescript, 반응형) (0) | 2024.09.27 |
[GitHub Pages] gh-pages 라이브러리를 활용하여 배포하기 (0) | 2024.09.02 |
Axios와 Promise에 대해 알아보자 (0) | 2024.06.19 |