[Разработка веб-сайтов, Open source, JavaScript, ReactJS, TypeScript] Что выбрать в качестве библиотеки компонентов для React-проекта

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
26-Дек-2020 18:32

Меня зовут Ксюша Луговая. В СберКорусе я занимаюсь поддержкой библиотеки React-компонентов Korus-UI. С проблемой выбора библиотеки рано или поздно сталкивается почти каждый разработчик, и порой решение может быть нетривиальным. Возникают вопросы: чем руководствоваться при выборе библиотеки, какие популярные решения предлагает рынок, какие у них плюсы и минусы? Обзоры и отзывы не всегда помогают найти решение.В мире разработки не существует идеального варианта на все случаи. Поэтому в статье я расскажу, как мы решаем эту задачу, и разберу на примерах анализа нескольких популярных решений, как выбрать библиотеку React-компонентов для своего проекта. Основные критерии выбора библиотекиСценарии использования библиотеки. Это звучит очевидно, но четкое понимание задач — первоочередный критерий выбора.Типы компонентов приложения. От типа приложения зависит, какие компоненты вам потребуются. Часто достаточно набора кнопок/чекбоксов, базовых полей ввода, списков/меню с готовыми стилями. Значит, можно воспользоваться простыми компонентами с минимальным количеством настроек и готовыми стилями.Настройки, форматирование и интерактивность в дизайне. Если вам нужно значительно отформатировать и стилизовать свои компоненты, это тоже важно решить заранее.Когда требования четко сформулированы, ответьте на вопросы:
  • Хорошо ли составлена документация проекта, есть ли интерактивные примеры?
  • Насколько активно поддерживается проект?
  • Сколько в проекте issues и как быстро они решаются?
  • Проект бесплатный или коммерчески лицензированный?
  • Насколько легко настраиваются компоненты?
  • Покрыт ли код библиотеки тестами?
  • Какие браузеры и платформы поддерживает библиотека?
Это универсальные вопросы, которые помогут выбрать библиотеку. Даже если функционально решение идеально подходит под нужды вашего проекта, отсутствие поддержки или большое количество нерешенных багов — веская причина выбрать другую библиотеку. Я отобрала следующие библиотеки, чтобы наглядно показать процесс анализа по критериям:
  • Material-UI,
  • Semantic-UI-React,
  • yandex-ui,
  • arui-feather,
  • Korus-UI.
С одной стороны, в этом списке  представлены наиболее популярные проекты – Material-UI и Semantic-UI-React, которые были созданы одним разработчиком и со временем обросли большим сообществом.С другой стороны – библиотеки, созданные внутри крупных компаний (Яндекс, Альфа Банк) для своих проектов, которые постепенно обрели популярность в качестве opensource решений.Далее рассмотрим сравнение библиотек в разрезе определенных выше критериев.Компонентный составГлавная цель подключения библиотеки — набор компонентов для приложений, которые можно использовать повторно и легко комбинировать при создании более сложных модулей.Компоненты библиотек можно разделить на несколько групп.Layout-компоненты Контейнеры, карточки, таблицы, гриды и прочие. Основные характеристики:
  • Отвечают только за отображение;
  • Часто принимают на вход только props.children;
  • Не имеют своего состояния и методов жизненного цикла;
  • Примеры:  h1, section, div, span, Icon, Avatar.
Готовые дизайн-системы библиотек сильно упрощают верстку, если проекту не нужна своя тема стилей. Например, Material-UI и  Semantic-UI могут вполне справиться с этой задачей. Однако в крупных коммерческих проектах своя дизайн-система и кастомизация стилей библиотек будет избыточной.Компоненты-контролы (controls)Кнопки, чекбоксы, радиокнопки, поля ввода, слайдеры — небольшие базовые компоненты, которые помогают «оживить» контент и обеспечивать взаимодействие с пользователем. Основные характеристики:
  • Отвечают за отображение и не имеют внутреннего состояния;
  • Принимают данные и функции обратного вызова в качестве props;
  • Состояние компонентов связано в основном только с UI (disabled, required, isLoading).
