React + Storybook: библиотека компонентов

Быстрые ссылки
- Что такое Storybook?
- Инициализация проекта React
- Добавление Storybook
- Написание компонентов
- Сборка с Babel
- Публикация и советы
- Проверки и приемка
- Альтернативы и миграция
- Итог
React — одна из основных технологий для разработки фронтенда на JavaScript. Архитектура React естественно компонентная: приложение строится из переиспользуемых, автономных блоков. Логичный следующий шаг — вынести базовые UI‑компоненты в библиотеку: это ускоряет старт новых проектов и упрощает поддержку единообразного дизайна.
В этой статье мы шаг за шагом создадим простую библиотеку React‑компонентов, добавим Storybook для визуализации и документации, а затем настроим сборку через Babel для публикации в npm. Это обзорный, практический гид: достаточно деталей, чтобы запустить поток разработки компонентов и сделать пакет для использования в приложениях.
Что такое Storybook?
Storybook — инструмент для разработки и отображения компонентов в изоляции, вне контекста приложения. Он позволяет:
- просматривать компоненты в веб‑интерфейсе;
- описывать примеры использования (stories);
- документировать props/args и играть с ними в реальном времени;
- воспроизводить события (actions) и просматривать логи.
Storybook не привязан к React: он работает с Angular, Vue, Svelte и другими фреймворками, но в этой статье мы фокусируемся на использовании с React.

Компоненты остаются теми же, что и в обычном проекте. Для Storybook вы добавляете companion‑файл с суффиксом .stories.js, в котором описываете вариации компонента — «истории», используемые в UI Storybook. Storybook автоматически находит такие файлы по шаблонам, указанным в конфигурации.
Инициализация проекта React
Для примера используем Create React App (CRA) — он быстро создаёт проект и включает готовую структуру. В терминале выполните:
npx create-react-app my-componentsПри первом запуске подтвердите установку, нажав y, и дождитесь окончания. Перейдите в созданную папку my-components. CRA создаст public и src и добавит зависимости в package.json.

Поскольку мы создаём библиотеку, а не приложение, можно удалить часть артефактов CRA (например, демонстрационные файлы в src/public) и оставить структуру, удобную для разработки модулей.
Добавление Storybook
Установить Storybook в проект CRA очень просто:
npx sb init
Инсталлятор добавит директории .storybook и stories (примеры). В нашей библиотеке папка stories обычно не нужна — мы поместим истории рядом с компонентами в src. Удалите stories, если хотите.
Внутри .storybook находятся файлы конфигурации. Главные из них:
main.js— глобальные настройки, в том числе шаблоны поиска stories;preview.js— контекст для рендера (провайдеры, глобальные декораторы и т.д.).
Измените поле stories в .storybook/main.js, чтобы Storybook искал *.stories.* внутри src:
module.exports = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
// ... остальные настройки
};Этот шаблон указывает на поиск файлов с суффиксом .stories.js, а также .jsx, .ts, .tsx.
Совет: если вы используете TypeScript — добавьте соответствующие пресеты и расширения к конфигу Storybook.
Написание компонентов
Пишем компонент так же, как в любом React‑проекте. Ниже — простой кнопочный компонент и его история. Обратите внимание: компоненты не нуждаются в изменениях ради Storybook; требуется лишь файл .stories.js с описанием историй.
Код компонента Button (сохраните в src/Button.js):
import PropTypes from "prop-types";const styles = {
background: “#fff”,
border: “0.2rem solid #0099ff”,
color: “#0099ff”,
letterSpacing: “0.1em”,
fontWeight: “bold”,
padding: “1em”,
textTransform: “uppercase”
};
const Button = ({disabled, label, onClick}) => (
);
Button.propTypes = {
disabled: PropTypes.bool,
label: PropTypes.label,
onClick: PropTypes.func
};
Button.defaultProps = {
disabled: false
};
export default Button;
Пример истории `src/Button.stories.js`:
import Button from “./Button.js”;
export default {
title: "Button",
component: Button,
args: {
label: "Demo Button"
}
};
const Template = args => ;
const Standard = Template.bind({});
const Disabled = Template.bind({});
Disabled.args = {disabled: true, label: "Disabled Button"};
export {Standard, Disabled};Ключевые понятия:
- default export — метаданные для Storybook (title, component, args);
- args — эквивалент props и удобный способ задавать значения для панели Controls;
- именованные экспорты — отдельные истории (вариации) компонента.
Запустите dev‑сервер Storybook:
npm run storybook
Откройте в браузере http://localhost:6006 и найдите ваш компонент в боковой панели. Нажмите на историю — увидите отрисованный компонент и панели Controls/Actions.

Панель Controls позволяет менять props в реальном времени. Actions логирует события (наши onClick и прочие колбэки).

