Библиотека компонентов Retail UI — это открытый проект и результат совместных усилий большого количества людей. Мы очень ценим вклад каждого и приглашаем всех желающих принять участие в его развитии. Этот гайд призван помочь новым участникам познакомиться с проектом и ответить на основные вопросы касательно его разработки.
- Документация:
- NPM-пакеты:
- retail-ui (больше не поддерживается, используйте
@skbkontur/react-ui) - @skbkontur/react-ui
- react-ui-validations
- @skbkontur/react-ui-validations
- @skbkontur/react-icons
- react-ui-codemod
- retail-ui (больше не поддерживается, используйте
- Контур.Гайды
- JS: React, TypeScript;
- CSS: CSS-in-JS;
- Сборка: Babel;
- CI: TeamCity;
Библиотека во многом опирается на стандарты и принципы дизайна, описанные в Контур.Гайдах. Как правило, все изменения, связанные с поведением или внешним видом компонентов, сперва согласуются с гайдами, и только потом реализуются в библиотеке. Контакты для решения подобных вопросов можно найти в разделе помощь.
Наши планы по развитию описаны в Roadmap.
После настройки и клонирования проекта работа над задачей в общем случае выглядит так:
- Выполнить задачу в отдельной ветке
- Добавить тесты и документацию
- Прогнать unit-тесты и линтеры
- Оформить pull request
Команды, доступные в проектах:
yarn workspace @skbkontur/react-ui <command>- контролыtest— unit-тестыJest+Enzymecreevey:ui— скриншотные тестыCreeveylint—tsc --noEmit+eslint+stylelint+prettierbuild— сборка библиотекиstorybook— Storybookstorybook:test— Storybook со стилями для тестовstyleguide— Styleguidist serverfix— форматирование кода по правилам eslint и prettier
yarn workspace react-ui-testing <command>- интеграционные тестыstart— старт приложения для интеграционных тестов (используется собранная версия библиотеки)test— интеграционные тесты с использованиемSeleniumTesting(работает только во внутренней сети Контура)
yarn workspace react-ui-validations <command>- валидацииstart:docs— документацияtest— unit-тестыlint— линтеры +prettierstorybook— Storybookfix— форматирование кода по правилам eslint и prettier
Для начала необходимо иметь установленными следующие инструменты:
Вся разработка ведется на GitHub. Монорепозиторий на базе lerna помимо самой библиотеки контролов содержит также библиотеку валидаций и инструменты тестирования.
Права на запись в репозиторий имеет ограниченный круг разработчиков. Информацию о том, как стать одним из них, вы найдете разделе помощь. А пока можно сделать Fork и работать через него.
Перейдите в выбранную директорию для клонирования и выполните команду:
git clone git@github.com:skbkontur/retail-ui.git
Или, в случае форка:
git clone git@github.com:%YOUR_USER_NAME%/retail-ui.git
Работая с форком, полезно добавить upstream в качестве удаленного репозитория:
git remote add upstream git@github.com:skbkontur/retail-ui.git
Теперь легко можно синхронизировать свой форк с основным репозиторием:
git fetch upstream
git checkout master
git merge upstream/master
Начиная работу над задачей, создайте для нее отдельную ветку. Если задачей является фикс критичной проблемы в стабильной версии, то ветку нужно делать от master. В остальных случаях — от next.
Особое внимание стоит уделить коммитам. В проекте используется commitlint с конфигурацией config-conventional. Это означает, что сообщения ваших коммитов должны соответствовать следующему формату:
тип(scope?): короткое описание
Например:
feat(ComboBox): new prop 'searchOnFocus'
fix(Button): fix icon padding
chore: update dependencies
тип должен быть одним из следующих ключевых слов:
feat: новая функциональностьfix: исправление багаtest: добавление и корректировка тестовrefactor: рефакторингdocs: изменение документацииbuild: изменения в системе сборки или внешних зависимостяхperf: улучшение производительности кодаstyle: изменение стиля кода (именование, форматирование и прочее)ci: изменения конфигурационных файлов и скриптов CIchore: прочие изменения
scope - опциональный параметр, указывающий на область изменений. Это может быть имя компонента или пакета.
короткое описание - минимальное сообщение на русском или английском языке, отражающее суть внесенных изменений.
Все три поля в сумме составляют заголовок коммита, который не должен превышать 72 символа. Более подробное описание можно оставить в теле коммита, отступив одну пустую строку от заголовка. Например:
fix(RenderLayer): add touchstart handling
iOS mouse events don't bubble up, use touchstart event instead
Closes #1439
В футере, через пустую строку от тела коммита, можно оставить ссылки на связанные issue.
Также, для составления правильного сообщения коммита можно воспользоваться интерактивной командой yarn commit.
Важно! Все коммиты типа feat и fix попадают в changelog. Поэтому, желательно, чтобы их краткое описание являлось информативным для широкого круга пользователей. По этой же причине, не стоит создавать более одного коммита этих типов на одну решенную задачу, иначе все они попадут в changelog. Для дополнительных коммитов, которые неизбежно возникают в процессе, можно использовать тип refactor, chore или любой другой из вышеописанных, который подойдет лучше.
packages/
├── ...
├── react-ui-validations/
└── react-ui/
├── .creevey/
├── .storybook/
├── .styleguide/
├── ...
└── components/
├── ...
└── Button/
├── __stories__/
├── __tests__/
├── Button.tsx
├── Button.styles.ts
├── ...
└── README.md
| Директория / Файл | Описание |
|---|---|
react-ui-validations/ |
Библиотека валидаций |
react-ui/ |
Библиотека контролов |
react-ui/.creevey/ |
Скриншотные тесты |
react-ui/.storybook/ |
Конфиг Storybook |
react-ui/.styleguide/ |
Конфиг React Styleguidist |
react-ui/components/ |
Компоненты контролов |
react-ui/components/Button |
Компонент кнопки |
react-ui/components/Button/__stories__/ |
Stories для Storybook |
react-ui/components/Button/__tests__/ |
Unit-тесты |
react-ui/components/Button/Button.tsx |
Код компонента |
react-ui/components/Button/Button.styles.ts |
Кастомизируемые стили |
react-ui/components/Button/README.md |
Документация |
Для контроля над стилем и форматированием кода в проекте используются editorconfig, ESLint, Stylelint и Prettier. По возможности, рекомендуем установить соответствующие плагины в свою IDE, чтобы получать от нее предупреждения в режиме реального времени. Но запускать линтеры можно и вручную, с помощью команды yarn workspace @skbkontur/react-ui lint. Советуем делать это перед каждым коммитом или пользоваться командой yarn commit. PR, не прошедший проверку линтеров, не может быть принят.
По возможности, любая новая функциональность или фикс должны сопровождаться тестами.
Unit-тесты хорошо подходят для тестирования логики работы компонентов и утилит. Они довольно дешевы, и, при прочих равных, стоит отдавать предпочтение им.
Для unit-тестирования в проекте используются Jest и React Testing Library. Тесты находятся в поддиректориях __tests__ внутри почти каждого компонента. Для их запуска служит команда yarn workspace @skbkontur/react-ui test. Её тоже желательно выполнять перед отправкой своих изменений, чтобы убедиться в том, что они не сломали существующие сценарии.
В проекте также может присутствовать некоторое количество тестов на Enzyme. В будущем они будут переписаны с использованием React Testing Library. Для новых тестов стоит сразу использовать RTL.
Storybook позволяет описывать и просматривать все имеющиеся компоненты в различных состояниях, а также взаимодействовать с ними. Он используется для ручного и скриншотного тестирования.
Запускается командой yarn workspace @skbkontur/react-ui storybook.
Все story находятся в файлах __stories__/[ComponentName].stories.tsx, в директориях своих компонентов. Просто добавьте новое состояние и оно появится в storybook:
export const ButtonWithError = () => <Button error>Error</Button>;Скриншотные тесты пишут для проверки верстки и отдельной функциональности в различных браузерах (Chrome, Firefox, IE11). В проекте они построены на основе Creevey и Storybook. Для удобства поддержки нужно разделять статичные и интерактивные тесты и выносить в отдельные файлы стори. Статичные тесты — те, в которых рендерятся элементы и не производятся никакие действия над ними. Интерактивные — те, где производятся разные пользовательские манипуляции. Интерактивные тесты необходимо выделить в __stories__/[ComponentName].creevey.stories.tsx, а статичные в __stories__/[ComponentName].stories.tsx
Скриншоты являются сравнительно дорогим видом тестирования. Используйте их, если unit-тестов недостаточно.
Конфиг для Creevey ожидает переменные окружения GRID_URL и GET_IP_URL. Поэтому, для локального запуска добавьте
их в файл .env в корне репозитория.
Ребята из Контура могут использовать значения для переменных отсюда.
yarn workspace @skbkontur/react-ui storybook:test - запуск storybook со стилями для тестов
yarn workspace @skbkontur/react-ui creevey:ui - запуск creevey с web-интерфейсом
- Создать или выбрать готовую story
- Добавить сценарий в параметры story
ButtonWithError.parameters = {
creevey: {
tests: {
async idle() {
await this.expect(await this.takeScreenshot()).to.matchImage('idle');
},
},
},
};- Через gui запустить добавленный тест
- Принять новые скриншоты в интерфейсе или с помощью команды
yarn workspace @skbkontur/react-ui creevey --update
Существующие тесты обновляются тем же образом (шаги 3 и 4).
Для документирования компонентов используется React Styleguidist. Он позволяет документировать пропы и методы, а также демонстрировать примеры использования. Более подробную информацию можно найти в официальной документации.
Собранная документация всегда доступна на витрине. А локально она запускается так:
yarn workspace @skbkontur/react-ui styleguide
Для того, чтобы новый компонент появился в документации, его нужно поместить в отдельную одноименную директорию внутри packages/react-ui/components и сопроводить файлом README.md:
components/
└── MyComponent/
├── MyComponent.tsx
└── README.md
Для документирования отдельных утилит и хелперов в проекте используется jsdoc.
Простейший пример выглядит так:
/** This is a description of the foo function. */
function foo() {}В неочевидных и сложных для понимания местах кода следует оставлять поясняющие комментарии.
После отправки изменений на сервер появится возможность создать pull request (PR) в основной репозиторий. Опишите сделанные вами изменения по специальному шаблону, чтобы проверяющим было проще в нем ориентироваться. PR следует делать в ту ветку, от которой была создана рабочая ветка.
В проекте приняты следующие соглашения и правила работы над PR:
- Перед запросом ревью PR должен быть оформлен по шаблону
- После начала ревью и внесения последующих правок, ревью следует перезапрашивать
- Резолв тредов во время ревью осуществляется их автором
- Все договоренности и результаты ревью, даже если они происходили вне github, следует зафиксировать в PR
- После запроса ревью делать force-push уже нежелательно
Добавление нового флага реализуется по алгоритму:
-
Сформируйте название флага по правилу [Название компонента или области]+[Описание изменения]. Стоит избегать общих слов, таких как "change". Вместо этого опишите в чем конкретно произошло изменение.
Примеры:
- validationsRemoveExtraSpans - Избавиться от обертки span в ValidationContainer, ValidationWrapper и ValidationText
- tokenInputRemoveWhitespaceFromDefaultDelimiters - В TokenInput изменили разделитель по умолчанию
-
Добавьте флаг в ReactUIFeatureFlags в файл ReactUIFeatureFlagsContext.tsx и в документацию FEATUREFLAGSCONTEXT.md
По любым возникающим вопросам можно обращаться в канал поддержки в Слаке:
- если вы из Контура - #infra_front_support
- если нет — написать письмо на адрес канала.