Сложные модульные компонентыЭто группа компонентов с более сложной логикой, они расширяют функции базовых компонентов и могут их комбинировать. Основные характеристики:
  • Имеют состояние;
  • Предоставляют данные и логику layout-компонентам (валидация, форматирование вывода, автодополнение);
  • Комбинируют другие компоненты.
LayoutControlsModulesКоличество компонентовMaterial-UIApp Bar, Avatars, Badges, Bottom Navigation, Divider, Grid List, Lists, Paper, Progress, Snackbar, Tables, Button, Chip, Selection Controls, Text Fields, Pickers*Dialog, Cards, Drawers, ExpansionPanel, Menu, Stepper, Tabs, Tooltip26**Semantic-UI-ReactContainer, Divider, Flag, Header, Icon, Image, Label, List, Loader, Placeholder, Rail, Reveal, Segment, Step, Breadcrumb, Form, Grid, Menu, Message, Table, Advertisement, Card, Comment, Feed, Item, StatisticButton, Input, Checkbox, Radio, Select, Text AreaAccordion, Dimmer, Dropdown, Embed, Modal, Popup, Progress, Rating, Search, Sidebar, Sticky, Tab, Transition, Visibility, Confirm, Pagination, Portal, Ref, Transitionable Portal52yandex-uiBadge, Divider, Icon, Image, Text, UserPic, ListTile, Spacer, Link, SpinAttach, Button, Checkbox, Menu, Radiobox, RadioButton, Select, Slider, Textarea, Textinput, TumblerTabsMenu, Drawer, Dropdown, Messagebox, Modal, Popup, TabsPanes, Tooltip, Progress 30arui-featherAmount, CardImage, FlagIcon, Form, GridRow, GridCol, Heading, Icon, InputGroup, Label, Link, List, Paragraph, SpinAttach, Button, CardInput, CheckBoxGroup, CheckBox, FormField, IconButton, Input, RadioGroup, Radio, Select, TagButton, Textarea, ToggleCalendatInput, Calendar, Collapse, EmailInput, InputAutocomplete, IntlPhoneInput, Menu, MoneyInput, Notification, PhoneInput, Plate, Popup, ProgressBar, Sidebar, SlideDown, Tabs44Korus-UIHTML tags factory***,Currency, TagsButton, Checkbox, Input,  Radio, Rating, Slider, Switcher, TextareaAutocomplete, ButtonGroup, Collapse, Collapsible, DatePicker, DateRange, DateTimePicker, DateTimeRange, Dropdown, DropdownLink, DropdownSelect, Dropzone, FileDrop, FileUpload, Loader, MaskedInput, Modal, MultiSelect, Notifications, NumericRange, NumericTextBox, Pagination, Password, ProgressBar, StatusBar, StickyPanel, Tabs, TimePicker, TimeRange, Tooltip, Tour,  Validation, VStepper, Wizard, form45+ Компоненты-обертки для всех основных HTML-тегов*Material-UI использует нативный календарь браузера в компонентах с выбором даты**Основные компоненты библиотеки, для которых есть примеры в документации***Korus-UI создает обертку для всех основных HTML-тегов c единым APIПочти 50% компонентного состава Material-UI и Semantic-UI-React и около 30% в библиотеках yandex-ui и arui-feather — малофункциональные layout-компоненты. В Korus-UI более 70% — сложные модульные компоненты.КастомизируемостьВозможность подстраивать компоненты под собственный дизайн экономит много времени и сил в будущем. Сравним подходы к кастомизации визуального отображения компонентов на примерах.Material-UI
  • С помощью MuiThemeProvider. Компонент использует контекст библиотеки React для передачи объекта с темой всем дочерним компонентам.
  • Через добавление классов. Все компоненты поддерживают атрибут className.
