Предполагалось, что React облегчит разработку, но он создал препятствия


Летом 2018 года, мой босс, Эдриан, попросил меня присоединиться к его звонку по Skype с Джеймсом, техническим директором крупной канадской компании.

Пока мы узнавали друг друга, я понял, что Джеймс – умный парень с большими амбициями. Его видение заключается в миграции массивного десктопного приложения WPF в облако.

Мне нравится его дружелюбное отношение, и я могу сказать, что он готов сотрудничать с нами. У Джеймса уже есть партнёр по развитию в Индии, но ему не хватает опыта в создании веб-приложений. Казалось бы, что может пойти не так?




Мы с с моим боссом Эдрианом придерживаемся стандартного подхода к этой ситуации. У нас будет ещё несколько звонков, а затем мы начнём фазу открытия, в которой попытаемся понять общую картину происходящего и обнаружить нефункциональные требования. Вот основные моменты, на которых мы должны сосредоточиться:

  1. Приложение большое: более 220 страниц, большинство из которых – экраны для технического сопровождения, а около 20 % из них тонко настраиваются.
  2. Отображать большие объёмы данных, особенно в сетях со всевозможными функциями: группировка, возможность заморозить столбцы, расширить строки, настроить столбцы… ну, вы понимаете.
  3. Модульная архитектура, позволяющая нескольким командам работать над проектом одновременно.
  4. Это многолетний проект. Со временем будут добавляться новые функции.
  5. Автономный режим поддерживать не нужно.
  6. Новичков нужно адаптировать быстро, особенно разработчиков .NET, работающих над старым настольным приложением.

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

Джеймс неоднократно упоминал, что он хочет получить технологию будущего, и он не благосклонен к Angular, потому что, когда AngularJS устарел, эта технология приобрела плохую репутацию.

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

Для этого проекта я выбираю «React и Redux»… о чём буду жалеть два года спустя.

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

1. Разработчики .NET присоединяются к команде


После доказательства концепции настало время разработчикам из команды аутсорсинга заказчика присоединиться к нам. Мы ещё не начали встречи, чтобы поделиться знаниями о проекте, и технический директор прислал мне письмо по электронной почте со словами: «Привет, Рэзван. Нам действительно нужно встретиться завтра с моей командой аутсорсинга».

Итак, мы на встрече; технический руководитель устраивает мне засаду с вопросами:

  • «Где инъекции зависимости? Что ты имеешь в виду под „Не нужно никаких инъекций“? Вот пример: InversifyJS!»
  • «Функциональные компоненты»? Нет, нет, нет. Они нам не нравятся. Давайте работать с компонентами класса!"
  • «Почему эти функции просто болтаются в коде, и почему они не инкапсулируются внутри классов сервисов, чтобы сделать их статичными?»
  • «Где Retry Policy [прим. перев: политика повторения запросов] для API? Давайте реализуем её с помощью PollyJS».
  • «Почему в именах файлов тире, когда имена классов – PascalCase? Имена файлов должны отражать имя класса в файле, поэтому отныне будем называть их SomePageComponent.tsx».
  • И вопрос, который раздражает меня больше всего: «Как я могу запустить его в Visual Studio, а не в Visual Studio Code?»

Всё проясняется. Разработчики .NET хотят использовать руководящие принципы .NET и шаблоны проектирования в React. Я много раз видел разработчиков, которым трудно адаптироваться к новым технологиям, так что не боюсь ввязываться в дебаты о том, почему для React эти паттерны необычны.

Но в данном случае технический директор поддерживает свою команду, это нормально. Он знал меня всего два месяца, а со своей командой работал много лет. Я должен пойти на компромисс и согласиться с их предложениями.

И тут я осознал, что React не дружественен ни к Java, ни к .NET разработчикам. Angular в этом случае был бы лучшим выбором из-за схожих шаблонов проектирования.

2. Дело не обходится одним React


React – это библиотека, не имеющая мнения; это означает, что у нее нет мнения о том, как решать проблемы, которые касаются всех аспектов. Таким образом, это ваша обязанность и вашей команды – выработать мнение о том, что и как сделать и особенно о том, какие другие библиотеки вы хотите использовать. Конечно, вы будете применять сторонние библиотеки, потому что не хотите изобретать колесо. И в React имеется множество разных вариантов.

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

  • Какой маршрутизатор следует использовать?
  • Что кроме Redux мы должны использовать для асинхронных действий? Thunk? Saga?
  • Должны ли мы использовать Axios или fetch API в браузере?
  • Redux-Forms, Formiq или Final-Form?
  • Styled-Components, makeStyle, SASS или чистый CSS?
  • А что с библиотекой интернационализации?

Так что, принимая эти решения, мы провели ещё три недели. Я уже слышу, как вы воскликнули: «Мужик! Не может быть, чтобы на выбор этих библиотек потребовалось три недели!»

Ну… добро пожаловать на корпоративные проекты. Есть множество решений. Для каждого из них вы должны создать критерии принятия решения, провести исследование, проверить результаты, создав доказательство концепции, представить результаты, задокументировать всё в журнале принятия решений и поддерживать библиотеки в актуальном состоянии. Это занимает сумасшедшее количество времени, и это совсем не весело.

