_sergeysova

29 июня 2020, Saint Petersburg, Russia

# Понедельник 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…

12:43

# Среда 11 твитов

За мои несколько лет попыток сделать универсальную архитектуру, я случайно обнаружил структуру, которая позволяет о… twitter.com/i/web/status/1…

10:51

FeatureSlices существует на стыке множества разных подходов, там и .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, а что оставить в фиче?
Сразу стоит понять, что компоненты во фронтенд проекте могут лежать в любой директории.

10:13

Разделение проекта на директории необходимо, чтобы понимать назначение лежащих внутри файлов, как их менять и что м… twitter.com/i/web/status/1…

10:16

Важно, чтобы в такой библиотечный код не протекали особенности бизнеса. Ведь если такое случится модифицировать и п… twitter.com/i/web/status/1…

10:16

UI это внутренняя библиотека строительных блоков проекта. Я уверен, что в любом проекте можно выделить внушительную… 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:07

Flow и 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:46

20 и 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

other