Для кастомизации дочерних компонентов необходимо воспользоваться атрибутом classes.Библиотека заточена на применение CSS-in-Js, что может вызвать определенные трудности, если стили для приложения содержатся в CSS-файлах. Для внедрения кастомных стилей CSS-in-Js предоставляется HOC withStyles() либо хук makeStyles() для функциональных компонентов.Semantic-UI-ReactУ Semantic-UI-React нет своей темы, можно использовать стили  Semantic-UI.Библиотека предоставляет несколько конфигурационных файлов, в которых можно указать кастомные настройки для всей темы или отдельных компонентов. Это: yandex-uiУ библиотеки Яндекса несколько пресетов с темами. Их можно подключить сразу для всего проекта или применить стили для определенных компонентов.Возможности:
  • Создание кастомной темы с помощью инструмента themekit
  • Переопределение значения (токены) в теме;
  • Дизайн-токены в формате yaml или json. Их можно собрать в итоговый файл (css, json, js, ios, android) и подключить к проекту.
arui-feather (Альфа Банк)У библиотеки Альфа Банка нет руководства по кастомизации стилей в общедоступной документации.  Компоненты поддерживают атрибут className, возможно задать кастомные классы только их оберткам.Korus-UI (СберКорус)
  • Кастомизация темы с помощью компонента LedaProvider. Он использует контекст библиотеки React для передачи объекта с темой всем дочерним компонентам.
  • Можно написать кастомные стили под имеющуюся вёрстку. Полный список классов  в компонентах находится в разделе API-документации (см. атрибут theme). Их можно переопределять глобально для всех компонентов одного типа или для каждого индивидуально. 
РасширяемостьВ работе с библиотекой может возникнуть потребность изменить внутренний элемент компонента. Например, добавить картинку или иконку в поле ввода, заменить элемент на новый (в компонент Loader передать кастомный элемент спиннера).Рассмотрим решения.Material-UIПозволяет изменять корневые элементы с помощью атрибута component.Например, компонент List по дефолту рендерит <ul> элемент. Его можно заменить другим элементом или React компонентом:
<List component="nav">
  <ListItem button>
    <ListItemText primary="Trash" />
  </ListItem>
  <ListItem button>
    <ListItemText primary="Spam" />
  </ListItem>
</List>
Semantic-UISemantic-UI-React компоненты поддерживают схожий по функциональности атрибут as:
<Button as='a' />
Переданный элемент или React-компонент заменяют корневой элемент. Все неподдерживаемые пропсы передаются корневому элементу в качестве атрибутов.yandex-uiПредлагает использовать библиотеку render-override.  В ней есть набор хуков и компонентов для реализации переопределения элементов внутри составного компонента. Пример:
import React from 'react'
import { useRenderOverride } from '@yandex/ui/lib/render-override'
const ElementOriginal = ({ children }) => <div>{children}</div>
const MyComponent = ({ renderElement }) => {
  const Element = useRenderOverride(ElementOriginal, renderElement)
  return (
    <>
      <Element />
    </>
  )
}
В библиотеке yandex-ui расширяемость для существующих компонентов не реализована.arui-feather (Альфа Банк)Расширяемость компонентов не реализована.Korus-UIРасширяемость внутренних элементов библиотеки с помощью специального API. На вход компоненту можно передать атрибут из названия элемента и суффикса Render. Атрибуту присваивается функция, возвращающая элемент, которым заменяют существующий.Простейший пример:
labelRender={() => <MyCustomLabel />}
Структура метода позволяет вносить изменения максимально гибко:
({ Element, elementProps, componentProps, componentState }) => React.Node
  • Element - сам элемент
  • elementProps - props элемента
  • componentState, componentProps - для удобства дополнительно приходят объекты с props и state всего компонента
 Если мы хотим, чтобы новый элемент принимал на вход те же пропсы, можно отредактировать пример:
<L.CheckBox
  labelRender={({ elementProps }) => <MyCustomLabel {…elementProps} />}
>
  Label
</L.CheckBox>
ТипизацияДля типизации React-проектов применяются 2 основных инструмента:
  • Typescript
  • PropTypes
