HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
♥️
2기 최종 프로젝트 팀별 공간
/
💡
[팀 04] 동규라미
/
📊
코딩 컨벤션
📊

코딩 컨벤션

폴더 구조스타일드 컴포넌트CSS 프로퍼티 순서import 문 정렬네이밍타입핸들러 함수PrettierLint함수 정의Container? Wrapper?API 로직

폴더 구조

폴더가 너무 많아도 그리고 너무 중첩되어도 좋지 않다
타입이 중복되어 사용된다면 types 폴더 하나에서 관리할 수 있도록 하자
.d.ts 파일보다는 .ts 파일에서 export 를 이용하자

스타일드 컴포넌트

백틱 형식을 오브젝트 형태로 통일하자
현재 common.ts 에 있는 컴포넌트를 components 폴더로 옮기자 ⇒ 이것도 또한 컴포넌트이기 때문에
Object Styles
Writing styles with objects is a powerful pattern built directly into the core of emotion. Instead of writing css properties in kebab-case like regular css, you write them in camelCase, for example background-color would be backgroundColor.
Object Styles
https://emotion.sh/docs/object-styles#with-styled
Object Styles

CSS 프로퍼티 순서

import 문 정렬

eslint-plugin-import/order.md at main · import-js/eslint-plugin-import
Enforce a convention in the order of require() / import statements. +(fixable) The--fix option on the [command line] automatically fixes problems reported by this rule. With the option set to ["builtin", "external", "internal", "parent", "sibling", "index", "object", "type"] the order is as shown in the following example: Unassigned imports are ignored, as the order they are imported in may be important.
eslint-plugin-import/order.md at main · import-js/eslint-plugin-import
https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md
eslint-plugin-import/order.md at main · import-js/eslint-plugin-import

네이밍

💡
컴포넌트명은 파스칼 케이스 ex) Header, Button 변수명, 함수명은 카멜 케이스 ex) isLogin

타입

파스칼 케이스로 Prefix 없이 정의한다.
Props는 해당 타입이 사용되는 파일 내부에 정의한다.

핸들러 함수

Prefix로 handle을 사용한다.
핸들러 함수의 타입은 React.ChangeEventHandler<HTMLInputElement> 와 같은 형태로 통일한다.

Prettier

🌺
코드 포맷팅을 위한 Prettier 설정은 아래와 같다.

Lint

🛠
코드 린팅을 위한 ESLint 설정은 아래와 같다.
🚨
만약 새로운 룰이 필요하거나 기존 룰 중에서 사용하지 않아야 할 룰이 있는 경우 1. 추가하거나 삭제해야 하는 이유를 노션에 문서로 정리한다. 2. 정리한 내용을 바탕으로 팀원들과 상의 후 결정한다.

함수 정의

🔊
function 키워드 대신 화살표 함수를 사용한 함수 표현식으로 함수를 정의한다.

Container? Wrapper?

단일 요소를 감싸야 한다면 Wrapper
2개 이상의 요소를 감싸야 한다면 Container

API 로직

 
├── api ├── assets ├── components │ └── Button │ ├── Button.styles.ts │ ├── Button.tsx │ └── index.ts ├── constants ├── hooks ├── recoil ├── pages ├── styles ├── interfaces ├── types └── utils
.selector { /* Positioning */ position: absolute; z-index: 10; top: 0; right: 0; /* Display & Box Model */ display: inline-block; overflow: hidden; box-sizing: border-box; width: 100px; height: 100px; padding: 10px; border: 10px solid #333; margin: 10px; /* Color */ background: #000; color: #fff /* Text */ font-family: sans-serif; font-size: 16px; line-height: 1.4; text-align: right; /* Other */ cursor: pointer; }
"import/order": [ "error", { "groups": ["builtin", "external", "internal", ["parent", "sibling"], "index"], "alphabetize": { "order": "asc", "caseInsensitive": true }, "newlines-between": "always" } ]
interface Props { name: String, password: String } const Login = ({ name, password }: Props) => { return (); }
const handleChange = () => {}
onChange: React.ChangeEventHandler<HTMLInputElement>
{ "printWidth": 120, "tabWidth": 2, "singleQuote": true, "semi": true, "bracketSpacing": true, "bracketSameLine": false, "jsxSingleQuote": true, "trailingComma": "all", "useTabs": false, "singleAttributePerLine": true, "endOfLine": "auto" }
{ "root": true, "parser": "@typescript-eslint/parser", "parserOptions": { "tsConfigRootDir": "./", "project": "./tsconfig.json" }, "plugins": ["@typescript-eslint"], "extends": [ "next/core-web-vitals", "airbnb", "airbnb-typescript", "plugin:react/jsx-runtime", "plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended-requiring-type-checking", "prettier" ] }
const handleSubmit = () => {}; const ComponentName = () => { return <div>hello</div>; }; export default ComponentName;
<Wrapper> <span>hi</span> </Wrapper>
<Container> <img src='/img/good.png' /> <span>hi</span> </Container>
// API 요청 함수 분리 const fetch = async (id: number) => { try { const { data: { data }, } = await axiosAuthInstance.get<Response<MatchRecord>>(`/api/matches/records`, { params: { userId: id }, }); return data } catch (error) { // 에러 처리 } } // 컴포넌트 내부 API 요청 React.useEffect(() => { setIsMatchLoading(true); (async () => { const matchRecord = await fetch(); setmatchRecord(() => matchRecord)); setIsMatchLoading(false); })(); }, [router.isReady])