Обзор: Я был очень взволнован, когда на прошлой неделе прочитал объявление о выпуске Storybook 3.4, поэтому решил написать статью о Storybook. В этой статье мы рассмотрим, как мы можем создать лучший проект React с помощью Storybook и поиграться с некоторыми дополнениями, которые предлагает Storybook, мы также интегрируем Storyshots в наш рабочий процесс, чтобы мы могли получать как структурные снимки, так и снимки изображений для лучшей регрессии пользовательского интерфейса. Тестовое задание. Демо

Когда вы работаете над проектом React, обычно вы определяете повторно используемые части приложения в виде компонентов. Может наступить время, когда размер вашего проекта React резко увеличится и вырастет из-под контроля до такой степени, что вы или члены вашей команды даже не знаете, как выглядит компонент, или, возможно, член вашей команды создал еще одну кнопку компонент только потому, что он / она не знает, создал ли кто-то его раньше. Это очевидные признаки того, что вам может понадобиться Storybook в вашем проекте.

Итак, что такое Storybook и почему мы должны его использовать? Согласно собственному определению Storybook, это среда разработки пользовательского интерфейса, которую вы хотели бы использовать (я действительно люблю ее использовать, я думаю, вам тоже стоит!). Storybook позволяет просматривать компоненты внутри проекта, изменять его состояние, а также разрабатывать и тестировать его в интерактивном режиме. Он работает за пределами области действия вашего приложения, поэтому вы можете разрабатывать свои компоненты, не беспокоясь о зависимостях приложений, поэтому, если ваш дизайнер хочет изменить цвет кнопки с красного на синий, вместо того, чтобы беспокоиться о некоторых ошибках в ваших приложениях из-за ваших пьяных коммитов прошлой ночью , он / она может просто запустить сборник рассказов и напрямую изменить компонент.

Storybook из коробки поддерживал несколько интерфейсных фреймворков, основные интерфейсные фреймворки, такие как React, React Native, Angular и Vue (наконец-то мы кое-что согласовали, ребята из Angular и Vue! ) уже довольно давно поддерживаются, в последней версии также добавлена ​​поддержка Полимера.

Установка Storybook

Первый очевидный шаг к работе с Storybook - это его установка. Чтобы упростить процесс настройки, команда Storybook создала инструмент CLI для интеграции Storybook в существующий проект, вы можете установить этот инструмент глобально с помощью следующей команды:

yarn global add @storybook/cli

или если вы предпочитаете использовать npm вместо пряжи:

npm i -g @storybook/cli

После завершения установки перейдите в свой проект React и просто запустите getstorybook:

cd my-react-project
getstorybook

Затем интерфейс командной строки Storybook умело определит архитектуру вашего проекта, а затем установит Storybook в соответствии с потребностями проекта, поэтому не имеет значения, используете ли вы приложение create-response-app или просто веб-пакет, все, что вам нужно для установки Storybook, - это просто простая одиночная команда!

Затем вы должны убедиться, что Storybook был установлен правильно, для этого вы можете просто запустить:

yarn run storybook

и перейдите по адресу http: // localhost: 9009 /, вы увидите это, если Storybook был установлен правильно:

Настройка установки Storybook

Вся конфигурация Storybook для вашего проекта будет находиться в .storybook каталоге, вы найдете этот каталог в корневом каталоге вашего проекта. Есть несколько файлов, которые можно использовать для настройки установки сборника рассказов:

  • config.js - в этом файле вы можете настроить конфигурацию для установки Storybook.
  • addons.js - с помощью этого файла можно зарегистрировать надстройки Storybook.
  • preview-head.html. Вы можете использовать этот файл, если хотите вставить теги в тег head в сборнике рассказов. Этот файл может быть полезен, если у вас есть внешние скрипты, файлы css. , или, может быть, шрифты, которые нужно внедрить, а не объединить в ваше приложение.
  • webpack.config.js - Storybook автоматически использует собственную конфигурацию веб-пакетов по умолчанию, вы можете расширить их конфигурацию веб-пакетов по умолчанию с помощью этого файла, если, например, вам нужен другой загрузчик веб-пакетов для вашего проекта. Более подробную информацию о настройке конфигурации веб-пакета для Storybook можно найти здесь.
  • .babelrc - по умолчанию Storybook загружает .babelrc из корневого каталога проекта. Если вам нужно исключить некоторые правила для среды Storybook, вы можете предоставить этот файл, чтобы в Storybook загружались только правила из этого файла.

Исходя из моих личных предпочтений, я обычно хочу, чтобы мои файлы историй располагались рядом с соответствующими файлами компонентов React, поэтому вместо одного большого каталога stories/ я бы поставил его так:

components/
    button/
       button.js
       button.stories.js
       button.css

Для этого нам нужно изменить config.js функцию loadStories следующим образом:

к этому:

