Канал для поиска исполнителей для разных задач и организации мини конкурсов
Last updated 2 months, 1 week ago
Также, очень приятно видеть в твиттере много довольных мейнтейнеров open source проектов - Microsoft поддержал финансово внушительный список проектов - https://x.com/jeffwilcox/status/1801794149815095495?s=19
Вдохновляет ❤️
Не так давно писал про интересное изменение в React 19 - последовательная загрузка компонентов в рамках Suspense границ - https://t.me/super_oleg_dev/181
Как я понимаю это сильно ударило по перфу SPA приложений, где нет возможности предзагрузить ассеты и данные параллельно как это делают при SSR.
В итоге будут искать более удачное / универсальное решение:
- https://github.com/facebook/react/issues/29898
- https://x.com/sophiebits/status/1801663976973209620?s=19
Telegram
SuperOleg dev notes
Парочка интересных кейсы из беты React 19, которые особо не освещались: - Прощай useIsomorphicLayoutEffect, больше нет варнинга на сервере - https://github.com/facebook/react/pull/26395 - Если вы используете throw promise или либы с поддержкой Suspense…
Про "все-в-React" или "все-в-компоненте" и декларативность.
Что мы видели интересного в коде компонентов:
- <Route>
и <Redirect>
из React Router
- <Script>
из Next.js и <Scripts>
из Remix
- useQuery
из React Query или Apollo
- useForm
из React Hook Form
- не могу не вспомнить <FormSpy>
из Formik
Компоненты и хуки из списка объединяет то, что это либо обернутые в компонент сайд-эффекты, либо размазанная по компонентам логика, которой не возможно управлять централизованно.
Это не примеры абсолютного зла - так как плюсы без сомнения есть, в очень гибком роутинге, либо в умном механизме запросов без бойлерплейта, либо в минималистичной абстракции логики фреймворка от пользователя.
Но в масштабе, проблемы есть.
Хранить список роутов в компонентах - не масштабируется, подход с заранее объявленными роутами гораздо легче развивать и поддерживать.
Но декларативность в React мире доходит до того, что например в React Router вообще нет такой цельной сущности как Router! Есть только набор хуков, а сделать что-то с роутингом вне компонентов мы просто не имеем возможности.
Например (императивно) создать const router = new Router()
, предзаполнить router.addRoute(...)
, в лоадере/экшены выполнить router.redirect(..)
, передать в <Router.Provider router={router} >
и так далее.
Отсутствует жизненный цикл, настолько RR связан с реактом. Механизм loader'ов добавил хотя бы один этап жизненного цикла. Но для какой-нибудь авторизации разработчики все-равно будут создавать всякие <Auth>
и <ProtectedRoute>
компоненты.
Наглядный пример в этой статье - https://blog.logrocket.com/authentication-react-router-v6/. Хороший гайд, все аккуратно, react way, но насколько же сильно размазана аутентификация по компонентам, и не существует снаружи.
Просто сравните с Angular, где через DI предоставляется отдельный сервис для аутентификации, используемый и в UI и в гуарде роутера.
React Query большие молодцы, выделяют логику в отдельные сущности, и с ними можно работать где угодно, например QueryClient. Такие вещи очень упрощают интеграцию для SSR фреймворка.
Но и тут есть проблемы, возьмем сами квери. Как отдельной сущности их просто нет, есть набор параметров вида const query = useQuery({ queryKey: ['todos'], queryFn: getTodos }), и только через queryKey возможна связь для одной и той же квери между использованием в компоненте и прямой работой через QueryClient в других местах.
Сложно делать расширяемые и переиспользуемые query, параметры считываются и сохраняются сразу при рендере хука - нельзя сделать queryKey
функцией, на момент рендера useQuery
надо иметь все параметры для формирования массива ключей.
Используя React Query и React Hook Form, можно делать хороший UX и писать мало кода на сложные кейсы, но очень сложно явно выделить сущности / модели / бизнес-логику, что опять-таки может выстрелить в ногу в масштабе, и уж точно не поможет сделать архитектуру "кричащей".
По поводу таких кейсов как Scripts
в Remix, или поддержка метаданных и стилей в React 19.
Реакт или Ремикс не дает нам условный AssetsManager
, в который мы смогли бы добавить ресурс явно по конкретному условию, например:
if (analyticsEnabled) {
assetManager.addScript({ src: anaylicsScript, async })
}
Нам предлагается явно рендерить нужный скрипт в компоненте (прямо или косвенно). И хотя для RSC и стриминга понятно почему важно поддержать эти механизмы, выбранный путь мне совершенно не нравится.
Если подвести итог, эта псевдо-декларативность в React и экосистеме, как и явно обозначенная ограниченная область ответственности React (не фреймворк, а библиотека!), напрямую влияет на то как сообщество пишет приложения, на образ мышления новых разработчиков, и как мне кажется влияет негативно.
Получается для меня, главная проблема React это точно не лишние ререндеры, а архитектурные вопросы. И вряд ли экосистема в этом плане заметно поменяется, а область ответственности React только расширяется. Скорее всего в будущем при поддержке RSC и прочих современных возможностей, остро встанет вопрос что мета-фреймворк либо будет написан в react way стиле, либо останется в стороне.
GitHub
Add useRouter Hook · Issue #6430 · remix-run/react-router
Hi guys, at current React Conf Hooks have been announced for React v16.7. What's the plan for supporting them? Will there be a useRouter() any time soon? https://reactjs.org/docs/hooks-faq.html...
Собрал для вас в одну папку авторов, ведущих блоги по фронтенду, веб-разработке и вокруг неё.
? https://t.me/addlist/Z6Efi4jXwe9lODcy
Специально отобрал именно ламповые авторские блоги, а не перепосты ссылок, документации или тексты не про код.
Для меня это хороший способ следить за реакциями о событиях индустрии. Например, конференции проходят не так часто, и контент с них становится общедоступным не сразу. Кроме того, там обычно рассказывают о чём-то эпичном, не сиюминутном, так как формат обязывает. А вот в авторских бложиках (и комментариях к постам) можно собрать цельную картинку происходящего в рутине, и не просто факты, а именно авторскую интерпретацию и комментарии.
Надеюсь, будет полезно ✌️
Парочка интересных кейсы из беты React 19, которые особо не освещались:
- Прощай useIsomorphicLayoutEffect, больше нет варнинга на сервере - https://github.com/facebook/react/pull/26395
- Если вы используете throw promise или либы с поддержкой Suspense, в рамках одного Suspense загрузка данных в параллельных компонентах начнет происходить последовательно - https://github.com/facebook/react/pull/26380
Пример кода где будет водопад запросов при использовании условного useSuspenseQuery:
const Root = () => {
return <>
<Suspense>
<CmpWithUseSuspenseQuery />
<CmpWithUseSuspenseQuery />
</Suspense>
}
В релизе очень порадовало улучшение ошибок гидрации, и централизованная обработка ошибок Error Boundaries.
Также я никак не пойму в какой версии удалили или удалят 421 ошибку гидрации - https://github.com/facebook/react/issues/24959#issuecomment-1317309116
Ошибка происходит при ререндере Suspense компонента, поддерево которого не завершило гидрацию, и приводит к деоптимизации - клиентский рендер вместо гидрации.
Очень легко словить такую ошибку используя useSyncExternalStore.
Потратил часы на разборы таких ошибок, а ситуация в итоге странная - ошибку выпиливают, а деоптимизация остаётся.
Наверное мне стоило более тщательно подойти к замеру разницы в перформансе при деоптимизации, может проблема и не такая значительная, раз ее просто можно заглушить?
GitHub
Remove layout effect warning on the server by rickhanlonii · Pull Request #26395 · facebook/react
Overview This PR unfortunately removes the warning emitted when using layout effects on the server: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server...
Подведу некий summary:
- Round Trip Time важен на каждом из многочисленных этапов загрузки HTML, в идеальном мире точка входа в приложение - это CDN
- Редиректы не бесплатные как для клиента, так и для приложения, лучше их не делать или делать поближе к пользователю, например на уровне балансера
- Service Worker может как ускорить, так и замедлить ваше приложение - измеряйте все что можете, пробуйте Navigation Preload, не используйте SW для "галочки" - браузер и так отлично все кэширует
- Раздутый HTML и плохой интернет - это значительная проблема для SSR, которую трудно исправить малыми усилиями
Круто, что есть много браузерных API для мониторинга таких деталей.
Про разработку.
Запланированные процессы такие:
- один разработчик пишет бэк, один фронт- до разработки, создается задача на конкретный небольшой функционал
- бэк пишет Open API схему и тест кейсы до реализации, на этом этапе асинхронно ревью/приемка заказчиком
- фронт накидывает мокапы и тест кейсы до реализации, на этом этапе асинхронно ревью/приемка заказчиком
- фронт получает сгенерированные API клиенты + моки от бэка до реализации
- реализация обязательно с тестами (Mostly integration!)
И если с тестами нам очень помогают коллеги, в том числе QA-инженер (отсутствует в нашей команде), сильно недооценили работу по дизайну, делать хорошие мокапы сложно даже при наличии кита и каких-то гайдлайнов, поэтому в асинхронном режиме будем привлекать дизайнера (отсутствует в нашей команде).
Также, большой объем работы потребовался на изначальную настройку инфраструктуры, это и тестовое окружение, Allure, генераторы клиентов и моков, CI/CD, и многое другое.
Поэтому процессы еще совсем не прошли проверку временем.
История далека от завершения, но очень надеюсь в следующих постах затронуть сторонние темы, и возвращаться тут к MF Platform по мере возникновения интересных инсайтов, точно будет что рассказать по SRE (платформу будут использовать критичные сервисы, что подразумевает высокие требования к доступности и поддержке).
Привет!
Вернулся из отпуска, вхожу в привычный ритм, пора начинать писать)
По проектированию Microfrontends Platform я не успел рассмотреть клиентскую архитектуру, но думаю тут достаточно информации из одного из старых постов - https://t.me/super_oleg_dev/41, те же подходы планируем применять и для UI сервиса.
Детальное проектирование сервиса очень помогло для старта, многие базовые сущности оказались достаточно гибкими и расширяемыми, и остались без изменений.
При этом, дизайн все-равно быстро устаревает по ряду причин:
- выявляются новые потребности
- все это время идет постоянная проработка сценариев и граничных кейсов
- информация мигрирует в другие источники
Потребности.
Как я писал ранее, одно из слабых мест проекта это предварительный сбор требований. За одну-две встречи и презентовать свое видение проекта заинтересованным лицам, и собрать с них все потребности кажется невозможно.
В итоге, кейсы использования сервиса у основного заказчика требуют совсем другого взгляда на возможности проекта - основная разница, что версиями и доставкой микрофронтов управляют не разработчики приложений где они используются (как я планировал изначально), а разработчики самих микрофронтов, которым грубо говоря нужно релизить большие наборы протестированных микрофронтов, часто, и сразу на все приложения где они используются.
Это очень сильно влияет на сценарии использования сервиса, и требуемый функционал, можно сказать у нас получается x2 фич.
И одновременно почти не влияет на структуру базы данных (расширяет в первую очередь), где в основе по прежнему штучные релизы микрофронтов, привязанные к конкретным приложениям.
Поэтому в будущем для любых проектов я планирую уделять намного больше времени на сбор требований и формирование сценариев использования.
Проработка сценариев и граничные кейсы.
Пока это похоже на потенциально бесконечный процесс, так как он идет рука об руку с развитием продукта.
Но на первых этапах это конечно проработка основного функционала, даже на самые простые кейсы можно добавить десяток правил валидации, а на более сложные - очень повезет если получится найти все подводные камни до реализации.
Пример, есть потребность - массовые релизы микрофронтов.
Коллегам нужна возможность группировать микрофронты, релизить группу на несколько приложений одновременно, откатывать эти релизы, при этом не затрагивая другие микрофронты приложения.
Сюда добавляются такие кейсы как “заморозка” версии одного микрофронта из группы, если следующие версии сломаны, но не хотим блокировать релизы полностью.
Потом встает вопрос изменения состава групп, перенос микрофронтов между ними, и так далее.
Что бы не утонуть в этой сложности, проводим регулярные встречи и ведем подробную документацию.
Для MVP проекта сильно ограничили функционал, и прикинули следующие итерации самых приоритетных вещей.
Сложные кейсы стараемся упрощать и откладывать проработку, если есть понимание что возможное решение не потребует перелопатить всю архитектуру проекта в будущем.
Источники информации.
Вайтборд почти полностью устраивал меня на начальных этапах проектирования.
Но для долгоживущей информации, которая должна быть полной и актуальной, не обойтись без какой-либо wiki.
Что у нас уже есть в этой документации:
- минимальный глоссарий (выбрать и согласовать общие и понятные для всех термины тоже оказалась целая история!)
- сценарии использования сервиса
- потребности стейкхолдеров
- значимые архитектурные решения
- процессы разработки и приемки фичей заказчиками
- спецификация как пишем API эндпоинты
- всевозможные meeting notes
Ряд вещей перемещается в кодовую базу:
- схема базы данных - Prisma
- схема API эндпоинтов - Open API
- всевозможные сценарии - Allure тест кейсы
Тут важно иметь один обновляемый источник информации, постепенно уйти от дублирования, соответственно этот источник должен быть удобен в поддержке.
Telegram
SuperOleg dev notes
Другая задача - разработка рекомендаций и практических советов по организации структуры и архитектуры в tramvai приложениях. Нашей команде кажется очень перспективным подход Feature Sliced - https://feature-sliced.design/ В рамках исследования подготовил…
Нижний уровень C4 - Code.
Но у нас осталось много не проработанных вещей, поэтому дальше я работаю сразу над несколькими:
- сущности бэкенда
- структура API роутов
- основные классы и методы
- описание сценариев работы
Список сущностей похож на БД, но собран в удобные для дальнейшего использования объекты.
API роуты старался делать не слишком низкоуровневыми, а под основные кейсы использования.
Например, у каждого приложения могут быть пресеты, в каждом свой маппинг микрофронтов.
Сначала я описал эндпоинты вида /:tenant/:app/:preset/mapping
где работа с сущностью Mapping
, но понял что по отдельности они не нужны, и удобнее сразу работать со всеми маппингами - например на GET /:tenant/:app/mapping
возвращать Record<Preset, Mapping>
.
Для основных классов из C4 Components описал методы и логику их работы. Вообще, получилось что эти сервисы и их методы 1 к 1 соотносятся с API эндпоинтами, и кажется это не очень корректно, но может измениться после рефакторинга - далее планирую найти и вынести общую логику из сервисов.
И конкретный пример:
Есть сервис HistoryService
, сигнатура одного из его методов - rollback( Tenant, Application, History? ): History[]
- он будет использоваться для откатов по истории изменения маппингов.
Для метода rollback описана логика работы:
- В рамках одной транзакции, получаем в БД соответствующую запись History либо берем предыдущую
- Находим все записи History с timestamp выше, проходим по ним
- В цикле, в таблице Mapping находим все записи под текущие History и Application
- Удаляем эти записи Mapping, в конце удаляем эту запись History
- И наконец обновляем поле Revision для текущей записи Application
На этом этапе много сложностей, так как буквально зайти дальше - это уже писать код, держать все в голове и прорабатывать низкоуровневые моменты оказалось сложнее всего, особенно в областях с множеством неизвестных.
Из интересного, сильно задумался над процессом загрузки файлов микрофронта через API платформы в файловое хранилище s3.
План примерно такой:
- CLI утилита в CI/CD создает объект FormData, считывает контент файлов, добавляет туда и отправляет стрим на бэкенд
- Бэкенд не буферизует эти данные, а сразу перенаправляет стрим в s3 через aws-sdk
Тут стоит сделать отдельно прототип и убедиться что нет подводных камней.
Далее, переходим к бэкенду.
Сначала поверхностно, уровень C4 components.
Как уже писал, это не самый сложный бэкенд и не тот случай когда когда нам нужны DDD или Hexagonal Architecture.
В первую очередь хочется отделить бизнес-логику от работы с запросами.
Также, выделить предметную область - сущности которыми будет оперировать бэкенд для удобства будут отличаться от сущностей, которые мы создали в базе данных.
Также у нас будут сервисы для работы с внешними хранилищами.
Итого слои приложения:
- Controllers - минимум логики, обработка API роутов, работа с req/res
- Services - конкретный функционал, без прямой работы с БД
- Entities - схема сущностей API
- Storages:
- Prisma - схема сущностей в БД, работа с БД, миграции
- s3 - работа с s3
Из важных границ, стоит для работы с БД сделать абстрактный интерфейс, а адаптером для этого интерфейса будет Prisma сервис - это немного ослабит зависимость от конкретной ORM.
И если все-таки мы в итоге возьмем Prisma (от вас много комментариев по этому поводу :) ), хочется переиспользовать опыт работы с Redux селекторами и React-Query, и выделить дополнительный слой с атомарными и переиспользуемыми queries, которые можно будет комбинировать уровнем выше, в том числе в транзакции.
Пока не прорабатываем логику авторизации / пользователей / ролей и групп - как уже писал тут хочется переиспользовать API нашей IDP.
Канал для поиска исполнителей для разных задач и организации мини конкурсов
Last updated 2 months, 1 week ago