본문 바로가기

Programming

Storybook으로 React 컴포넌트 문서화하기 - 실무 가이드

반응형

Storybook으로 React 컴포넌트 문서화하기 - 실무 가이드

🎯 왜 Storybook인가?

프론트엔드 개발을 하다 보면 이런 상황을 겪게 됩니다:

  • "이 버튼 컴포넌트 어떻게 쓰는 거지?"
  • "props가 뭐가 있더라?"
  • "디자이너님, 이 상태 확인해 주세요" (매번 로컬 서버 켜기...)

Storybook은 이 모든 문제를 해결합니다. 컴포넌트를 독립적으로 개발하고, 문서화하고, 테스트할 수 있는 워크샵이죠.


🚀 5분 만에 시작하기

설치

# 기존 React 프로젝트에 추가
npx storybook@latest init
설치가 끝나면 자동으로 .storybook 폴더와 예제 스토리가 생성됩니다.

실행

npm run storybook
# http://localhost:6006 에서 확인

첫 번째 Story 작성하기

Button 컴포넌트 예제

Button.tsx

interface ButtonProps {
  variant: 'primary' | 'secondary' | 'danger';
  size: 'sm' | 'md' | 'lg';
  children: React.ReactNode;
  disabled?: boolean;
  onClick?: () => void;
}

export const Button = ({ 
  variant = 'primary', 
  size = 'md', 
  children, 
  disabled,
  onClick 
}: ButtonProps) => {
  return (
    <button
      className={`btn btn-${variant} btn-${size}`}
      disabled={disabled}
      onClick={onClick}
    >
      {children}
    </button>
  );
};
Button.stories.tsx

import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';

const meta: Meta<typeof Button> = {
  title: 'Components/Button',
  component: Button,
  tags: ['autodocs'], // 자동 문서 생성!
  argTypes: {
    variant: {
      control: 'select',
      options: ['primary', 'secondary', 'danger'],
      description: '버튼 스타일',
    },
    size: {
      control: 'radio',
      options: ['sm', 'md', 'lg'],
      description: '버튼 크기',
    },
    onClick: { action: 'clicked' }, // 클릭 이벤트 로깅
  },
};

export default meta;
type Story = StoryObj<typeof Button>;

// 기본 버튼
export const Primary: Story = {
  args: {
    variant: 'primary',
    children: '확인',
  },
};

// 위험 버튼
export const Danger: Story = {
  args: {
    variant: 'danger',
    children: '삭제',
  },
};

// 비활성화 상태
export const Disabled: Story = {
  args: {
    variant: 'primary',
    children: '비활성화',
    disabled: true,
  },
};

// 모든 사이즈 한눈에
export const AllSizes: Story = {
  render: () => (
    <div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
      <Button variant="primary" size="sm">Small</Button>
      <Button variant="primary" size="md">Medium</Button>
      <Button variant="primary" size="lg">Large</Button>
    </div>
  ),
};

실무 활용 팁

1. MDX로 풍부한 문서 작성

Button.mdx

import { Meta, Story, Canvas, Controls } from '@storybook/blocks';
import * as ButtonStories from './Button.stories';

<Meta of={ButtonStories} />

# Button 컴포넌트

사용자 인터랙션을 위한 기본 버튼 컴포넌트입니다.

## 사용법

import { Button } from '@/components/Button';

<Button variant="primary" size="md">
  클릭하세요
</Button>

예제

<Canvas of={ButtonStories.Primary} />

Props

<Controls />

디자인 가이드라인

• Primary: 주요 액션에 사용 (저장, 확인, 제출)
• Secondary: 보조 액션에 사용 (취소, 이전)
• Danger: 삭제, 경고 등 주의가 필요한 액션

2. 폴더 구조 추천

src/
├── components/
│ ├── Button/
│ │ ├── Button.tsx
│ │ ├── Button.stories.tsx
│ │ ├── Button.test.tsx
│ │ └── index.ts
│ ├── Input/
│ └── Card/

3. 자동 배포 (GitHub Pages)

# .github/workflows/storybook.yml
name: Deploy Storybook

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm run build-storybook
      - uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./storybook-static

Storybook은 단순한 문서화 도구를 넘어, 컴포넌트 기반 개발의 핵심 인프라입니다.
오늘 바로 시작해 보세요!

반응형