Важно: Storybook анализирует propTypes и другие подсказки, чтобы автоматически генерировать контролы.
Сборка с Babel
Чтобы распространять библиотеку как npm‑пакет, нужно публиковать транспилированный код. Create React App в проектах‑клиента не транслирует JSX внутри node_modules, поэтому нельзя публиковать «сырые» JSX‑файлы — потребитель получит ошибку при сборке.
- Создайте входную точку API в
src/index.js:
import Button from "./Button.js";export {Button};
2) Установите dev‑зависимости Babel:
npm install –save-dev
@babel/cli
@babel/plugin-transform-react-jsx
@babel/preset-env
@babel/preset-react
3) Создайте `.babelrc` в корне проекта:
{
“presets”: [
“@babel/preset-env”,
“@babel/preset-react”
],
“plugins”: [
[
“@babel/plugin-transform-react-jsx”,
{
“runtime”: “automatic”
}
]
]
}
Эта конфигурация включает поддержку нового JSX‑transform (runtime: automatic), поэтому не обязательно импортировать React в файлах с JSX.
4) Добавьте скрипты сборки в `package.json`:
“scripts”: {
“prepare”: “npm run dist”,
“dist”: “rm -rf dist/ && babel src/ –out-dir dist –copy-files –no-copy-ignored –ignore src/**/.stories.js”
}
Скрипт `prepare` будет автоматически выполняться npm перед публикацией. `dist` создаёт собранную версию в папке `dist`, игнорируя файлы историй (они не нужны в npm‑пакете).
5) Укажите, какие файлы публиковать и главный файл пакета в `package.json`:
{
“files”: [
“dist”
],
“main”: “dist/index.js”
}
После этого `npm publish` отправит только содержимое `dist`, а потребители смогут импортировать ваш API через `import {Button} from "@example/example-components";`.

