Storybook 컴포넌트 개발
독립적인 컴포넌트 개발과 문서화
학습 항목
본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
이미지 로딩 중...
Storybook 최신 기능 완벽 가이드
Storybook 8.x의 최신 기능들을 중급 개발자를 위해 소개합니다. Component Story Format 3.0, 자동 문서화, 인터랙션 테스팅 등 실무에 바로 적용할 수 있는 핵심 기능들을 다룹니다.
들어가며
이 글에서는 Storybook 최신 기능 완벽 가이드에 대해 상세히 알아보겠습니다. 총 10가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.
목차
- Component_Story_Format_3.0
- Play_Function_인터랙션_테스팅
- Auto_Documentation_자동_문서화
- Conditional_Controls_조건부_컨트롤
- Viewport_Addon_반응형_테스트
- Component_Composition_합성_패턴
- Loaders_데이터_사전_로딩
- Decorators_공통_래퍼_적용
- Test_Coverage_Report_커버리지
- Vite_Builder_빠른_빌드
1. Component Story Format 3.0
개요
CSF 3.0은 더 간결한 문법으로 스토리를 작성할 수 있게 해주는 최신 포맷입니다. 기본 export만으로 args를 자동으로 전달받습니다.
코드 예제
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
component: Button,
};
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = {
args: { label: 'Click me', variant: 'primary' }
};
설명
template 함수 없이 args만으로 스토리를 정의할 수 있어 코드가 50% 이상 간결해집니다. TypeScript 타입 추론도 자동으로 지원됩니다.
2. Play Function 인터랙션 테스팅
개요
play 함수를 사용하면 컴포넌트의 사용자 인터랙션을 자동으로 테스트하고 시각화할 수 있습니다.
코드 예제
import { userEvent, within } from '@storybook/testing-library';
import { expect } from '@storybook/jest';
export const FilledForm: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await userEvent.type(canvas.getByRole('textbox'), 'test@email.com');
await userEvent.click(canvas.getByRole('button'));
await expect(canvas.getByText('Success')).toBeInTheDocument();
}
};
설명
스토리북 UI에서 자동으로 재생되는 인터랙션 시나리오를 작성하여 컴포넌트 동작을 검증하고 문서화할 수 있습니다.
3. Auto Documentation 자동 문서화
개요
TypeScript 타입과 JSDoc 주석을 자동으로 분석하여 Props 문서를 생성합니다. 별도 설정 없이 작동합니다.
코드 예제
interface ButtonProps {
/** 버튼에 표시될 텍스트 */
label: string;
/** 버튼 스타일 변형 @default 'primary' */
variant?: 'primary' | 'secondary' | 'danger';
/** 클릭 이벤트 핸들러 */
onClick?: () => void;
}
export const Button = ({ label, variant = 'primary' }: ButtonProps) => (
<button className={variant}>{label}</button>
);
설명
JSDoc 주석이 자동으로 Controls 패널과 Docs 페이지에 표시되어 개발자와 디자이너 모두 쉽게 이해할 수 있습니다.
4. Conditional Controls 조건부 컨트롤
개요
특정 props 값에 따라 다른 컨트롤을 동적으로 표시하거나 숨길 수 있는 기능입니다.
코드 예제
const meta: Meta<typeof Card> = {
component: Card,
argTypes: {
background: {
control: 'color',
if: { arg: 'variant', eq: 'custom' }
},
imageUrl: {
control: 'text',
if: { arg: 'hasImage', truthy: true }
}
}
};
설명
variant가 'custom'일 때만 background 컨트롤이 나타나고, hasImage가 true일 때만 imageUrl을 입력할 수 있어 UI가 깔끔해집니다.
5. Viewport Addon 반응형 테스트
개요
다양한 디바이스 해상도에서 컴포넌트가 어떻게 보이는지 즉시 확인할 수 있습니다.
코드 예제
export const Responsive: Story = {
parameters: {
viewport: {
viewports: {
mobile: { name: 'Mobile', styles: { width: '375px', height: '667px' } },
tablet: { name: 'Tablet', styles: { width: '768px', height: '1024px' } }
},
defaultViewport: 'mobile'
}
}
};
설명
툴바에서 클릭 한 번으로 다양한 화면 크기를 전환하며 반응형 디자인을 테스트할 수 있습니다.
6. Component Composition 합성 패턴
개요
여러 스토리를 조합하여 복잡한 시나리오를 재사용 가능하게 구성하는 패턴입니다.
코드 예제
import { Primary as PrimaryButton } from './Button.stories';
import { Default as DefaultInput } from './Input.stories';
export const LoginForm: Story = {
render: () => (
<form>
<DefaultInput.render {...DefaultInput.args} />
<PrimaryButton.render {...PrimaryButton.args} />
</form>
)
};
설명
기존 스토리들을 가져와서 조합하므로 DRY 원칙을 지키고 일관성 있는 문서를 유지할 수 있습니다.
7. Loaders 데이터 사전 로딩
개요
스토리가 렌더링되기 전에 비동기 데이터를 미리 로드하여 API 응답을 시뮬레이션합니다.
코드 예제
export const WithUserData: Story = {
loaders: [
async () => ({
user: await fetch('/api/user/1').then(res => res.json())
})
],
render: (args, { loaded: { user } }) => (
<UserProfile {...args} user={user} />
)
};
설명
MSW나 실제 API 없이도 로딩된 데이터를 스토리에 주입하여 다양한 데이터 상태를 재현할 수 있습니다.
8. Decorators 공통 래퍼 적용
개요
모든 스토리에 공통으로 적용될 래퍼 컴포넌트를 선언하여 일관된 환경을 제공합니다.
코드 예제
import { ThemeProvider } from 'styled-components';
import { theme } from './theme';
const meta: Meta = {
decorators: [
(Story) => (
<ThemeProvider theme={theme}>
<div style={{ padding: '20px' }}>
<Story />
</div>
</ThemeProvider>
)
]
};
설명
Provider, 레이아웃, 패딩 등을 중복 작성하지 않고 모든 스토리에 자동 적용되어 개발 효율이 높아집니다.
9. Test Coverage Report 커버리지
개요
스토리북의 play 함수들이 컴포넌트 코드를 얼마나 커버하는지 측정할 수 있습니다.
코드 예제
// .storybook/main.ts
export default {
stories: ['../src/**/*.stories.tsx'],
addons: ['@storybook/addon-coverage'],
framework: '@storybook/react-vite',
features: {
interactionsDebugger: true,
}
};
설명
npm run test-storybook -- --coverage 명령으로 인터랙션 테스트의 커버리지 리포트를 생성하여 테스트 품질을 관리할 수 있습니다.
10. Vite Builder 빠른 빌드
개요
Webpack 대신 Vite를 사용하여 스토리북 시작 시간을 10배 이상 단축시킵니다.
코드 예제
// .storybook/main.ts
import type { StorybookConfig } from '@storybook/react-vite';
const config: StorybookConfig = {
framework: '@storybook/react-vite',
core: {
builder: '@storybook/builder-vite'
},
viteFinal: (config) => {
return config;
}
};
export default config;
설명
HMR이 즉각적으로 반영되고 초기 로딩이 빨라져 대규모 프로젝트에서도 쾌적한 개발 경험을 제공합니다.
마치며
이번 글에서는 Storybook 최신 기능 완벽 가이드에 대해 알아보았습니다. 총 10가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.
관련 태그
#Storybook #CSF3.0 #Component #Testing #Documentation