В приведенном выше примере мы использовали require.context из Webpack для загрузки всех файлов, которые заканчиваются на .stories.js, поэтому, когда мы добавляем новый файл истории, нам не нужно указывать его снова и снова.

Написание нашей первой истории

Довольно конфигурации, давайте напишем нашу первую историю. В этом примере мы будем использовать проект из моей предыдущей публикации Написание многоразового Redux как босс. Причина, по которой мы используем этот проект, заключается в том, чтобы лучше продемонстрировать, как мы можем разработать наш компонент пользовательского интерфейса, даже не затрагивая бизнес-логику, которая уже была там a̶n̶d̶̶ ̶I̶’̶m̶ ̶t̶o̶o̶ ̶l̶a̶z̶y̶ ̶t̶o̶ ̶w̶r̶i̶t̶e̶ ̶a̶n̶o̶t̶eee̶e̶e̶e̶.

В этом примере мы напишем историю для компонента виджета курсов:

Компонент Courses Widget отвечает за отображение списка курсов, на которые пользователи могут записаться на нашем сайте React News, он получает массив курсов и отображает их.

Чтобы создать историю, мы просто импортируем storiesOf from@storybook/react, а затем добавляем каждую из записей нашей истории, как в приведенном выше примере. Затем вы можете снова запустить свой сборник рассказов, и вы сразу увидите историю:

Чтобы лучше документировать наш компонент «Виджет курсов», мы хотим рассказать всем, кто видит эту историю, можно ли на самом деле нажать нашу кнопку регистрации. Прямо сейчас, если вы нажмете кнопку регистрации, ничего не произойдет, мы изменим это с помощью нашего первого дополнения.

Установка нашего первого аддона

Установить аддоны для Storybook также довольно просто, для нашего первого аддона мы добавим аддон действие. Для этого сначала нам нужно установить его пряжей:

yarn add --dev @storybook/addon-actions

или npm:

npm i -D @storybook/addon-actions

Обычно мы хотим установить надстройки для сборников рассказов в devDependencies, чтобы не загрязнять наши производственные зависимости, в конце концов, нам это не нужно в наших производственных сборках. После того, как мы закончили установку аддонов, нам нужно зарегистрировать его, чтобы Storybook мог использовать его позже, чтобы зарегистрировать наши аддоны, мы можем просто импортировать его в наш addons.js файл в .storybook каталоге:

Затем мы можем определить действия внутри нашего courses-widget.stories.js:

Теперь, когда вы нажимаете кнопку Enroll, он регистрирует действие внутри регистратора действий:

Если вы нажмете кнопку регистрации, и она ничего не ответит, вы узнаете, что что-то пошло не так, и это объясняет, почему эти нетерпеливые умы не могут записаться на наши курсы в последние несколько дней.

Создайте простую документацию с помощью надстройки Info

Мы создали библиотеку компонентов с помощью Storybook, можно было бы написать документацию внутри нее, а ?. Что ж, мы можем автоматически сгенерировать документацию с помощью аддона info:

Сначала установите его с помощью:

yarn add --dev @storybook/addon-info

Чтобы лучше удовлетворить наши потребности, мы сделаем несколько настроек внутри config.js:

Поскольку надстройка Info хорошо интегрируется с react-docgen из коробки, для создания таблицы типов опор мы могли бы использовать prop-types или, если вам нужны более продвинутые варианты использования, вы могли бы использовать flow, они в основном проверяют типы данных ваших опор. поэтому его можно использовать только для одного типа данных на протяжении всего жизненного цикла вашего приложения. Я мог бы написать о статической проверке типов и о том, почему они здесь классные, но давайте оставим это на другой день, а пока все, что вам нужно сделать, это установить Flow с помощью следующих команд:

yarn add --dev flow-bin
yarn run flow init

Затем нам нужно будет определить типы потоков в нашем компоненте виджета курсов:

Затем в файл истории компонента виджета курса мы добавим новую запись истории, обернутую функцией withInfo:

Тестирование снимков с помощью Storyshots

Storyshots позволяет нам автоматически добавлять тестирование снимков с помощью Storybook. Благодаря Storyshots нам не нужно указывать другие тесты моментальных снимков в нашей среде тестирования, такие как Jest, мы просто используем наши истории, которые мы создали ранее. Чтобы использовать Storyshots, сначала мы установим его с помощью:

yarn add --dev @storybook/addon-storyshots

Затем мы можем просто добавить новый тестовый файл в наш ./src каталог для инициализации Storyshots:

Если мы запустим наши наборы тестов с yarn run test, мы сможем увидеть наши снимки, созданные в каждом каталоге нашего компонента.

Теперь, когда вы измените структуру своего компонента, вы получите предупреждение о том, что что-то изменилось:

Когда эти изменения ожидаются, вы можете просто нажать u, чтобы обновить сбойные снимки, или нажать i, чтобы обновить сбойные снимки в интерактивном режиме.