И я даже не учитываю, сколько времени каждый разработчик тратит на изучение всех этих сторонних библиотек. Я никогда не видел двух проектов React с одинаковыми зависимостями, структурой проекта и руководящими принципами. Это означает, что знания не могут передаваться от проекта к проекту, как это может быть в случае Angular или Vue.

После трёх недель без прогресса во внедрении функционала из юзер-стори технический директор забеспокоился.

3. Хуки React обретают популярность


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

React Hooks обретают популярность. Разработчики испытывают смешанные чувства.  Одни обижаются на предположение, что классы вводят в замешательство людей и машины, тогда как другие с энтузиазмом относятся к новому паттерну кодирования.

Все сторонние библиотеки, которые мы используем, добавили поддержку хуков, и похоже, что весь мир React движется в этом направлении. Так что же делать нам? Должны ли мы отклониться от первоначальных руководящих принципов кодирования и добавить третий способ реализации компонентов? Вернуться назад и перенести существующие страницы и компоненты в хуки уже невозможно!

Команда выступает за использование хуков Redux, потому что нет необходимости использовать Redux connect() и отделять «глупые компоненты» от контейнеров. Это имеет смысл, и мы согласились с тем, что отныне новые страницы и компоненты будут использовать хуки. Старые страницы останутся как есть.

Итак, у нас есть три разных способа писать проект. И нет последовательности.

Что ещё хуже, некоторые разработчики начинают настаивать на том, чтобы больше не использовать Redux, а вместо него применять useState. Это означает, что мы разрушим идею единого глобального состояния.
Функция Suspense всё ещё экспериментальная. Я забеспокоился о том, что произойдёт, когда она войдёт в релиз официально.

4. Разработка замедляется


Когда мы настроили непрерывную интеграцию (CI), сборка, включая npm install, занимала около трёх минут. Но теперь, спустя год, она занимает около 15 минут.

Мы также должны были настроить Node.js и поставить оперативную память 4 ГБ, потому что 2 ГБ уже не хватало. Это небольшая проблема. Что касается начавшихся жалоб на время сборки, горячая перезагрузка перестает работать после 45–60 минут разработки, а перезапуск занимает более пяти минут – особенно у разработчиков с Windows (системы Linux, по-видимому, намного быстрее в смысле Node.JS). Иногда разработчикам на Windows приходится полностью удалять node_modules и снова загружать зависимости, потому что иначе они просто не работают.

Чего ещё можно ожидать, когда в node_modules более 1200 зависимостей общим размером 600 МБ?

В смысле корпоративного приложения всё сводится к затратам. Допустим, разработчик с почасовой ставкой 40 долларов в час должен перезапускаться шесть раз в день. Шесть раз в день умножаем на пять минут и на 240 рабочих дней в году, затем на 40 долларов в час и на восемь разработчиков = 38 400 долларов в год. Это небольшая сумма для предприятия, но это хороший ежегодный бонус для спонсоров проекта. В конце концов, сумма равносильна совершенно новой Tesla Model 3.

5. Redux-Saga медленно умирает


Большинство разработчиков не согласны со мной, но я ощущаю, что большая часть бизнес-логики находится внутри асинхронных действий Redux. В большинстве случаев асинхронные действия – единственное место, где можно выполнять проверку, вызовы API, обработку ошибок, запускать мутации redux или тостер уведомлений. Если это не бизнес-логика в интерфейсных приложениях, то что же тогда это такое?

Решение использовать Redux-Saga оказалось плохим потому, что оно добавляет ненужную сложность. Достаточно хорошо подходил бы Thunk.

В корпоративных приложениях вам необходимо время от времени обновлять и перепроверять зависимости. Это хорошая практика, потому что важно иметь обновления безопасности, улучшения производительности и небольшие инкрементные изменения API, при этом надеясь на отсутствие критических изменений. Похоже, что Redux-Saga в этом смысле осталась позади. Последнее обновление было более года назад, количество issues на GitHub растёт, и никто не исправляет их.

Разработчики любят React по трём причинам: простота, гибкость, экосистема. Команде React нравится экспериментировать с новыми идеями, но это убивает экосистему! Они должны проявить смелость и взять на себя вину за это!

Действительно, React в основном обратно совместим, а экосистема вокруг React – нет. Разработчики и сторонние библиотеки всегда будут использовать новейшие функции и шаблоны архитектуры, а старые эксперименты останутся умирать. Это не должно быть проблемой для малых и средних проектов, потому что вы можете легко адаптироваться. Но для больших многолетних проектов эти эксперименты могут отбить у клиента желание работать с продуктом.

Уже сентябрь 2020 года, и я решаю включить «React-Saga» в результаты оценки рисков, предназначенные для технического руководящего комитета.

Поскольку 30 % бизнес-логики содержалось внутри Saga, я посчитал это высоким риском. Когда мы начинали проект, технический директор вышел из себя и обвинил меня в том, что я принимал неверные решения.

Это была просто искра, в которой нуждался продакт-менеджер. Эта искра дала менеджеру возможность задавать вопросы, например:

  • «Почему мы должны тратить столько времени на обновление библиотек?»
  • «Почему разработка замедляется?»
  • «Почему приложение стало глючным и нестабильным?»

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

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

Заключение


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



image