Skip to content

[FE] 컨벤션

Gyaak edited this page Sep 25, 2024 · 1 revision

기술 스택

Category Tool/Library Version
Framework Next.js
Package Manager Yarn Berry @4.3.1
Notification Library react-hot-toast
UI and Styling radix-ui, vanilla-extract
Linting and Formatting ESLint, Prettier, TypeScript @5.5.4
State Management zustand, tanstack query
Component Testing Storybook
E2E Testing Playwright
Utility Testing Jest
Git Hooks and Automation husky

코드 컨벤션

디렉토리 설계 (Inspired by fsd)

아래 다이어그램은 각 요소가 어떻게 서로 연결되어 있는지를 나타냅니다.

예를 들어, widgetcomponentfeature를 사용하고, featureapilib에서 필요한 로직이나 데이터를 가져오는 구조입니다.

이런 구조는 기능 단위로 프로젝트를 분리하면서도, 재사용 가능한 컴포넌트와 로직을 적절히 활용할 수 있게 해 줍니다.

이미지

app:

  • app 폴더는 페이지나 전역 설정을 담당하는 부분입니다.
  • 앱의 전반적인 구조를 관리하는 곳으로, 전역 상태 관리나 라우팅 등의 중요한 로직들이 위치하는 곳입니다.

widget:

  • widget 폴더는 더 복잡한 UI 컴포넌트로, 재사용 가능한 큰 UI 블록들을 의미합니다.
  • 여러 기능에 걸쳐 사용할 수 있는 복합적인 UI 요소들이 여기에 속할 수 있습니다.

feature:

  • features 폴더는 특정 기능들을 독립적으로 구현한 영역입니다.
  • 기능 단위로 코드를 모듈화해 관리하는 역할을 합니다.
  • 각 기능은 여러 컴포넌트, API 호출, 비즈니스 로직, 상태 관리 등을 포함할 수 있습니다.

component:

  • components 폴더는 재사용 가능한 UI 컴포넌트들을 모아 놓는 곳입니다.
  • widget이나 feature 안에서 사용되며, 공통적인 UI 요소를 관리합니다.

api:

  • 서버와의 통신, 데이터 처리와 관련된 부분입니다. 이곳에서 API 호출, 데이터 관리, 비즈니스 로직을 처리합니다. apis 폴더가 이러한 기능을 담당합니다.

lib :

  • 공통된 유틸리티 함수나 상태 관리 로직이 들어가는 곳입니다.
  • 상태나 util들이 포함될 수 있습니다.

hook:

  • React의 커스텀 훅을 정의한 곳입니다.
  • 상태 관리나 사이드 이펙트 처리 등 공통된 로직을 모듈화하여 여러 곳에서 재사용할 수 있도록 합니다.

JavaScript/TypeScript 규칙

  • Prettier

    {
      "printWidth": 80,
      "tabWidth": 2,
      "useTabs": false,
      "semi": true,
      "singleQuote": true,
      "trailingComma": "es5",
      "bracketSpacing": true,
      "arrowParens": "always"
    }
    
  • ESLint

    {
      "extends": [
        "next/core-web-vitals",
        "next/typescript",
        "plugin:storybook/recommended",
        "plugin:storybook/recommended",
        "plugin:react/recommended",
        "next/core-web-vitals",
        "prettier"
      ]
    }

React 규칙

  • 컴포넌트 네이밍: 파일명과 컴포넌트명은 PascalCase로 통일합니다.
    • 예: UserProfile.tsx, Header.tsx.
  • 함수형 컴포넌트: 더 간결한 코드와 React Hooks 사용을 위해 함수형 컴포넌트를 사용합니다.
  • Hooks 사용 규칙: React Hooks 사용 시 useState, useEffect 등의 사용을 철저히 관리합니다.
    • Custom Hook은 use로 시작.
    • Side effect는 useEffect에서만 처리.

스타일링

Vanilla Extract 스타일링 규칙

  • 파일 구조: 스타일 파일을 컴포넌트별로 관리하고, 각 컴포넌트 폴더 내에 .css.ts 파일을 둡니다.

    • 예시: Button.css.ts, Header.css.ts.
  • 변수 및 타입 정의: Vanilla Extract의 강점 중 하나는 타입 지원입니다. 색상, 폰트 크기 등의 스타일 값을 변수로 추출하고 이를 .css.ts 파일에서 정의합니다.

    • 예시: colors.ts, spacing.ts와 같은 파일에 스타일 변수들을 관리.
  • Scoped 스타일링: 각 컴포넌트에 스코프된 스타일을 정의하여 전역 스타일 충돌을 방지합니다. style 함수와 styleVariants를 사용해 스타일 변형을 쉽게 관리합니다.

    • 예시:

      import { style } from '@vanilla-extract/css';
      
      export const button = style({
        padding: '10px',
        backgroundColor: 'blue',
      });
  • 반응형 디자인: 미디어 쿼리를 사용할 때는 Vanilla Extract의 globalStyle 또는 @vanilla-extract/recipes 패키지의 recipe API를 활용하여 반응형 스타일을 쉽게 관리합니다.

Git Hooks

Husky와 lint-staged 설정

코드 스타일과 테스트를 커밋 전에 자동으로 체크하도록 Husky와 lint-staged를 설정합니다.

  • Prettier, ESLint로 JavaScript/TypeScript 코드의 린팅을 자동화.
  • Vanilla Extract의 CSS도 자동으로 포맷팅되도록 Prettier 설정에 포함.

테스팅

Storybook 테스트 규칙

  • 파일 구조: 컴포넌트별로 .stories.tsx 파일을 만들어 Storybook에서 각 컴포넌트의 다양한 변형을 테스트합니다.
    • 예시: Button.stories.tsx, Header.stories.tsx.
  • 스토리 작성 규칙: 기본 컴포넌트 및 다양한 상태(variant)별로 스토리를 정의합니다.
    • 예시:

      import { Button } from './Button';
      
      export default {
        title: 'Components/Button',
        component: Button,
      };
      
      export const Primary = () => <Button variant="primary">Primary Button</Button>;
      export const Secondary = () => <Button variant="secondary">Secondary Button</Button>;