С помощью структурного моментального тестирования мы можем сравнить, как выглядит структура компонента, и можем проводить регрессионные тесты на ее основе. Но он не может охватить изменения, которые могут происходить визуально, например, если вы или члены вашей команды изменили некоторые правила CSS и визуально изменили компонент, вы не сможете уловить эту регрессию с помощью простого структурного регрессионного теста.

К счастью, в Storybook 3.4, помимо использования наших историй для тестирования структурных снимков, мы можем использовать их также для тестирования визуальных снимков. для этого мы можем просто инициализировать другой пакет Storyshots:

Что Storyshots делает при тестировании снимков изображений, это в основном переход к заданному URL-адресу Storybook с помощью браузера без головы (кукловод), захват скриншотов каждой из наших историй и сохранение их в виде изображений для проведения визуальных регрессионных тестов позже. Затем можно провести визуальные регрессионные тесты с помощью шутка-изображение-снимок. Итак, чтобы иметь возможность запустить тестирование снимков нашего изображения, нам нужно сначала запустить наш экземпляр Storybook с yarn storybook или создать статический с yarn build-storybook.

Вместо того, чтобы запускать два сценария каждый раз, когда мы хотим запустить наши наборы тестов, мы можем использовать npm-run-all, чтобы запустить все сразу, и wait-port, чтобы дождаться, пока Storybook будет готов обработать запрос. Давайте установим npm-run-all и wait-port с помощью:

yarn add --dev npm-run-all wait-port

Затем в package.json мы можем создать новый скрипт для его запуска:

Теперь мы можем запускать наши тесты с yarn test:watch. Когда вы снова запустите тесты, вы увидите, что снимки изображений были успешно созданы внутри __image_snapshots__ каталога:

Когда вы меняете некоторые правила CSS, Jest выдаст предупреждение о том, что визуальная регрессия не удалась, и спросит, ожидалось это или нет:

Затем мы можем проверить разницу в созданном файле сравнения:

С помощью визуального тестирования снимков мы можем быть уверены, что держим наши визуальные изменения под контролем, вместо того, чтобы проверять каждый компонент вручную, мы сохранили скучную работу для нашей среды тестирования.

Пока что я доволен результатами, но здесь можно исправить две проблемы:

  1. Мы не хотим делать тесты снимков для наших файлов Read Me, поскольку они предназначены только для целей документации, будет сложно обновлять снимки каждый раз, когда мы обновляем наши файлы Read Me.
  2. Мы хотим сохранить файл снимков нашего изображения относительно связанных с ним компонентов.

Что касается первой проблемы, мы можем завершить нашу историю Read Me простой NODE_ENV проверкой:

Что касается второй проблемы, поскольку снимок изображения StoryShots использует внутренний снимок jest-image-snapshot, мы могли бы передать простую конфигурацию, добавив getMatchOptions:

Есть и другие конфигурации, которые мы можем передать снимку-образу-шутке, например Порог сбоя и т. Д. Вы можете найти этот список конфигураций в документации снимка-образа-шутки.

В среде непрерывной интеграции (CI) вы можете убедиться, что Storybook был готов перед выполнением регрессионных тестов. Обычно я предпочитаю использовать Storybook статической сборки в среде CI. Для этого мы представим новую переменную среды с cross-env:

yarn add cross-env

Затем в нашем package.json нам нужно создать новые скрипты для запуска в среде CI:

Установка переменной среды CI на true заставит приложение create-response-app запускать Jest в неинтерактивном режиме, кроме того, мы можем использовать эту переменную среды, чтобы изменить URL-адрес нашего Storybook в Storyshots, чтобы он указывал на статический сборник Storybook:

Другие полезные дополнения

В целом мне нравятся все дополнения, которые предлагает Storybook, но лично я использую несколько:

  1. Knobs - с помощью этого дополнения мы можем интерактивно изменять свойства нашего компонента, чтобы увидеть, что с ним происходит на разных свойствах.
  2. Jest - аддон Jest покажет результаты вашего теста Jest прямо в записи Storybook вашего компонента.
  3. Viewport - этот аддон может помочь нам увидеть отзывчивость наших компонентов при разных размерах области просмотра.
  4. GraphQL - этот аддон можно использовать для отображения IDE graphiQL с примерами запросов внутри Storybook.
  5. Intl - этот аддон предоставляет переключатель для локали react-intl, так как react-intl - это мои настройки фреймворка i18n, этот аддон для меня просто необходим.

Заключение

С помощью Storybook вы можете легко просматривать, управлять и тестировать свою библиотеку компонентов React. Трудно работать над крупномасштабным проектом с множеством разных членов команды с разной функциональностью. Будем надеяться, что добавление еще одного набора инструментов под рукава может немного облегчить нашу жизнь.

Спасибо за прочтение, также не забудьте заглянуть в демо репозиторий. И как всегда, Удачного взлома!