В документации React для большой кодовой базы отдается предпочтение Typescript. Это инструмент статической типизации, который позволяет отлавливать большинство ошибок еще до исполнения кода. У PropTypes проверка типизации осуществляется только после запуска кода — это существенный недостаток по сравнению с другими инструментами.В основном рассматриваемые библиотеки для типизации используют Typescript. У Semantic-UI основная библиотека написана на ванильном JS, а Typescript используется только в Semantic-UI-React, созданной для интеграции с библиотекой React.Покрытие тестамиХороший процент покрытия тестами — важный показатель качества кодовой базы. Потому что покрытие тестами дает некоторые гарантии, что изменение или добавление новых функций ничего не сломает. Это особенно важно для библиотеки компонентов с точки зрения обратной совместимости и для разработчиков, которые используют библиотеку в своих проектах. Очередное обновление версии не должно приводить к появлению трудно распознаваемых ошибок.Ради справедливости стоит отметить, что автоматические тесты — не панацея. Высокий процент покрытия не гарантирует качество теста и охват основных пользовательских сценариев.Но без покрытия тестами невозможно проверить совместную работу компонентов (интеграционное тестирование) и их работу вообще (модульное тестирование).Сравним библиотеки на покрытие тестами.Инструменты Типы тестов% покрытияMaterial-UIChai, Mocha, SinonUnit95.28% Statements87.22% Branches97.51% Functions95.26% LinesSemantic-UIJasmine, KarmaUnitОтчет о покрытии отсутствуетSemantic-UI-ReactChai, EnzymeUnitОтчет о покрытии отсутствуетyandex-uiJest, EnzymeUnitЗапуск тестов приводит к ошибкеarui-featherJest, EnzymeUnit88.1% Statements73.84% Branches66.61% Functions87.19% LinesKorus-UICypress, JestUnit, end-to-end69.28% Statements56.14% Branches66.29% Functions71.78% LinesДокументацияКачественная библиотека компонентов должна предоставлять хорошо структурированный сайт с документацией, которая включает большое количество интерактивных примеров. Storybook с демонстрацией функций компонентов может существенно сэкономить время при использовании библиотеки.ДокументацияНаличие интерактивных примеровStorybookMaterial-UIhttps://material-ui.com/ru/--Semantic-UI-Reacthttps://react.semantic-ui.com/+-yandex-uihttps://yastatic.net/s3/frontend/lego/storybook/index.html-+arui-featherhttps://digital.alfabank.ru/+-Korus-UIhttps://opensource.esphere.ru/korus-ui/++ПоддержкаИногда возникает проблема, которая требует сторонней помощи. Нужно заранее определить, как ее получить.Ситуация с технической поддержкой решений с открытым исходным кодом неоднозначна. Если библиотека, которую вы планируете использовать, имеет большое сообщество, можно получить помощь от других разработчиков, вносящих свой вклад в развитие библиотеки. Но результат непредсказуемый: на ваши вопросы могут ответить не очень быстро или не ответить вообще, если проблема никого не заинтересует. По этой причине выигрышно смотрятся библиотеки от крупных компаний-разработчиков. У них есть техподдержка и постоянная команда разработки, поэтому больше шансов решить проблему оперативно. Правки от крупных разработчиков поступают в продакшн по графику, закрепленному в релизной политике, а ответы на запросы дают своевременно.В разделе Pulse на GitHub можно ознакомиться со статистикой репозитория по количеству Pull Request и коммитов за определенный период времени. Он находится на вкладке Insights каждого репозитория. Рассмотрим статистику по выбранным библиотекам.Material-UI
Semantic-UI
yandex-ui
 arui-feather (Альфа Банк)
 Korus-UI (СберКорус)