Советы:
- добавьте `dist` в `.gitignore`;
- храните исходники в `src`, тесты в `__tests__` или `tests`;
- настройте `engines` в `package.json`, если требуются минимальные версии Node.js.
## Публикация: playbook
Ниже — упрощённый SOP для публикации новой версии библиотеки.
Шаги публикации:
1. Обновите версию в `package.json` (semver).
2. Убедитесь, что все тесты и линтеры проходят.
3. Запустите `npm run dist` локально и проверьте артефакты в `dist`.
4. Проверьте, что `main` указывает на `dist/index.js` и `files` содержит только нужные каталоги.
5. Добавьте CHANGELOG или release notes в Git.
6. Запушьте изменения в git и создайте тег (git tag vX.Y.Z).
7. Выполните `npm publish` (или используйте CI/CD, который выполнит `npm publish` при пуше тега).
8. Проверка после публикации: в новом CRA‑проекте установите пакет и проверьте базовый импорт.
Совет: автоматизируйте шаги через CI (GitHub Actions, GitLab CI) — выполняйте `npm run dist` и `npm publish` только в защищённом окружении.
## Критерии приёмки
Перед тем как пометить релиз как готовый, убедитесь, что:
- Компоненты корректно рендерятся в Storybook и в реальном приложении.
- Все автотесты (unit/visual) проходят.
- Не осталось «магических» глобальных стилей, которые меняют внешний вид компонентов.
- API (имена экспорта) не изменились без мажорного релиза.
- Документация в stories покрывает ожидаемые варианты использования.
## Тесты и кейсы приёмки
Типовые тест‑кейсы:
- Unit: Button рендерится с заданным label.
- Unit: Disabled Button не вызывает onClick.
- Snapshot: визуальное совпадение базовой истории Standard.
- Интеграция: импорт пакета в свежий CRA и рендер без ошибок сборки.
Примеры acceptance criteria:
- Кнопка с disabled пропс не вызывает колбэк (acceptance).
- Storybook показывает Controls для всех настраиваемых props.
## Роли и чек‑листы
Разделение ответственности помогает организовать релизы.
Разработчик:
- Пишет компонент и истории.
- Пишет unit‑тесты и снапшоты.
- Следит за покрытием и линтером.
Владелец библиотеки/maintainer:
- Проверяет API и совместимость с предыдущими релизами.
- Обновляет CHANGELOG и версии.
- Настраивает CI и публикацию.
QA:
- Проверяет Storybook, проверяет визуальное поведение в разных браузерах.
- Тестирует импорт пакета в реальном приложении.
## Альтернативные подходы и когда они лучше
- Если вам нужна монорепозитория с несколькими пакетами — рассмотрите Lerna или Yarn Workspaces + Rollup. Эти инструменты удобнее для монолитов с большим количеством пакетов.
- Для библиотек, ориентированных на ES‑модули и оптимизацию сборки у потребителя, используйте Rollup (обычно даёт более компактные бандлы).
- Если вы используете современный стек TypeScript — добавьте tsc в pipeline и выдавайте типы (`.d.ts`) вместе с компиляцией.
Когда этот подход не подходит:
- Небольшим проектам из одного‑двух компонентов может хватить простого копирования кода между проектами.
- Если вы целиком полагаетесь на глобальные CSS, то компоненты могут выглядеть по‑разному при переносе. Решение — использовать CSS‑модули или styled components.
## Ментальные модели и эвристики
- Компонентная библиотека — это контракт. Меняйте API аккуратно; документируйте и версионируйте.
- Storybook — инструмент «песочницы» и документации; не заменяет e2e‑тесты и интеграцию в реальном приложении.
- Сборка — одноразовый акт перед публикацией: исходники остаются в `src`, пакет содержит только `dist`.
## Матричная совместимость и советы по миграции
Совместимость версий (рекомендации):
- React: поддерживайте диапазон React 16.8+ если используете хуки; явно указывайте peerDependencies.
- Babel: используйте актуальные пресеты, тестируйте Babel‑сборку в CI.
- Storybook: крупные обновления Storybook иногда ломают конфигурацию; обновляйте его отдельно и тестируйте stories.
Советы по миграции потребителей:
- При изменении API делайте мажорный релиз.
- Предоставьте миграционный гайд в CHANGELOG с примерами до/после.
## Безопасность и приватность
- Не включайте секреты и конфигурации в публикуемый пакет.
- Если компоненты обрабатывают пользовательские данные, проверьте, что они не логируют приватную информацию в Actions во время демонстраций.
- При хранении персональных данных в компонентах (например, аватары) учитывайте требования локального законодательства по хранению и обработке данных.
## Risk matrix и способы смягчения
- Риск: изменение API ломает потребителей — Смягчение: семантическое версионирование, тесты обратной совместимости.
- Риск: глобальные стили ломают внешний вид — Смягчение: изолируйте стили (CSS‑модули, BEM, shadow DOM).
- Риск: публикация приватных ключей — Смягчение: проверка артефактов `dist` перед публикацией, аудит CI.
## Примеры/шаблоны (cheat sheet)
package.json (ключевые поля):
{ “name”: “@example/example-components”, “version”: “1.0.0”, “main”: “dist/index.js”, “files”: [“dist”], “scripts”: {
"dist": "rm -rf dist/* && babel src/ --out-dir dist --copy-files --no-copy-ignored --ignore src/**/*.stories.js",
"prepare": "npm run dist"}, “peerDependencies”: {
"react": ">=16.8"} }
Мини‑чеклист перед публикацией:
- [ ] Все тесты проходят
- [ ] Storybook отображает основные истории
- [ ] `npm run dist` создаёт корректный `dist`
- [ ] `package.json` содержит `main` и `files`
- [ ] CHANGELOG готов
## Decision tree (Mermaid)
flowchart TD A[Начало разработки компонента] –> B{Нужен ли Storybook?} B – Да –> C[Создать компонент + .stories.js] B – Нет –> D[Только компонент в src] C –> E{Нужна публикация в npm?} D –> E E – Да –> F[Добавить Babel, настроить dist и prepare] E – Нет –> G[Остановиться: компонент используется локально] F –> H[Запустить тесты и CI] H –> I{Все тесты OK?} I – Да –> J[Публиковать пакет] I – Нет –> K[Исправить баги и повторить]
## Сравнение подходов (краткая матрица)
| Задача | CRA + Storybook + Babel | Rollup + Storybook | Monorepo (Yarn/Lerna) |
|---|---:|---:|---:|
| Простота старта | Высокая | Средняя | Сложная |
| Контроль над бандлом | Средний | Высокий | Высокий |
| Поддержка множественных пакетов | Средний | Средний | Высокая |
| Требуется конфигурация | Низкая | Средняя | Высокая |
## Edge cases / Галерея проблем
- Плавающие CSS‑переменные от глобального стиля приложения могут менять кнопки. Решение — локализовать стили.
- Если ваш компонент ожидает специфичный `context` (например, тема), добавьте декоратор в `preview.js`, чтобы Storybook рендерил компонент в правильном окружении.
- TypeScript: если вы публикуете `.d.ts` файлы, убедитесь, что они соответствуют реальному API.
## Примеры миграции кода потребителя
До:
import Button from “../../local/components/Button”;
После (после публикации пакета):
import {Button} from “@example/example-components”;
## Короткое объявление (announce)
Готова первая версия библиотеки React‑компонентов: включает базовую кнопку, Storybook‑документацию и пайплайн сборки через Babel. Пакет публикуется как `@example/example-components` и готов к установке в приложениях через npm.
## Social preview
OG title: React + Storybook: библиотека компонентов
OG description: Пошаговое руководство по созданию, документированию и публикации библиотеки React‑компонентов с помощью Storybook и Babel.
## Итог
Создание библиотеки React‑компонентов — это инвестиция, которая окупается в скорости разработки и единообразии интерфейсов. Storybook упрощает разработку и документацию, а Babel позволяет безопасно публиковать готовые артефакты. Автоматизируйте сборку и публикацию через CI, документируйте изменения и тестируйте интеграцию в реальных приложениях.
Короткие ключевые рекомендации:
- Пишите компоненты чисто и изолированно.
- Используйте Storybook для визуальной документации и тестирования.
- Транспилируйте и публикуйте только `dist`.
- Версионируйте и автоматизируйте релизы.
---
ЗАМИТКА: В статье приведены практические примеры и шаблоны, которые можно адаптировать под конкретный проект.Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента