|
| 1 | +# 🧾 코딩 컨벤션 |
| 2 | + |
| 3 | +메잇볼 클라이언트 팀의 코드 품질과 협업 효율을 높이기 위한 코딩 컨벤션입니다. |
| 4 | +모든 팀원이 일관된 스타일로 코드를 작성할 수 있도록 아래 규칙을 준수해주세요. |
| 5 | + |
| 6 | +--- |
| 7 | + |
| 8 | +## 🟡 변수 |
| 9 | + |
| 10 | +- `var` 사용 **금지**, `const` → `let` 순으로 선언 |
| 11 | +- 문자열 조합 시 `+` 대신 **템플릿 리터럴(``` ` ```) 사용** |
| 12 | +- 변수명은 의미를 명확히 드러내도록 작성 |
| 13 | + - ✅ `users`, `fruits` |
| 14 | + - ❌ `Arr`, `tmp`, `data1` |
| 15 | +- 줄임말 지양: 의미가 길더라도 명확한 이름 사용 |
| 16 | + - ✅ `Button` |
| 17 | + - ❌ `Btn` |
| 18 | +- `map()` 사용 시, key는 반드시 고유한 값 사용 |
| 19 | + - ❌ `key={index}` → ❌ |
| 20 | + - ✅ `key={user.id}` 또는 `uuid` |
| 21 | +- **전역 변수**는 지양 (가능하면 로컬 스코프 유지) |
| 22 | + |
| 23 | +--- |
| 24 | + |
| 25 | +## 🔵 함수 |
| 26 | + |
| 27 | +- **function 키워드 금지**, **화살표 함수만 사용** |
| 28 | +- 공통 함수는 `utils/` 폴더로 분리하여 재사용 |
| 29 | +- 변수/함수 이름은 **20자 미만** |
| 30 | + - 네이밍에 의미를 담고, 필요한 경우 주석으로 보완 |
| 31 | +- **Early Return 패턴 권장** |
| 32 | + |
| 33 | +```tsx |
| 34 | +// ✅ Early Return |
| 35 | +const processUser = (user) => { |
| 36 | + if (!user || !user.isActive) return; |
| 37 | + // 이후 로직 |
| 38 | +}; |
| 39 | +```` |
| 40 | + |
| 41 | +--- |
| 42 | + |
| 43 | +## 🟢 컴포넌트 |
| 44 | + |
| 45 | +* 기본 템플릿은 `rafce` 사용 (React Arrow Function Component with Export) |
| 46 | +* 불필요한 wrapper는 ❌ → **Fragment (`<>`) 사용 권장** |
| 47 | + |
| 48 | +```tsx |
| 49 | +const InfoText = () => { |
| 50 | + return ( |
| 51 | + <> |
| 52 | + <h1>Welcome!</h1> |
| 53 | + <p>This is our new page!</p> |
| 54 | + </> |
| 55 | + ); |
| 56 | +}; |
| 57 | +``` |
| 58 | + |
| 59 | +* children이 없는 컴포넌트는 self-closing (`<Component />`) |
| 60 | +* children 적극 활용해 UI 유연하게 구성 |
| 61 | + |
| 62 | +--- |
| 63 | + |
| 64 | +## 🟠 타입 (TypeScript) |
| 65 | + |
| 66 | +* `object` 타입은 **interface** 사용 |
| 67 | +* 단일 변수 타입은 **type alias** |
| 68 | +* 컴포넌트 Props 타입은 **컴포넌트 상단에 정의** |
| 69 | +* 그 외 타입은 `types/` 폴더에 분리 |
| 70 | +* API 응답 타입 네이밍: `OOOResponse` 형태 |
| 71 | + |
| 72 | +```ts |
| 73 | +interface UserCardProps { |
| 74 | + userId: string; |
| 75 | + userName: string; |
| 76 | +} |
| 77 | +``` |
| 78 | + |
| 79 | +--- |
| 80 | + |
| 81 | +## 🔴 메소드 |
| 82 | + |
| 83 | +* 배열 복사는 **스프레드 연산자(...)** 사용 |
| 84 | + |
| 85 | + ```ts |
| 86 | + const copy = [...originals]; |
| 87 | + ``` |
| 88 | + |
| 89 | +* `for` 루프 대신 `map`, `forEach`, `filter` 사용 |
| 90 | + |
| 91 | +* 구조 분해 할당 적극 사용 |
| 92 | + |
| 93 | +```ts |
| 94 | +const checkUser = ({ userName, userBirth }: UserDataProps) => { |
| 95 | + // ... |
| 96 | +}; |
| 97 | +``` |
| 98 | + |
| 99 | +* 불필요한 반복문 지양 |
| 100 | + |
| 101 | + * 조건 검색 시 `Map`, `Object`, 인덱스 접근 방식 고려 |
| 102 | + |
| 103 | +--- |
| 104 | + |
| 105 | +## ⚙ 기타 |
| 106 | + |
| 107 | +* `button` 태그에는 `type` 명시 (`type="button"` / `"submit"`) |
| 108 | +* 비교 연산은 `===`, `!==`만 사용 |
| 109 | +* **axios는 async/await 패턴 사용**, then/catch 대신: |
| 110 | + |
| 111 | +```ts |
| 112 | +const fetchData = async () => { |
| 113 | + try { |
| 114 | + const res = await axios.get('/api/data'); |
| 115 | + } catch (err) { |
| 116 | + console.error(err); |
| 117 | + } |
| 118 | +}; |
| 119 | +``` |
| 120 | + |
| 121 | +--- |
| 122 | +<br/> |
| 123 | + |
| 124 | +> 📌 컨벤션이 어긋난 경우 리뷰 시 코멘트 부탁드리며, **모두가 이해할 수 있는 코드 작성**을 우선합니다. |
| 125 | + |
0 commit comments