Storybook 완벽 가이드 | UI 컴포넌트 개발·문서화·테스트·실전 활용
이 글의 핵심
Storybook으로 UI 컴포넌트를 개발하고 문서화하는 완벽 가이드. Stories, Args, Actions, Addons, Visual Testing까지 실전 예제로 정리. Storybook·UI·Component 중심으로 설명합니다.
이 글의 핵심
Storybook으로 UI 컴포넌트를 개발하고 문서화하는 완벽 가이드입니다. Stories, Args, Actions, Addons, Visual Testing까지 실전 예제로 정리했습니다.
실무 경험 공유: Storybook을 도입하면서, 컴포넌트 개발 속도가 50% 향상되고 디자이너와의 협업이 원활해진 경험을 공유합니다.
들어가며: “컴포넌트 개발이 비효율적이에요”
실무에서 마주치는 문제들
컴포넌트를 격리해서 개발하기 어려워요
전체 앱을 실행해야 합니다. Storybook은 격리된 환경을 제공합니다. 모든 상태를 테스트하기 어려워요
수동으로 상태를 만들어야 합니다. Storybook은 모든 상태를 Story로 정의합니다. 문서화가 번거로워요
별도로 문서를 작성해야 합니다. Storybook은 자동으로 문서화합니다.
1. Storybook이란?
핵심 특징
Storybook은 UI 컴포넌트 개발 도구입니다. 주요 장점
- 격리된 개발: 컴포넌트만 개발
- 모든 상태: Stories로 정의
- 자동 문서화: Props, Events
- Addons: 수백 개의 확장
- Visual Testing: 시각적 회귀 테스트
2. 설치 및 설정
React 프로젝트
npx storybook@latest init
수동 설치
npm install -D @storybook/react @storybook/react-vite storybook
.storybook/main.ts
import type { StorybookConfig } from '@storybook/react-vite';
const config: StorybookConfig = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/react-vite',
options: {},
},
};
export default config;
3. 첫 Story 작성
Button 컴포넌트
// src/components/Button.tsx
interface ButtonProps {
label: string;
variant?: 'primary' | 'secondary';
size?: 'small' | 'medium' | 'large';
onClick?: () => void;
}
export default function Button({ label, variant = 'primary', size = 'medium', onClick }: ButtonProps) {
return (
<button className={`btn btn-${variant} btn-${size}`} onClick={onClick}>
{label}
</button>
);
}
Story
// src/components/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'],
},
size: {
control: 'select',
options: ['small', 'medium', 'large'],
},
},
};
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = {
args: {
label: 'Primary Button',
variant: 'primary',
},
};
export const Secondary: Story = {
args: {
label: 'Secondary Button',
variant: 'secondary',
},
};
export const Small: Story = {
args: {
label: 'Small Button',
size: 'small',
},
};
export const Large: Story = {
args: {
label: 'Large Button',
size: 'large',
},
};
4. Args & Actions
Args
export const Interactive: Story = {
args: {
label: 'Click me',
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const button = canvas.getByRole('button');
await userEvent.click(button);
},
};
Actions
import { action } from '@storybook/addon-actions';
export const WithAction: Story = {
args: {
label: 'Click me',
onClick: action('button-clicked'),
},
};
5. Decorators
전역 Decorator
// .storybook/preview.tsx
import type { Preview } from '@storybook/react';
import '../src/index.css';
const preview: Preview = {
decorators: [
(Story) => (
<div style={{ padding: '3rem' }}>
<Story />
</div>
),
],
};
export default preview;
Story별 Decorator
export const Centered: Story = {
args: {
label: 'Centered Button',
},
decorators: [
(Story) => (
<div style={{ display: 'flex', justifyContent: 'center' }}>
<Story />
</div>
),
],
};
6. Parameters
TypeScript/JavaScript 예제 코드입니다.
export const DarkMode: Story = {
args: {
label: 'Dark Button',
},
parameters: {
backgrounds: {
default: 'dark',
},
},
};
7. Addons
인기 Addons
npm install -D @storybook/addon-a11y
npm install -D @storybook/addon-viewport
npm install -D @storybook/addon-storysource
.storybook/main.ts
const config: StorybookConfig = {
addons: [
'@storybook/addon-essentials',
'@storybook/addon-a11y',
'@storybook/addon-viewport',
'@storybook/addon-storysource',
],
};
8. Vue 통합
설치
npx storybook@latest init
Story
// src/components/Button.stories.ts
import type { Meta, StoryObj } from '@storybook/vue3';
import Button from './Button.vue';
const meta: Meta<typeof Button> = {
title: 'Components/Button',
component: Button,
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = {
args: {
label: 'Primary Button',
variant: 'primary',
},
};
9. Visual Testing
Chromatic
npm install -D chromatic
npx chromatic --project-token=YOUR_TOKEN
Storybook Test Runner
npm install -D @storybook/test-runner
{
"scripts": {
"test-storybook": "test-storybook"
}
}
10. 실전 예제: Form 컴포넌트
Input 컴포넌트
// src/components/Input.tsx
interface InputProps {
label: string;
type?: 'text' | 'email' | 'password';
placeholder?: string;
error?: string;
value?: string;
onChange?: (value: string) => void;
}
export default function Input({ label, type = 'text', placeholder, error, value, onChange }: InputProps) {
return (
<div className="input-group">
<label>{label}</label>
<input
type={type}
placeholder={placeholder}
value={value}
onChange={(e) => onChange?.(e.target.value)}
className={error ? 'error' : '}
/>
{error && <span className="error-message">{error}</span>}
</div>
);
}
Story
// src/components/Input.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import Input from './Input';
const meta: Meta<typeof Input> = {
title: 'Components/Input',
component: Input,
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof Input>;
export const Default: Story = {
args: {
label: 'Email',
type: 'email',
placeholder: 'john@example.com',
},
};
export const WithError: Story = {
args: {
label: 'Email',
type: 'email',
placeholder: 'john@example.com',
error: 'Invalid email address',
},
};
export const Password: Story = {
args: {
label: 'Password',
type: 'password',
placeholder: 'Enter password',
},
};
정리 및 체크리스트
핵심 요약
- Storybook: UI 컴포넌트 개발 도구
- 격리된 개발: 컴포넌트만 개발
- Stories: 모든 상태 정의
- 자동 문서화: Props, Events
- Addons: 수백 개의 확장
- Visual Testing: 시각적 회귀 테스트
구현 체크리스트
- Storybook 설치
- 첫 Story 작성
- Args 활용
- Actions 추가
- Decorators 사용
- Addons 설치
- Visual Testing 설정
- 문서화
같이 보면 좋은 글
이 글에서 다루는 키워드
Storybook, UI, Component, Documentation, Testing, React, Vue
자주 묻는 질문 (FAQ)
Q. 프로덕션 빌드에 포함되나요?
A. 아니요, 개발 도구로만 사용됩니다.
Q. 디자이너와 공유할 수 있나요?
A. 네, Storybook을 정적 사이트로 배포할 수 있습니다.
Q. 테스트 도구인가요?
A. 개발 도구이지만, Visual Testing도 지원합니다.
Q. 프로덕션에서 사용해도 되나요?
A. 네, 수많은 대기업에서 사용하고 있습니다.