ПопулярностьПопулярность библиотеки принято оценивать по звездам на GitHub и количеству скачиваний npm-пакета. Показатели легко проверить и измерить, они свидетельствуют о доверии разработчиков и наличии сообщества у библиотеки. Это упрощает ее использование и поиск решений для возникающих проблем. Однако стоит помнить, что популярность — это также результат хорошей маркетинговой стратегии и SEO-оптимизации, которые могут обеспечить библиотеке первые места в выдаче поисковика. Поэтому следует изучить обсуждения в блогах и на форумах, например, на Stackoverflow, Medium, DEV. Обсуждения находятся в разделе issues проекта. К сожалению, проанализировать и формально оценить всю доступную информацию из источников в рамках статьи невозможно, поэтому ограничимся количественными показателями. Для более реалистичной оценки качества библиотеки оценим соотношение положительных отзывов и количество скачиваний.ЗвездыСкачивания за последний годСоотношение количества звезд и скачиваний за последний год,  % Material-UI63 4006 372 3530,99Semantic-UI48 800541 2999Semantic-UI-React11 9008 620 9670,14@yandex/ui21215 9021,33arui-feather (Альфа Банк)55926 7442Работа с формами и валидация данныхФормы используются почти во всех приложениях. Это основной способ взаимодействия с пользователем. Даже если вы делаете простой лендинг, на нем скорее, всего будет, форма обратной связи. В сложном приложении могут быть десятки различных форм, начиная с формы авторизации. При взаимодействии с пользователем возникают разные проблемы: от ввода невалидных данных до попыток внедрения вредоносного кода. Поэтому золотым стандартом является валидация введенных данных до того, как они будут отправлены на сервер. Валидация может быть простой, например, на непустое значение (сделать поле обязательным). Или более сложной (кросс-валидация), когда данные в одном поле формы учитываются при проверке значений в других полях.Сравним работу с формами в различных библиотеках на конкретном примере.Задача: создать базовую форму авторизации с двумя полями для ввода логина и пароля и кнопкой отправки формы. Поля мы хотим сделать обязательными, чтобы незаполненное поле подсвечивалось, а текст ошибки отображался как при потере фокуса, так и после нажатия на кнопку «Отправить».Korus-UIИзвините, данный ресурс не поддреживается. :( Посмотреть код
const BasicForm = () => (
  <L.Div>
    <L.Input
      isRequired
      requiredMessage="Login is required"
      form="form"
      name="login"
      placeholder="Login"
    />
    <L.Input
      isRequired
      requiredMessage="Password is required"
      form="form"
      name="password"
      placeholder="Password"
    />
    <L.Button _warning form="form">
      Submit
    </L.Button>
  </L.Div>
);
Material-UIИзвините, данный ресурс не поддреживается. :( Посмотреть код
const BasicForm = () => {
  const [login, setLogin] = React.useState("");
  const [loginError, setLoginError] = React.useState(false);
  const [password, setPassword] = React.useState("");
  const [passwordError, setPasswordError] = React.useState(false);
  return (
    <div>
      <form
        onSubmit={(e) => {
          e.preventDefault();
          setLoginError(!login);
          setPasswordError(!password);
        }}
      >
        <p>
          <TextField
            error={loginError}
            placeholder="Login"
            value={login}
            onChange={(e) => {
              setLoginError(false);
              setLogin(e.target.value);
            }}
            onBlur={(e) => {
              setLoginError(!login);
            }}
            helperText={loginError && "Login is required"}
          />
        </p>
        <p>
          <TextField
            error={passwordError}
            placeholder="Password"
            value={password}
            onChange={(e) => {
              setPasswordError(false);
              setPassword(e.target.value);
            }}
            onBlur={(e) => {
              setPasswordError(!password);
            }}
            helperText={passwordError && "Password is required"}
          />
        </p>
        <Button type="submit" color="primary" variant="contained">
          Sign Up
        </Button>
      </form>
    </div>
  );
};
Semantic-UI-ReactИзвините, данный ресурс не поддреживается. :( Посмотреть код
const BasicForm = () => {
  const [login, setLogin] = React.useState("");
  const [loginError, setLoginError] = React.useState(false);
  const [password, setPassword] = React.useState("");
  const [passwordError, setPasswordError] = React.useState(false);
  return (
    <div>
      <Form
        onSubmit={(e) => {
          e.preventDefault();
          setLoginError(!login);
          setPasswordError(!password);
        }}
      >
        <Form.Group>
          <Form.Input
            error={loginError && { content: "Login is required" }}
            placeholder="Login"
            name="login"
            value={login}
            onChange={(e) => {
              setLoginError(false);
              setLogin(e.target.value);
            }}
            onBlur={(e) => {
              setLoginError(!login);
            }}
          />
          <Form.Input
            error={passwordError && { content: "Password is required" }}
            placeholder="password"
            name="password"
            value={password}
            onChange={(e) => {
              setPasswordError(false);
              setPassword(e.target.value);
            }}
            onBlur={(e) => {
              setPasswordError(!password);
            }}
          />
          <Form.Button content="Submit" />
        </Form.Group>
      </Form>
    </div>
  );
};
arui-featherИзвините, данный ресурс не поддреживается. :( Посмотреть код
const BasicForm = () => {
  const [login, setLogin] = React.useState("");
  const [loginError, setLoginError] = React.useState(false);
  const [password, setPassword] = React.useState("");
  const [passwordError, setPasswordError] = React.useState(false);
  return (
    <Form
      onSubmit={(e) => {
        e.preventDefault();
        setLoginError(!login);
        setPasswordError(!password);
      }}
    >
      <FormField>
        <Input
          error={loginError && "Login is required"}
          placeholder="Login"
          value={login}
          onChange={(value) => {
            setLoginError(false);
            setLogin(value);
          }}
          onBlur={(e) => {
            setLoginError(!login);
          }}
        />
      </FormField>
      <FormField>
        <Input
          error={passwordError && "Password is required"}
          placeholder="Password"
          value={password}
          onChange={(value) => {
            setPasswordError(false);
            setPassword(value);
          }}
          onBlur={(e) => {
            setPasswordError(!password);
          }}
        />
      </FormField>
      <FormField>
        <Button view="extra" type="submit">
          Submit
        </Button>
      </FormField>
    </Form>
  );
};
yandex-uiИзвините, данный ресурс не поддреживается. :( Посмотреть код
const BasicForm = () => {
  const [login, setLogin] = React.useState("");
  const [loginError, setLoginError] = React.useState(false);
  const [password, setPassword] = React.useState("");
  const [passwordError, setPasswordError] = React.useState(false);
  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        setLoginError(!login);
        setPasswordError(!password);
      }}
      className={cnTheme(theme)}
    >
      <Textinput
        error={loginError}
        placeholder="Login"
        value={login}
        onChange={(e) => {
          setLoginError(false);
          setLogin(e.target.value);
        }}
        onBlur={(e) => {
          setLoginError(!login);
        }}
        hint={loginError && "Login is required"}
      />
      <Textinput
        error={loginError}
        placeholder="Password"
        value={password}
        onChange={(e) => {
          setPasswordError(false);
          setPassword(e.target.value);
        }}
        onBlur={(e) => {
          setPasswordError(!login);
        }}
        hint={passwordError && "Password is required"}
      />
      <Button type="submit" view="action">
        Submit
      </Button>
    </form>
  );
};
Как видно из примеров, в Korus-UI задача создания формы с валидацией решается парой дополнительных атрибутов, тогда как в остальных библиотеках требуется достаточно много кода и проверок. В Material-UI и yandex-ui нет компонента формы, в Semantic-UI-React и arui-feather компонент формы является простой оберткой тега <form> и не предоставляет никакой дополнительной функциональности.Встроенная валидация полей отсутствует во всех рассмотренных библиотеках, кроме Korus-UI. Для реализации более сложной логики понадобится еще одна библиотека.Сравнительный анализ библиотек React-компонентовПодведем итог сравнительного анализа пяти библиотек React-компонентов.Korus-UI (СберКорус)Material-UISemantic-UI-Reactarui-feather (Альфа Банк)yandex-uiДокументацияStorybook++Примеры можно редактировать прямо в документации+++ПоддержкаКоличество Pull Request за последний месяц70241200ЛицензияMIT licenseMIT licenseMIT licenseMozilla Public License 2.0Mozilla Public License 2.0Покрытие тестамиПроцент покрытия > 50%+++Не удалось выяснитьE2E тесты+Поддержка браузеров и платформ Chrome85.0.4183.121>= 49Last 2 v.Last 2 v.Last 2 v.Firefox81.0.1>= 52Last 2 v.Last 2 v.>= 23Edge85.0.564.44>=1412+Last 2 v.IE111111+11+11+Safari14>= 10Last 2 v.Last 2 v.Opera Last 2 v.>= 12.1Yandex Last 2 v.?Android  4.4+5+>= 4iOS Safari7+Last 2 v.>= 5.1КастомизируемостьВозможность подключения кастомной темы++++Расширяемость+++ТипизацияTypescriptTypescriptTypescriptTypescriptTypescriptПопулярностьСоотношение звезд на GitHub и количества скачиваний за последний год, %0,990,1421,33Компонентный составЕсть компонент для работы с формами+++Наличие встроенной валидации+В этой таблице приведены только универсальные критерии для оценки качества инструментов. Кроме них, на выбор библиотеки значительно влияют субъективные факторы и конкретные требования проекта.Далее я расскажу, на какие факторы ориентировались мы в СберКорусе, и как было принято решение о создании своей библиотеки.Почему Korus-UIМожет возникнуть вопрос: зачем нужна еще одна библиотека? На рынке уже существует большое количество библиотек компонентов React на любой вкус.Мы решили создать свою библиотеку, потому что ни одно из существующих решений не удовлетворяло нас полностью по компонентному составу, возможностям расширения и кастомизации. Не устраивали также возможности настройки форм и валидации данных — функции, которые нужны буквально в каждом проекте.Были и объективные причины: недостаточное покрытие тестами кодовой базы, низкая активность в репозиториях библиотек. При разработке коммерческих проектов отсутствие своевременной поддержки со стороны команды библиотеки может стать досадной причиной срывов дедлайнов. С учетом всех факторов в компании было принято решение создать свою библиотеку React-компонентов, которая упростила бы разработку фронтенда на всех будущих проектах. Кроме того, при большом количестве крупных заказов возникает острая необходимость в едином стеке технологий и универсальных инструментах для всех проектов.  Ясно, что такие инструменты должны соответствовать высоким стандартам качества, предоставлять гибкие возможности по расширяемости и кастомизируемости.На разработку библиотеки Korus-UI ушло 1,5 года. В процессе создания мы ориентировались на лучшие практики разработки opensource-библиотек. Какие преимущества предоставляет Korus-UIФормы и валидацияВ Korus-UI подход к построению форм принципиально иной: поля и кнопка отправки формы связываются атрибутом form, в который передается строка с названием формы. Так элементы одной формы могут находиться в разных контейнерах, подключаться динамически, никакие общие обертки им не нужны. При этом создается объект формы, к которому можно получить доступ в обработчиках событий или с помощью метода  L.form(). Есть возможность передать кнопке массив из названий форм, чтобы валидировать и отправлять несколько форм одним кликом.У библиотеки Korus-UI удобный обработчик onValidationFail, который позволяет получить объект формы, не прошедшей валидацию. А еще есть приятный бонус — прокрутки к невалидным полям.Валидация в Korus-UI — это отдельный компонент. Его основные фичи:
  • Валидация поля функцией или RegExp
  • Готовые валидаторы
  • Один или несколько валидаторов для каждого поля со своими сообщениями
  • Настраиваемые сообщения (текст и внешний вид)
  • Задание валидности поля извне через атрибут isValid
  • Валидация компонентов в состоянии unmounted
  • Валидация полей по потере фокуса, сабмите формы и по событию в приложении
  • Прокрутка к невалидным полям при сабмите формы
  • Валидация нескольких форм одной кнопкой
  • Вспомогательные функции для валидации переданных значений
Единообразный APIВсе компоненты поддерживают атрибуты, начинающиеся с нижнего подчеркивания _. Такие атрибуты будут преобразованы в имена css-классов:
<L.Div _flexBox> -> <div class="flex-box"></div>
Атрибут className также поддерживается.В каждый компонент можно передать атрибут theme, который содержит набор css-классов для элементов компонента.Все компоненты поддерживают атрибуты с суффиксом Render (см. раздел расширяемость).Поведение и структура события расширены, соблюдается единый стандарт для всех компонентов:
{
  …Event, // оригинальное событие, сгенерированное React'ом
                
  // событие расширено объектом component, которое содержит данные из компонента
  component: {
    isValid?: boolean, // признак валидности компонента, есть только в onBlur
    name?: string, // имя формы, к которой привязан компонент
    value: any, // значение компонента
    … // другие свойства объекта (см. API компонента)
  }
}
Названия атрибутов с булевыми значениями начинаются с:is: isOpen, isValid, isRequired, isDisabledhas: hasCloseButtonshould: shouldCorrectValueВсе компоненты поддерживают атрибут ref.Korus-UI расширяет механизм ref, принятый в React.Недостатки Korus-UIСейчас библиотека используется в основном только в проектах СберКоруса, у нее пока не сформировалось свое сообщество. Так что вы не сможете получить информацию из блогов или на форумах, но всегда можете создать issue или обратиться к разработчикам библиотеки напрямую и быстро получить обратную связь.Еще можно отметить отсутствие поддержки мобильных платформ iOS и Android. Сейчас библиотека гарантирует поддержку только последних версий популярных браузеров. Подробная информация приведена в сравнительной таблице выше.ИтогиМы подробно рассмотрели основные критерии выбора библиотеки React-компонентов и проанализировали библиотеки Material-UI, Semantic-UI-React, arui-feather (Альфа Банк), yandex-ui, Korus-UI (СберКорус), опираясь на критерии качества. Вот коротко то, что нужно учесть при выборе библиотеки: 
  • Собственные нужды и требования
  • Кастомизируемость
  • Расширяемость
  • Типизацию
  • Покрытие тестами
  • Наличие техподдержки
  • Документацию
  • Отзывы и активность сообщества библиотеки
С учетом всех требований мы разработали собственную библиотеку Korus-UI, которая имеет все шансы стать достойным конкурентом существующим на рынке инструментам. Библиотека активно развивается, количество проектов, использующих Korus-UI в компании постоянно растет.В ближайшее время мы добавим новые компоненты. Также в планах расширение тестового покрытия, перевод на английский язык документации и актуализация Storybook.Библиотека  Korus-UI выложена в opensource и доступна на GitHub. Это первый шаг для нашей компании в opensource, и мы уверены, что не последний:)Отдельно хочу выразить благодарность команде разработчиков СберКоруса, отцу и идейному вдохновителю библиотеки Артёму Повольских. Если вам интересно, как устроена фронтенд-разработка в СберКорусе, читайте статью Артёма.Делитесь в комментариях своим опытом использования библиотек компонентов. Интересно обсудить, с какими преимуществами и недостатками вы сталкивались на личном опыте и какого функционала вам не хватает в процессе работы. 
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_open_source, #_javascript, #_reactjs, #_typescript, #_sberkorus (сберкорус), #_razrabotka_prilozhenij (разработка приложений), #_biblioteka_komponentov (библиотека компонентов), #_react, #_opensourse, #_typescript, #_javascript, #_optimizatsija (оптимизация), #_instrumenty_razrabotki (инструменты разработки), #_razrabotka_vebsajtov (
Разработка веб-сайтов
)
, #_open_source, #_javascript, #_reactjs, #_typescript
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Ноя 17:50
Часовой пояс: UTC + 5