Storybook — инструмент для разработки UI-компонентов в изоляции. Разработчик создаёт компонент и его stories (состояния) — Storybook рендерит их в браузере без запуска всего приложения. Дизайнер видит как выглядит Button в разных состояниях, QA тестирует граничные случаи, документация генерируется автоматически.
Установка и настройка
# Автоматическая настройка в существующем React+Vite проекте
npx storybook@latest init
# Запуск
npm run storybook # Открывает localhost:6006После инициализации появятся:
- .storybook/main.ts — конфигурация
- .storybook/preview.ts — глобальные декораторы и параметры
- src/stories/ — примеры stories
Написание Stories
// components/Button/Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
// Метаданные компонента
const meta: Meta<typeof Button> = {
title: 'UI/Button',
component: Button,
tags: ['autodocs'], // Автогенерация документации
argTypes: {
variant: {
control: 'select',
options: ['primary', 'secondary', 'ghost', 'danger'],
description: 'Визуальный вариант кнопки',
},
size: {
control: 'radio',
options: ['sm', 'md', 'lg'],
},
disabled: { control: 'boolean' },
loading: { control: 'boolean' },
},
};
export default meta;
type Story = StoryObj<typeof Button>;
// Stories — разные состояния компонента
export const Primary: Story = {
args: {
children: 'Основная кнопка',
variant: 'primary',
size: 'md',
},
};
export const Secondary: Story = {
args: {
children: 'Вторичная кнопка',
variant: 'secondary',
},
};
export const Loading: Story = {
args: {
children: 'Загрузка...',
loading: true,
},
};
export const Disabled: Story = {
args: {
children: 'Недоступна',
disabled: true,
},
};
// Интерактивный сценарий
export const WithInteraction: Story = {
args: { children: 'Нажми меня' },
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const button = canvas.getByRole('button');
await userEvent.click(button);
await expect(button).toHaveBeenClicked(); // Проверка в Storybook
},
};Декораторы: контекст для компонентов
// .storybook/preview.ts
import type { Preview } from '@storybook/react';
import { ThemeProvider } from '../src/providers/ThemeProvider';
import '../src/styles/global.css';
const preview: Preview = {
decorators: [
// Оборачиваем все stories в провайдеры
(Story) => (
<ThemeProvider>
<div style={{ padding: '1rem' }}>
<Story />
</div>
</ThemeProvider>
),
],
parameters: {
// Отключить анимации для тестирования
chromatic: { disableSnapshot: false },
},
};
export default preview;MSW Addon: мокинг API прямо в Storybook
// ProductCard.stories.tsx с моком API
import { http, HttpResponse } from 'msw';
export const WithAPI: Story = {
parameters: {
msw: {
handlers: [
http.get('/api/products/:id', ({ params }) => {
return HttpResponse.json({
id: params.id,
name: 'MacBook Pro M4',
price: 189900,
inStock: true,
});
}),
],
},
},
};Автодокументация с Autodocs
autodocs генерирует страницу документации из JSDoc и TypeScript types:interface ButtonProps {
/** Текст кнопки */
children: React.ReactNode;
/** Визуальный вариант */
variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
/** Размер кнопки */
size?: 'sm' | 'md' | 'lg';
/** Отключает кнопку */
disabled?: boolean;
/** Показывает индикатор загрузки */
loading?: boolean;
/** Обработчик клика */
onClick?: () => void;
}Storybook автоматически создаст таблицу с описанием каждого prop.
Chromatic: Visual Regression Testing
Chromatic (от команды Storybook) делает скриншоты всех stories после каждого коммита и показывает diff. Если кнопка случайно поменяла цвет — увидите визуально.
# Установка
npm install --save-dev chromatic
# Первый запуск — установка baseline
npx chromatic --project-token=<YOUR_PROJECT_TOKEN>
# GitHub Actions интеграция
# .github/workflows/chromatic.yml
name: Chromatic
on: push
jobs:
chromatic:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
- run: npm ci
- uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}Организация stories в крупном проекте
src/
├── components/
│ ├── ui/
│ │ ├── Button/
│ │ │ ├── Button.tsx
│ │ │ ├── Button.test.tsx
│ │ │ └── Button.stories.tsx
│ │ └── Input/
│ │ ├── Input.tsx
│ │ └── Input.stories.tsx
│ └── features/
│ ├── ProductCard/
│ │ ├── ProductCard.tsx
│ │ └── ProductCard.stories.tsx
│ └── CheckoutForm/
│ ├── CheckoutForm.tsx
│ └── CheckoutForm.stories.tsxFAQ
Storybook замедляет разработку?
На старте — небольшой overhead (написание stories). В долгосроке — ускоряет. Компоненты в изоляции разрабатываются быстрее, нет нужды гонять всё приложение для проверки одного компонента.
Storybook работает с Vue и Angular?
Да, Storybook поддерживает React, Vue, Angular, Svelte, Lit и другие. API stories унифицирован (Component Story Format 3).
Как деплоить Storybook для команды?
npm run build-storybook), GitHub Pages.Storybook vs Bit — в чём разница?
Bit — платформа для публикации и управления компонентами как независимыми пакетами. Storybook — инструмент разработки и документации. Они решают разные задачи.
Нужен ли Storybook если нет дизайн-системы?
Полезен даже без дизайн-системы. Визуализация состояний компонентов, изолированная разработка, автодокументация — всё это ценно в любом проекте с нетривиальным UI.
Настроим Storybook и дизайн-систему для вашего проекта
Установка, конфигурация, написание первых stories, интеграция с Chromatic. Компоненты, которые легко поддерживать.
Нужна помощь с разработка?
Обсудим задачу, предложим решение и рассчитаем стоимость — бесплатно, без обязательств.