Мой опыт работы с необычным подходом к построению группы React приложений

от автора

  • Вступление

  • О системе

  • Плюсы и минусы

  • Возможные улучшения

  • Заключение

Вступление

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

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

Если у тебя есть какие то замечания (или находишь статью душноватой), дополнения или можно как то написать статью лучше, то пожалуйста напиши об этом в комментарии, мне будет очень интересно почитать 🙂


Немного боли из проекта:

  • Полное копирование всей директории с исходниками => Вставка директории и ручное удаление ненужных частей

  • Практически полное отсутствие переиспользуемых компонентов

  • Глобальные файлы со стилями без использования модульности или CSS-in-JS

  • Написание стилей через id и теги

  • Нам нужны новые фичи, а это не принесет денег бизнесу (с)

    • У нас тут все логично, поразбирайся немного и поймешь что все логично и правильно

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


О системе

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

  1. Подготовка небольших фрагментов кода для вставки в мобильное приложение через WebView

  2. Проведение AB тестирования для увеличения конверсии продукта (то есть если люди не стали больше покупать услуги, директория с фичей удаляется или уходит в папку deprecated)

Данная система имеет 2 типа приложений Screens и Widgets, главное их различие в том, куда WebView позже их вставит в мобильное приложение и наверное это все 🙂

Screens и Widgets это набор директорий, где каждая собирается Webpack как отдельное React приложение, так же приложение имеет свой конфиг и конфиг в директории фикстур.

Такая архитектура была сделана с целью, чтобы каждое последующее приложение (далее буду называть его экраном), могло сильно отличаться предыдущего и сделать возможность его максимально кастомизируемым визуально.

Ключевая структура корня приложения имеет примерно следующий вид:

{   .storybook: "Конфиги для общей настройки сторибука",   node_modules: "Куда же без них",   scripts: "Общие скрипты с функциями",      src: {   js: {   fuxtures: "Конфиги для тестирования", components: "Буквально пару переиспользуемых компонентов",   screens: "Директория с приложениями",   widgets: "Другая директория с приложениями" }, img: "Общие стили", styles: "Директория с общими стилями", index.html: "Корневой html шаблон для приложений" }  // И некие стандартные вещи вроде tsconfig.json, package.json, jest.config.js, postcss.config.js, webpack.common.js ... }

Структура экрана или виджета следующая:

{ components: "Компоненты под текущий экран или виджет",   colorThemeStylesheet.tsx: `   Файл в котором через react-helmet устанавливаются css переменные,     значение которых берется из конфига или конфига фикстуры если      он имеется.   `,   config.ts: "Локальный конфиг экрана",   id999.pcss: "Стили для экрана или виджета, где 999 это id текущего экрана",   id999.stories.ts: "Конфиг для storybook",   index.ts: "Входной файл для сборки вебпака",   Screen.tsx: `   JSX код в основном в нем содержится весь код,      который в редких моментах вынесен в локальные компоненты   ` }

Принцип создания нового экрана

Берем директорию с похожим функционалом делаем CTR+C => CTR+V, добавляем щепотку магии фикстурного конфига и вуаля! Вроде как наше промо готово, но нам же нужно сделать не 100% копию другого экрана, а с отличиями, мы их делаем для экспериментов и вооот тут начинается унылый механический ад.

Предположим у нас в экране который мы копировали есть следующий функционал:

  • название

  • слайдер

  • описание

  • продукты

  • Кнопка покупки

А по ТЗ нужно:

  • название

  • слайдер

    • (вместо него поставить какую-нибудь анимацию моргания глаз, которую можно взять из экрана 100 или экрана 102, которые кстати отличаются)

  • описание акции

  • продукты

  • Кнопка покупки


Начинаем идти по кругам рутины

Для начала мы должны удалить вручную из Screen.tsx всю JSX разметку слайдера и разметку «описания акции» =>

Переходим в стили этого экрана ищем все места, где необходимо удалить (что кстати мы можем вполне себе пропустить из-за того что они могут стилизоваться совершенно разными способами, что приведет к снежному кому, когда данный экран скопируют) =>

Переходим в ColorThemeStylesheet.tsx и убираем места св-ва конфига которые не используются =>

Убираем с нашего config.ts лишние параметры и интерфейсы с типами =>

Идем в фикстуры, повторяем процесс =>

Переименовываем директорию на новые экран =>

Переименовываем файл стилей и сторибука =>

В файле стилей оборачиваем в наш id экрана для инкапсуляции стилей для сторибука (тк в сторибуке отображаются все экраны и виджеты и если не делать вышеперечисленное, то сторибук может поплыть) =>

Идем в 100 экран ищем JSX разметку анимации «моргания глаз», вставляем ее, вставляем стили к ней, вставляем ColorThemeStylesheet какие-нибудь св-ва конфига и фикстур (предварительно дописав типы в конфиге и сами значения), вставляем и понимаем что в 100 она была реализована криво или с отличающимся сильно разным функционалом =>

Ломаем клавиатуру об стену => достаем из ящика новую

Повторяем процесс удаления анимации =>

Берем из 102, повторяем процесс вставки руками

Ищем «акции» или верстаем этот блок сами (чтобы потом его удалить в дочернем экране)

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


Плюсы и минусы

Плюсы

Минусы

Максимальная кастомизация экранов и виджетов.

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

Просмотр всех экранов и виджетов из сторибука, возможность передать в параметры сторибука св-ва для визуального тестирования

Нет возможности быстро узнать в какой экране есть тот или иной функционал

Нет возможности быстро переиспользовать какой-либо функционал

Снежный ком из потенциальных багов

Нет возможности исправить ту или иную часть группы экранов из-за пропущенной ошибки

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

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


Возможные улучшения

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

    P.S. так как наша система должна быть максимально гибкой мы должны использовать композицию элементов и если есть необходимость в изменении компонента использовать Theme, но не менять нашу компоненту Modal, тк это может затронуть другие экраны.

    Пункт №1
    Пункт №1
  2. Создание некого шаблона который будет собирать в пустой экран или виджет (а в нем использовать импорт компонентов из 1 пункта)

Пункт №2
Пункт №2

Заключение

Тк обладаю неким своим контекстом знания о системе, мог что то упустить в статье что привело бы к ее непониманию, однако очень надеюсь что все было понятно и интересно 🙂

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


ссылка на оригинал статьи https://habr.com/ru/articles/589903/