파일 & 코드 컨벤션
2.1 Folder & File Convention
현재 프로젝트는 Next.js 13.5.8에서 App Router를 사용하는 것을 기준으로 폴더가 구성되어 있습니다.
src
폴더는 선택 사항입니다. 현재 프로젝트에서는src
폴더를 사용하고 있으며, 애플리케이션 코드를 분리할 수 있기때문에, 사용하는 것을 권장합니다.관련 문서: src Directory
Routing
Next.js에서 App Router를 사용할 때 폴더명은 라우팅에 영향을 미치기 때문에, 알아두어야 할 사항들이 있습니다.
일반 라우트:
folder
- 일반적인 라우팅 세그먼트동적 라우트:
[folder]
- 동적 라우트 세그먼트.folder
에 slug 변수값 대입라우트 그룹:
(folder)
- 라우팅에 영향을 주지 않고 그룹화비공개 폴더:
_folder
- 라우팅에서 폴더 및 모든 자식 세그먼트 제외병렬/가로채기 라우트:
[...folder]
,[[...folder]]
,@folder
,(.)folder
,(..)folder
,(..)(..)folder
,(...)folder
관련 문서: Project Structure
Folder Naming Convention
kebab-case
(각 단어를 소문자로 쓰고 대시로 구분하는 규칙)로 작성하는 것을 권장합니다.Next.js에서는 폴더명에 따라 라우팅이 되고, 폴더명이 곧 URL 세그먼트가 됩니다. URL에서는
kebab-case
사용이 권장됩니다.Next.js에서 공식적으로
kebab-case
를 강제한 것은 아니지만, 여러 공식 문서나 예제 코드에서kebab-case
를 사용하는 것을 확인할 수 있습니다.
File Naming Convention
페이지 파일:
page.tsx
- 각 폴더의 루트에 위치하며, 해당 폴더가 라우트의 엔드포인트가 됩니다.레이아웃 파일:
layout.tsx
- 해당 폴더와 하위 폴더의 공통 레이아웃을 정의합니다.템플릿 파일:
template.tsx
- 레이아웃과 유사하지만, 각 라우트마다 새로운 인스턴스를 생성합니다.로딩 파일:
loading.tsx
- 해당 라우트의 로딩 상태를 정의합니다. 현재 프로젝트에서는, 루트 레이아웃과 같은 레벨에 1개만 두어 관리합니다.에러 파일:
error.tsx
- 해당 라우트의 에러 상태를 정의합니다. 현재 프로젝트에서는, 루트 레이아웃과 같은 레벨에 1개만 두어 관리합니다.기타 컴포넌트 파일:
component-name.tsx
- 일반 컴포넌트 파일명은kebab-case
로 작성합니다.
2.2 Code Convention
Convention
모든 팀원들이 프로젝트 시작 전에 컨벤션을 협의하고 숙지한 후 개발을 진행합니다.
ESLint와 Prettier 설정을 통일한 후 개발을 시작합니다.
Code Style
이름을 정의할 때는 약어 사용을 자제하며, 변수명만 보고 의미를 알 수 있도록 단어 그대로 사용하는 것을 권장합니다.
들여쓰기 : 들여쓰기는 Tab 문자가 아닌 공백(Space) 문자를 사용하며 공백 2칸을 기본값으로 사용합니다.
세미콜론 : 세미콜론을 사용하여 문장을 끝냅니다.
문자열 : 문자열에는 일관되게
싱글쿼트(')
를 사용합니다.문자열 연결 : 문자열 연결을 할때는 가독성을 위해
template strings
를 사용합니다.
한 줄 길이 제한 : 한 줄의 최대 길이를 100자로 제한합니다.
복수형 명명 : 복수형에는 's' 대신 'List'를 사용합니다.-
비교 연산자 : ==와 != 대신 ===와 !==를 사용합니다.
끝 쉼표 : 끝 쉼표를 추가해줍니다. 끝 쉼표가 없으면 git diffs에 불필요한 변경사항이 저장될 수 있습니다.
Components
컴포넌트 파일은 해당 컴포넌트를 사용하는 파일들이 위치한 가장 가까운 상위 폴더 아래에 있는
_components
폴더에 생성합니다.가능한 한 컴포넌트를 분리하여 한 파일당 코드가 너무 길어지지 않도록 합니다.
컴포넌트 분리 기준
단일 책임 원칙: 각 컴포넌트는 하나의 명확한 역할을 수행해야 합니다.
재사용 가능성: 비슷한 기능을 하는 부분은 독립된 컴포넌트로 분리하여 재사용성을 높입니다.
가독성: 코드를 작고 독립적인 컴포넌트로 나누어 가독성을 높입니다.
상태와 라이프사이클: 컴포넌트가 관리하는 상태와 라이프사이클 메서드를 고려하여 분리합니다.
UI 요소: 서로 다른 UI 요소는 별도의 컴포넌트로 분리합니다.
Variables
camelCase로 작성합니다.
예:
userAge
,userName
ECMAScript 사양에 정의된 JavaScript 변수명 명명 규칙을 따릅니다:
if
,else
,for
등 예약어 사용 금지변수명 첫 글자에 숫자 사용 금지
특수 문자 사용 금지 (단,
$
와_
는 예외)
의미 있는 변수명을 사용하여 코드의 가독성을 높입니다.
예:
data
대신userData
,response
대신apiResponse
useState
는[변수명, set + 변수명]
형태로 명명합니다.예:
[count, setCount]
,[isLoggedIn, setIsLoggedIn]
boolean 변수는 is, has, can 등의 접두사를 사용하여 명명합니다.
Functions
camelCase로 작성합니다.
일반적으로 함수는 여러 가지 행위를 나타내는 것이기 때문에 첫 단어는 동사로 시작합니다.
예:
getUser
,setUserName
동사만으로 의미 전달이 불명확한 경우에는 동사 + 명사 형태로 표기합니다.
예:
fetchUserData
,updateProfilePicture
함수 선언문, 함수 표현식보다 화살표 함수를 권장합니다. 호이스팅을 방지하고, 일관된 스코프 관리를 제공하며, 코드의 예측 가능성과 가독성을 높일 수 있습니다.
예:
const fetchData = () => { ... };
Iterators
for 문 대신 forEach, map, reduce 등의 고차 함수를 사용하여 코드의 가독성을 높입니다.
Uppercase Constants
상수는 변경되지 않는 값을 의미하므로,
const
키워드를 사용하여 선언합니다.SNAKE_CASE 대문자와 밑줄(
_
)을 사용하여 명명합니다.상수를 사용하는 경우는 다음과 같습니다:
실행하기 이전에 값을 알 수 있는 경우: 예를 들어, 색상 코드와 같은 값은 미리 정의할 수 있습니다.
기억하기 힘든 값을 변수에 할당해 별칭으로 사용하는 경우: 복잡하거나 긴 값을 간단한 변수명으로 대체하여 사용합니다.
하드코딩 값: 코드 내에서 변경되지 않는 고정된 값을 상수로 정의합니다.
환경 변수: 애플리케이션의 환경 설정 값을 상수로 정의하여 사용합니다.
(주의) 일반적인 데이터 값은 const로 선언되었더라도, 위의 Variable 규칙에 따라 camelCase로 작성합니다.
Hooks
기본 훅: React의 기본 훅(useState, useEffect 등)은 컴포넌트 상단에 정의합니다.
커스텀 훅: 커스텀 훅은 use로 시작하는 이름을 사용하며, 훅의 목적을 명확히 설명합니다. 예: useGetQuery
Event Handler
이벤트 핸들러 함수는
handle
접두사를 사용하여 명명합니다.예:
handleClick
,handleSubmit
이벤트 핸들러 함수는 이벤트 객체를 매개변수로 받아야 합니다.
예:
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => { ... };
이벤트 핸들러 함수는 가능한 한 짧고 간결하게 작성하며, 필요한 경우 별도의 함수로 분리합니다.
이벤트 핸들러 함수는
JSX 요소의 속성으로 직접 전달하지 않고, 변수에 할당
하여 전달합니다.
Typescript
타입 정의: 모든 함수, 변수, 컴포넌트에 대해 명시적으로 타입을 정의합니다.
무분별한 any 사용을 지양합니다.
Type 대신에 Interface 를 사용하여 통일하도록 합니다. Interface는 확장이 가능하고, 객체의 구조를 명확하게 정의할 수 있어 코드의 재사용성과 유지보수성을 높입니다. 예외 : 리터럴 (Literal), 튜플 (Tuple), 유니온 (Union) 등이 꼭 필요시에는 Type 사용합니다.
타입명은 PascalCase로 작성합니다. Interface는 I 접두사를 사용 합니다. 타입명의 일관성과 가독성을 높이기 위함입니다.
Props
페이지 컴포넌트의 Props의 Interface를 명명할 때는 다음 규칙을 따릅니다.
컴포넌트 이름 + Props 형태로 작성합니다. Interface를 사용하지만, I 접두사를 미사용합니다.
Comment
소스코드에 대한 이해를 돕기 위해 주석을 작성합니다.
vscode의
Comment Anchors Plugin
extension을 사용하여 하이라이팅 합니다.각 주석에
유형(Anchor)
을 추가하여 작성합니다.주석은 // 를 사용하여 작성합니다.
여러 줄 주석이 필요한 경우 /** ... */를 사용합니다.
각 앵커 유형은 대문자로 작성하며, 콜론(:) 뒤에 설명을 추가합니다.
Comment : Anchor Type
NOTE : 특정 코드에 대한 주석이나 설명을 추가할 때 사용합니다.
TODO : 해야 할 작업을 표시할 때 사용합니다.
FIXME : 수정이 필요한 부분을 표시할 때 사용합니다.
REVIEW : 코드 리뷰가 필요한 부분을 표시할 때 사용합니다.
STUB : 아직 구현되지 않은 부분을 표시할 때 사용합니다.
ANCHOR : 일반적인 주석 앵커로, 코드 내에서 중요한 위치를 표시할 때 사용합니다.
Comment Anchors Plugin 적용시 주석 하이라이팅 예시
Comment : Page Comment
파일(화면)에 대한 주석을 작성합니다. jsx, js, tsx, ts 파일 최상단에 필수로 작성합니다.
NOTE에 화면설명을 작성합니다.
담당자를 식별하기 위해 author와 since를 작성합니다. (담당자가 모호한 파일에서는 생략)
그 외 description, version, copyright 등이 관례적으로 쓰였으나 사용성이 떨어지므로, 본 프로젝트에서는 생략합니다.
Comment : Block Comment
블럭 주석은 파일, 함수, 메서드 등에 대한 설명을 제공하며, 함수 선언부 바로 위에 작성됩니다.
함수 안에서 사용하는 경우, 설명하는 코드와 같은 간격의 들여쓰기(Indent)를 적용합니다.
param, restuns를 명시합니다.
TanstackQuery QueryKey
QueryKey는 camelCase로 작성합니다.
QueryKey는 고유해야 하며, 동일한 데이터를 가져오는 다른 쿼리와 중복되지 않도록 합니다.
명확하고 직관적인 이름을 사용하여 QueryKey의 의미를 쉽게 이해할 수 있도록 합니다.
Semantic Tag
Semantic 태그는 HTML5에서 문서의 구조와 의미를 명확히 하기 위해 사용됩니다.
주요 태그로는
header
,aside
,nav
,main
,article
,section
,footer
가 있습니다. - 본 프로젝트에서는header
,aside
,nav
,main
이 layout에서 적용되어 있으며, 각 화면(page.tsx) 개발시에는main
내부 요소인article
,section
태그만 사용하면 됩니다.
2.3 Commit Convention
커밋 메시지를 작성할 때 사용자 간 원활한 소통을 위해 일관된 형식을 사용하도록 합니다.
3가지 영역(제목, 본문, 꼬리말)으로 나누어집니다.
태그: 제목 형태로 : 뒤에만 space를 넣습니다.
Commit Message : Type
Commit Message Type은 아래와 같이 분류되며, 소문자로 작성합니다.
feat
: 새로운 기능 추가fix
: 버그 수정docs
: 문서 내용 변경style
: 포맷팅, 세미콜론 누락, 코드 변경이 없는 경우 등refactor
: 코드 리팩토링test
: 테스트 코드 작성chore
: 빌드 수정, 패키지 매니저 설정, 운영 코드 변경이 없는 경우rename
: 파일 혹은 폴더명 수정이나 이동remove
: 파일 삭제 작업만 수행
Commit Message : Subject (제목)
최대 50글자가 넘지 않습니다.
마침표와 특수기호는 사용하지 않습니다.
첫글자는 대문자로 표기하며 과거시제를 사용하지 않습니다.
간결하게 요점만 서술합니다.
Commit Message : Body (본문)
한 줄당 72자 이내로 작성합니다.
내용을 최대한 상세히 적습니다.
무엇
을왜
진행했는지 설명해야 합니다.
Commit Message : Footer (꼬리말)
선택사항입니다.
이슈 트래커의 ID를 작성합니다.
어떤 이슈와 관련된 커밋인지(Resolves), 그 외 참고할 사항이 있는지(See also)로 작성하면 좋습니다.