Как Oscar использовал модули React и CSS для создания гибкой библиотеки компонентов для своих многочисленных интерфейсов

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

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

В более ранних библиотеках компонентов Oscar мы использовали подход стандартных блоков, многократно встраивая четко определенные и относительно простые компоненты. Такой подход обеспечивал высокую степень гибкости и был легко реализован с помощью React. Однако со временем этот подход стал многословным и лишился модульности. Функциональность более крупных компонентов зависела от правильного использования и порядка многих компонентов, а также от строгой конфигурации для правильной передачи данных. Хотя этот дизайн не повлиял напрямую на пользователей, он сделал разработку более утомительной и без надобности замедлил работу инженеров.

Из этих разочарований родились идеи для новой библиотеки компонентов. API для этой общей библиотеки компонентов называется анатомией.

Ограниченная гибкость

Оскар уже использовал React и CSS-модули во фронтенд-разработке, поэтому было несложным решением создать Anatomy с теми же технологиями. React упрощает передачу данных от родительских компонентов их дочерним компонентам, в то время как модули CSS допускают строгий модульный стиль.

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

Оценив недостатки ранних версий нашей библиотеки компонентов, мы решили переосмыслить стандартный способ сборки компонентов React. Хотя большинство компонентов хорошо работают со стандартными стандартами составления API React, особенно сложные компоненты, такие как настраиваемые таблицы данных и макеты страниц, создать сложно. При перестройке этих более сложных компонентов мы хотели удовлетворить следующие требования:

  • Инкапсуляция: отделите детали внутренней реализации от внешнего интерфейса.
  • Детализация: установите разумные значения по умолчанию, обеспечивая при этом краткий способ переопределения поведения.
  • Простота использования: оставайтесь в рамках соглашений о проектировании React API, чтобы обеспечить простую совместимость и продуктивность разработчиков.

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

Анатомия: примеры использования шаблона конфигурации

  1. Конфигурация таблицы

Таблица - прекрасный пример того, почему нам понадобилось создать анатомию. В своей самой простой форме компонент таблицы должен отображать серию строк, заполненных данными, которые передаются как свойство. Но в самом сложном случае таблица может содержать настраиваемый заголовок, разбиение на страницы и сложное поведение отображения данных. Вложение большого количества дочерних элементов для создания этих сложных подкомпонентов может вызвать проблемы с упорядочением и совместным использованием данных между компонентами, поскольку многим из этих подкомпонентов по-прежнему потребуется доступ к необработанным данным и отражать изменения, когда эти данные будут обновлены в другом подкомпоненте. -составная часть.

Сложная вложенная конфигурация:

Чтобы решить эти проблемы, мы создали компоненты, используемые только для настройки. Эти псевдокомпоненты конфигурации передаются в корневой компонент, который управляет компоновкой, определяя, какие компоненты отображать на основе предоставленных данных. Эти псевдокомпоненты вложены в дочерние элементы корневого компонента и имеют свои собственные свойства и дочерние элементы, что позволяет выражать более гранулярные структуры в одном блоке JSX. Это одновременно устраняет проблемы, связанные с вложением и правильным упорядочиванием обычных элементов рендеринга React, и устраняет необходимость в массивном объекте JSON для передачи всех свойств.

Конфигурация таблицы JSON:

Шаблон конфигурации:

Реализация проста: динамический компонент обертывает и создает фактический компонент (в данном случае макет страницы), который необходимо настроить. Процесс выглядит следующим образом:

  1. Динамические компоненты принимают словарь имен типов компонентов, которые сопоставляются с конфигурациями типов свойств, соответствующими компонентам, которые необходимо создать.
  2. Эти сконструированные компоненты React содержат только параметры конфигурации и никогда не отображаются.
  3. Компонент более высокого порядка оболочки конфигурации затем берет эти дочерние элементы конфигурации и анализирует их в объект elements внутри компонента. (Например, в компоненте таблицы получить доступ к конфигурации Table.ColumnGroup так же просто, как вызвать this.elements.ColumnGroup.)

2. Макеты страниц:

Этот же подход хорошо работает для макетов страниц. Адаптивные макеты могут изменять порядок и направление разметки в зависимости от размера страницы, размеров ее дочерних компонентов и требований ее дочерних компонентов. Имеет смысл обернуть макет страницы более осознанным компонентом, который принимает несколько разделов JSX.

Текущая реализация этого шаблона Oscar не позволяет упорядочивать или вкладывать компоненты конфигурации. Это действует как временная остановка, предотвращающая создание разработчиками слишком сложных конфигураций, нарушающих основные ожидания относительно простых групп компонентов или эффективного вложения. Прелесть этих ограничений заключается в том, что наша реализация компонента более высокого порядка Configuration состоит из менее чем двухсот строк кода, большая часть из которых является отладочным кодом предупреждения, чтобы обеспечить четкие предупреждения и ошибки, когда разработчики передают компоненту неправильный тип.

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

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