# Понедельник 14 твитов
Всем доброго утречка. Я Сергей Сова (@_sergeysova). Я лид фронтовой команды Питерского @REDMADROBOT. Меня беспокоит… twitter.com/i/web/status/1…
7:16Давайте начнем с вопроса. Что такое архитектура фронтенда? Это как директории называются? Правила взаимного импорта… twitter.com/i/web/status/1…
8:15Почему меня вообще беспокоит архитектура и структура проекта? Начну с того, что "хорошая" структура вносит ясность.… twitter.com/i/web/status/1…
8:44С архитектурой сложнее, ведь она про отношение сущностей вашего проекта. Как выстроить зависимости между сущностями… twitter.com/i/web/status/1…
8:44Если со структурой все примерно понятно — описал конвенции в README, накинул правила в eslint и dependency-cruiser,… twitter.com/i/web/status/1…
8:44И если погрузиться чуть глубже, то скорее всего такой линтер и не получится создать. Архитектура это какой-то страш… twitter.com/i/web/status/1…
8:44Мне это напоминает стопку сбалансированных камней. Только архитектор может удерживать проект в устойчивом положении… twitter.com/i/web/status/1…
8:44Когда проект начинается, сразу раскладывать по какой-то сложной структуре вообще не хочется. Кажется, что это слишк… twitter.com/i/web/status/1…
10:04Проект растет и растет количество кода, вместе с директориями и файлами. Если не вводить четкой структуры проекта… twitter.com/i/web/status/1…
10:04Проблема в изменении существующего кода, ведь найти все возникшие дубликаты и использование функций/компонентов буд… twitter.com/i/web/status/1…
10:04Но постой-ка Сова, напишете вы, Чистая архитектура Мартина советует выстроить проект таким образом, чтобы любая нов… twitter.com/i/web/status/1…
10:04Но давайте вспомним что мы живем в реальном мире, хоть минимальные, но изменения придется внести в кодовую базу. Пе… twitter.com/i/web/status/1…
10:04Здесь архитектура и структура проекта играет ключевую роль. Архитектура позволяет выстроить взаимодействие высокоур… twitter.com/i/web/status/1…
10:04Разумеется придется изучить архитектуру и структуру выбранную в проекте, чтобы понимание стало интуитивным. А если… twitter.com/i/web/status/1…
10:04# Вторник 7 твитов
А что на счет microfrontends? Это ли не идеальная архитектура?
12:14Вот только стоит учесть, что microfrontends также как nrwl это не архитектура. А лишь способ организовать часть арх… twitter.com/i/web/status/1…
12:20@jsunderhood Без привязки к конкретному проекту и условиям его разработки говорить об идеальном решении не корректно.
Все архитектуры плохие. Нет универсальных хороших решений. Да, есть типичные проекты, архитектура которых весьма од… twitter.com/i/web/status/1…
@jsunderhood Без привязки к конкретному проекту и условиям его разработки говорить об идеальном решении не корректно.
12:23
По большому счёту, архитектура не про конкретные инструменты. Она о том как разделить код приложения и легче его по… twitter.com/i/web/status/1…
12:26Если проект призван жить долго, то он уже стал «кораблем Тесея» — рано или поздно все его составные части будут заменены.
12:28В большинстве тредов я буду говорить об архитектуре в пределах одного проекта-приложения.
Всякие сложные решения… twitter.com/i/web/status/1…
12:31Но при этом всём, вполне возможно описать универсальную структуру проекта.
Универсальность здесь будет не в названи… twitter.com/i/web/status/1…
# Среда 11 твитов
За мои несколько лет попыток сделать универсальную архитектуру, я случайно обнаружил структуру, которая позволяет о… twitter.com/i/web/status/1…
10:51FeatureSlices существует на стыке множества разных подходов, там и .NET, и hexagonal, и вообще много опыта в разных… twitter.com/i/web/status/1…
10:55Первое, что я стремлюсь сделать в любом проекте, это определить опасный и безопасный код. Опасный код — это такие с… twitter.com/i/web/status/1…
10:56К сожалению, невозможно писать лишь безопасный код. Ведь тогда, от этого кода никто не зависит, а значит его никто… twitter.com/i/web/status/1…
10:56К счастью, многолетняя история программирования подарила нам волшебную концепцию — инкапсуляцию. Мы можем скрыть де… twitter.com/i/web/status/1…
10:56Задача инкапсуляции — скрыть все детали под красивым названием, может даже несколькими. Ровно так мы и поступаем, к… twitter.com/i/web/status/1…
10:56И если продолжить аналогию, то легко понять, что код внутри компонента безопасен, его можно менять не переживая, чт… twitter.com/i/web/status/1…
10:57Задача архитектуры разделить весь проект на высокоуровневые блоки-компоненты, обезопасив код внутри каждого.
11:18Немного поразмыслив, я понял, что любой реюзабельный код опасен. Чем чаще его используют, тем сложнее вносить измен… twitter.com/i/web/status/1…
11:19Если я понимаю с каким типом кода я работаю, я знаю, что я могу с ним сделать.
При некотором исследовании разных п… twitter.com/i/web/status/1…
11:20При этом UI-компоненты, парсеры, конвертеры и прочий библиотечный код можно вполне закономерно вынести в директорию… twitter.com/i/web/status/1…
11:21# Четверг 17 твитов
В идеале, бизнес-логика должна быть отделена от остальных частей приложения. Может быть даже вынесена в отдельный б… twitter.com/i/web/status/1…
12:03Рефакторинг — изменение кода, не изменяющее поведение и интерфейсы модулей. Всякие вьюхи, контроллеры навигации и п… twitter.com/i/web/status/1…
12:11Во время проектирования я предпочитаю думать о вьюхах и контроллерах как о заменяемых модулях. В какой-то момент в… twitter.com/i/web/status/1…
12:30Даже если мне никогда не понадобится заменять React, такой подход позволяет четко разделить обязанности и описывать… twitter.com/i/web/status/1…
13:57Но в своих проектах я далеко не всегда выделяю бизнес-логику в отдельный пакет. Все потому, что придется придумыват… twitter.com/i/web/status/1…
13:58Архитектура должна развиваться вместе с проектом и требованиями к нему. А значит, пока выделение бизнес-логики в от… twitter.com/i/web/status/1…
14:04Но соломку конечно же подстелю — разделю вью и модель так, чтобы в будущем выделение бизнес-логики в отдельный паке… twitter.com/i/web/status/1…
14:07Итак, определенно у нас есть код страниц, модель которых никак не переиспользуется. Это всякие контроллеры форм, ре… twitter.com/i/web/status/1…
15:55В моем случае, разделение логики и вью это размещение кода в двух разных файлах-модулях.
Например: pages/login/{index.tsx, model.ts}
15:56При необходимости сама бизнес-логика может быть легко выделена из модели в отдельный модуль, при этом в модели стра… twitter.com/i/web/status/1…
15:56А еще есть код, который разделяется некоторыми страницами, то есть используется сразу в нескольких местах. Например… twitter.com/i/web/status/1…
15:56Вернемся к разделяемой логике. Куда класть модель управления данными используемыми сразу в нескольких страницах?
16:42В методологии FeatureSlices это называется feature. Одна фича это переиспользуемый общий код относящийся к одной су… twitter.com/i/web/status/1…
16:43В случае аутентификации и авторизации, бизнес-сущностью является текущий пользователь, так называемый viewer.
16:43В фиче viewer может лежать все что нужно для работы с текущим пользователем: проверка прав доступа, компонент для э… twitter.com/i/web/status/1…
16:43Но при этом, процессы входа(создания сессии) не являются фичей, так как не разделяются и не переиспользуются на разных страницах.
16:44Ведь способов входа может быть достаточно много: по номеру телефона, email + password, email + link, вход после вос… twitter.com/i/web/status/1…
16:44# Пятница 15 твитов
FeatureSlices не является догмой или строгими правилами по которым нужно проектировать и разделять код. Это рекомен… twitter.com/i/web/status/1…
10:10Если в Вашем приложении имеются общие компоненты или код в процессах аутентификации, вполне можно вынести суб-проце… twitter.com/i/web/status/1…
10:11Важный момент — документация. Стоит создать README.md для каждой фичи и накидать туда описание фичи,… twitter.com/i/web/status/1…
10:11Главное не забывать просматривать документацию и сверять с актуальным состоянием, может нужно отрефакторить, чтобы… twitter.com/i/web/status/1…
10:11Какие компоненты класть в UI, а что оставить в фиче?
Сразу стоит понять, что компоненты во фронтенд проекте могут лежать в любой директории.
Разделение проекта на директории необходимо, чтобы понимать назначение лежащих внутри файлов, как их менять и что м… twitter.com/i/web/status/1…
10:16Важно, чтобы в такой библиотечный код не протекали особенности бизнеса. Ведь если такое случится модифицировать и п… twitter.com/i/web/status/1…
10:16UI это внутренняя библиотека строительных блоков проекта. Я уверен, что в любом проекте можно выделить внушительную… twitter.com/i/web/status/1…
10:16Такие компоненты называются контекстонезависимыми. Ведь для использования компонента не нужно учитывать контекст ис… twitter.com/i/web/status/1…
10:16Пример: выпадающее меню составлено из выпадающего блока, списка и кнопки с иконкой. При этом, четкой области примен… twitter.com/i/web/status/1…
10:17Чего нельзя с уверенностью сказать про компонент профиля текущего пользователя. Используя тот компонент, можно пост… twitter.com/i/web/status/1…
10:17Ставьте лайкосы твитам, а то непонятно, интересно это или я просто не во время пишу твиты и их не видят. Какой там прайм-тайм в IT-твиттере?
10:20У твиттера отвратная аналитика по твитам. Даже у гитхаба и simplecast сильно лучше.
10:20Все компоненты без контекста я укладываю в UI, всякие библиотечные реализации в lib, но только если там есть дополн… twitter.com/i/web/status/1…
10:25А вот компоненты с четким контекстом располагаются по фичам. Причем необходимо четко определить область применения… twitter.com/i/web/status/1…
10:25# Суббота 54 твита
Каким боком @EffectorJS помогает выстроить архитектуру приложений? Очень просто: он является языком описания бизнес… twitter.com/i/web/status/1…
12:00К чему мы привыкли? Встраиваем управление состоянием внутрь React. И после этого продолжаем называть REACT библиоте… twitter.com/i/web/status/1…
12:01Мне не нравится такое положение. Из-за возраста React нам приходится очень долго ждать ConcurrentMode, терпеть изде… twitter.com/i/web/status/1…
12:02Чего я хочу от библиотеки рендеринга? Простого разделения ответственности, изящной интеграции СТМ, не сложного SSR,… twitter.com/i/web/status/1…
12:08Да. Я хочу, чтобы вьюха зависела от бизнес-логики и подчинялась её законам. Чтобы не приходилось вымучивать интегра… twitter.com/i/web/status/1…
12:08Помните нас «ублажали», что Реакт это «функция от состояния»? Мол, передали пропсы сверху в корневой компонент и по… twitter.com/i/web/status/1…
12:34Ага. Только если не используем хуки и классовые компоненты. Очевидно, что нужно иметь способ управлять состоянием приложения снаружи.
12:34Взять даже пресловутый SSR. Посмотрите на костыли NextJs, для того, чтобы запустить релевантные функции загрузки данных.
12:35Просто вдумайтесь: чтобы сделать SSR, пришлось построить огромный ФРЕЙМВОРК поверх реакта и новую экосистему! Экосистему, Карл!
12:35Чем дольше я пишу на реакте и чем больше создаю веб-приложений, тем больше убеждаюсь, что вьюха должна строиться во… twitter.com/i/web/status/1…
12:56То, что делает Redux, RxJs и MobX так это встраивание БЛ внутрь жизненного цикла слоя представления. А это сразу же… twitter.com/i/web/status/1…
12:57БЛ-процесс запускается из вьюхи, а значит на сервере ждет проблема в виде необходимости вытащить этот запуск из вью… twitter.com/i/web/status/1…
12:58А в браузере нужно дождаться рендера компонента, чтобы запустить логику. Вместо того, чтобы запустить логику сразу,… twitter.com/i/web/status/1…
12:58Нельзя просто так запустить логику вне компонента. Ведь СТМ лежит в контексте и извлечь наружу весьма проблемно. Пр… twitter.com/i/web/status/1…
13:01...логику использования этого служебного компонента(привет reatom), потерю семантичности jsx разметки. Притом, что… twitter.com/i/web/status/1…
13:01Если нужно, чтобы БЛ работала по своему особенному жизненному циклу не связанному с ЖЦ реакт компонента, то извините, придумывайте костыли.
13:01Я крайне не понимаю людей, которые рекомендуют не брать СТМ и писать на чистом реакте. Это же билет в один конец — станция метро «Наследие».
13:02Очень легко писать WriteOnly код. А как потом разбираться в куче memo и неизвестных причин рендера/ремаунта, которы… twitter.com/i/web/status/1…
13:03Пару лет назад, я понял, что хочу себе СТМ, который позволит из вьюхи отправлять оповещения о произошедших событиях… twitter.com/i/web/status/1…
13:40Чтобы БЛ жила отдельно своим процессом и могла самостоятельно реагировать на события и решать, нужно ли запустить л… twitter.com/i/web/status/1…
13:41Вьюха стала бы «функцией от состояния». БЛ обновляла бы состояние когда ей потребуется, именно те кусочки стейта, к… twitter.com/i/web/status/1…
13:42А прикиньте, как круто избавиться от необходимости в селекторах и мемоизации?
13:42А что если состояние приложения не уложить в дерево без поломки очевидности кода?
13:42Как избавиться от гонок обновлений в ромбовидных зависимостях?
13:42Может есть способ не тащить 100Кб СТМ без привязки к классам, но получить все эти возможности?
13:43Давайте попробуем старую практику как мир: лайк этому посту от вас, факт про эффектор, его историю и концепции от м… twitter.com/i/web/status/1…
13:51Изначально effector был миддлварой для ридакса и разрабатывался для высоконагруженного клиента реалтайм чата, вроде Телеграм.
14:06Пока флоу не умер, имелась его первоклассная поддержка. Сейчас типы затачиваются под TypeScript.
14:07Flow и Reason остались для поддержки обратной совместимости.
14:07Команда effector очень щепетильно относится к своим пользователям. Не выкатывая мажорных версий с кучей несовместимых изменений.
14:07Все новые фичи добавляются в минорных версиях. Мажорные версии только удаляют устаревшие методы. Мажор выход раз в… twitter.com/i/web/status/1…
14:07Русскоязычный чат в Телеграм ждет ваших вопросов и предложений. Удивительно, но у эффектора есть пользователи по вс… twitter.com/i/web/status/1…
14:11Эффектор занимается обработкой данных, а не жонглированием декораторами, стримами, пропсами и мемоизацией. Всё в его API нацелено на данные
14:14Во времена первых версий требовался инструмент, позволяющий управлять данными в сложных приложениях без опасности р… twitter.com/i/web/status/1…
14:16Сторы для приложения должны быть лёгкими, насколько это возможно — не должна пугать мысль о том, что нужно добавить… twitter.com/i/web/status/1…
14:22Сторы должны свободно совмещаться — идея в том, что данные, которые потребуются приложению, можно распределить стат… twitter.com/i/web/status/1…
14:23Принцип работы должен by design исключать необходимость в reselect, оповещая об изменениях только тех, кому они необходимы.
14:38Это позволяет не задумываться о том, что у тебя будет триггериться всё приложение если ты захочешь вынести стейт м… twitter.com/i/web/status/1…
14:38Возможность, место, и способ вынести любую требуемую бизнес-логику из view, максимально упрощая компоненты
14:45Независимость от спорных концепций — никаких декораторов, никаких зависимостей от реакта/rxjs либо необходимости юзать классы или прокси
14:45Ничего из этого не требуется для управления состоянием приложения и поэтому апи библиотеки использует только функции и простые js объекты
14:45Предсказуемость API — небольшое число базовых принципов переиспользуются в различных кейсах, снижая нагрузку на юзе… twitter.com/i/web/status/1…
14:45Те же базовые принципы позволяют построить вокруг эффектора дополнительные библиотеки методов, не снижая очевидност… twitter.com/i/web/status/1…
14:45Приложение строится из комбинации базовых элементов и возможности строить новые.
14:50Нет никакого смысла стремиться выдать всё за стрим, за редьюсер или за обсервабл, в приложении требуются они все, и… twitter.com/i/web/status/1…
14:50Отличие эффектора от контекста, и разница с внутриреактовыми сторами сводятся к одному: зонам ответственности.
14:50Концепция реакта подразумевает, что фронтенд-разработчики — это части гигантского организма, в котором всё предопре… twitter.com/i/web/status/1…
14:50Вся концепция эффектора предполагает, что мы сами решаем, что и когда мы отображаем, и каким образом обрабатываем —… twitter.com/i/web/status/1…
14:50Метод sample взял свое название из микроэлектроники. Гуглить «сэмплирование сигнала». Назначение: взять данные из с… twitter.com/i/web/status/1…
16:46Эффектор предполагает, что все редюссеры чистые. Почитать про чистоту effector.now.sh/docs/glossary
16:46Для асинхронных вычислений имеется отдельный контейнер — Эффект. Называется так, потому что его нужно использовать… twitter.com/i/web/status/1…
16:4620 и 21 версия вовсе не означает, что эффектор прошел столько мажорных обновлений. На самом деле, два года разработ… twitter.com/i/web/status/1…
16:47Типы тестируются не привычным для всех способом — с помощью снапшотов сохраняется реакция системы типов на код. Так… twitter.com/i/web/status/1…
16:47Уже несколько лет автор разрабатывает Effector full-time на пожертвования и помощь сообщества. Призываю закинуть $5… twitter.com/i/web/status/1…
16:47# Воскресенье 7 твитов
В качестве основ для концепций эффектора использовался Лисп. Но больше как теория, а не фактические решения. …ias-papers.s3-eu-west-1.amazonaws.com/interlisp-vm.p…
13:26Я заметил тенденцию в Телеграм сообществе. Все неудачные решения тяжело реализовать на Effector. При этом хорошие п… twitter.com/i/web/status/1…
13:29Это определенно очень круто! Столько желающих. Но это сильно больше, чем мое воображение и память способны выдать з… twitter.com/i/web/status/1…
20:26Я отвечу на все оставшиеся вопросы со своего аккаунта. А также постараюсь добить тред фактами.
Начнем новый тред п… twitter.com/i/web/status/1…
20:26Всем спасибо за эту неделю!
Вести коллективный аккаунт это круто. Видеть, что люди согласны с высказываемыми мысля… twitter.com/i/web/status/1…
20:29Очень приятно видеть лайки от людей, которых я уважаю. Не знаю, что именно они выражают этим, но надеюсь согласие.
20:29Надеюсь на интересные и жаркие дискуссии в будущем. Расскажите, как вы проектируете свои React-приложения?
20:29