artalog
4.24K subscribers
542 photos
40 videos
40 files
913 links
Развернутые ответы на вопросы в чатах, мысли от рабочих процессов.
Вопросы - @artalar.
Download Telegram
useSyncExternalStore

Подъехал очередной апдейт beta.reactjs.org. Все достаточно подробно и просто описано, только вот это вот важное замечание где-то вконце скрывается: If a different subscribe function is passed during a re-render, React will re-subscribe to the store using the newly passed subscribe function. You can prevent this by declaring subscribe outside the component.

Иначе говоря, НЕ создавайте функции для гета или подписки инлайн (как для useEffect), иначе на каждый ререндер будет отписка и подписка useSyncExternalStore((cb) => some.subscribe(cb))

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

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


Недавно, начал писать адаптер для Preact. Это не полная калька с адаптера для реакта, потому что у преакта батчинг есть уже давно, а для обобщенных хуков есть options api. Казалось, что debounceRendering решает мою проблему оборачивания рендеринга в собственный хук, но вылезло две проблемы: 1) пока не понял как добраться до провайдера что бы получить релевантный контекст реатома; 2) этот колбек не вызывается для первого рендера =/

Повторю в сотый раз всю ту же истину реактивного программирования - при вынесении связей в рантайм неизбежно появляются конфликты очередей обслуживающих эти связи. Пока мы не придем к единому стандарту единой очереди (или комплексу правильно связанных очередей) - разработчики библиотек и их пользователи будут страдать от краевых случаев. Но стандарта такого пока не намечается…
🔥8
Forwarded from Reatom новости (artalar)
Стори тесты!

Идея такая: пишем отдельные тесты с адекватным неймингом и коментами и автоматически копируем их в доку.

Отличие от реплов / сендбоксов в том что такой тест проверятеся на каждый апдейт в используемых фичах и всегда будет актуален. Ну и ментейнеру немного меньше работы :)
Так же, такой текст позволяет показать какой-то сценарий работы (многоступенчатый?). В репле это не удобно расписывать, а просто текстом обычно занимает много места - скриншоты с повторным кодом и т.п.

Что думаете?

Примеры:

https://www.reatom.dev/packages/async#story-test

https://www.reatom.dev/packages/testing#story-test
🤡2👏1
Написал код копайлотом и проверил с помощью ChatGPT
(сначала рили не понял зачем “+1” нужен)
🤯23😱4
Service Worker

Недавно подключал их к reatom.dev для офлайн доступа и быстрого повторного захода: https://github.com/artalar/reatom/pull/448, по коммитам можно увидеть как не просто мне это далось :)

В интернете очень много статей с нерабочим кодом, причем некоторые статьи из 2020 🤷‍♂. Мне больше всего помогла статья из заголовка и вот эта: https://habr.com/ru/company/2gis/blog/345552/, тут сразу есть несколько простых примеров под разные стратегии.

В планах еще подрубить htm для обновления контента после загрузки офлайн версии без необходимости перезагрузки страницы. Просто реплейснуть html будет плохо тк скролл и другие состояния собьются.

P.S. да я тыкал workbox, мне он простым не показался.
👍12🔥2
Forwarded from UfoStation
ufostation.tech

Завершил веху работы над сайтом — перенес основные посты из телеграмм канала. Все исходники в открытом виде на github, материалы свободно распостраняются по CC BY-SA 4.0 (копируй/модифицируй).

Буду рад любой обратной связи, которая поможет улучшить ресурс: комментарии под этим постом, сообщения в личку, любой issue или pull requests на github.

Нравится контент? Поддержи меня на boosty 🙃
🔥82👍1
artalog
Service Worker Недавно подключал их к reatom.dev для офлайн доступа и быстрого повторного захода: https://github.com/artalar/reatom/pull/448, по коммитам можно увидеть как не просто мне это далось :) В интернете очень много статей с нерабочим кодом, причем…
Service Worker для блога.

Повторюсь, в интернете статьи очень разрозненные и в некоторых код нерабочий, мне больше всего помогли: MDN и вот эта статья с готовыми примерами.

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

Заметки.

Типы нужно подключать явно так:

/// <reference lib="webworker" />


При этом addEventListener(“fetch”, (event) => …) все равно не выводит event, проставляем явно ExtendableEvent.

caches.match(request) не делаем! Используем только определенную версию caches.open(CACHE).then((cache) => cache.match(request)) что бы можно было ее поменять в случае какой-то ошибки или большой миграции.

Положить в кеш данные браузерного экстеншена нельзя, поэтому их нужно явно скипать !request.url.startsWith('http'), что бы не сыпались ошибки.

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

Тк получение нового контента sw может произойти И до старта скрипта апдейта на странице И позже, нужна простая версия хендшейка - отправляем апдейт сразу и на 'client-ready’, все это в промисе на waitUntil, при этом не забываем фолбек таймаут на клинап что бы промис не завис, на случай быстрого закрытия страницы (до окончания загрузки) и тп.

На клиенте получить новый контент и сравнить с текущим можно как-то так:

new DOMParser()
.parseFromString(data.text, 'text/html')
.querySelector('main')
.innerHTML
===
document.querySelector('main').innerHTML


Скрипт подключения воркера и апдейта контента нужно вынести отдельно и не кешировать.
👍10🔥3
artalog
О канале рекламу не даю Привет, меня зовут Артём Арутюнян aka @artalar, я разрабатываю крупные ИТ-сервисы больше 10 лет, половину из которых программированием на JS. Выступаю на конференциях. Участвовал во множестве разнообразных проектах в роле системного…
Дейли ремайндер: https://getmentor.dev/mentor/artem-arutyunyan-162

Помогу:
- разработать архитектуру фронт приложения под требования
- оптимизировать рантайм производительность существующего кода
- спланировать рефакторинг или миграцию на новые технологии
- написать хорошо компонент \ модуль со сложной логикой
- провести ревью ПРа \ архитектуры и репозитория react приложения
👍11💩1
В чате спрашивают про бесплатную замену хероку. Кмк из бесплатного vercel - топ.

Он же на каждый ПР создает новую среду - максимально удобно. Помогло безопасно тестировать внедрение сервис воркеров 🙂

Еще из удобного, можно подключить скрипт в 1кб и получать аналитику (реальный пример на скрине).


UPD
- fly.io
- render.com (есть бесплатный план с БД)
- netlify.com
- pages.cloudflare.com
- glitch.com
- railway.app триал дает 500 часов работы, есть базы данных
👍18
IoC & DI

Не знаю где взять хорошую статью на эту тему (поделитесь в комментариях), напишу от себя.

Инверсия зависимостей (IoC) предполагает какое-то промежуточное ключ-значение (KV) хранилище через которое происходят ~все связи между модулями и библиотеками приложения. DI - конкретная реализация этого паттерна. Нужно это что бы контролировать эти связи, например:

- подменять реализацию в дев / прод сред или возвращать какой-то мок в тестах.
- разруливать DAG, циклические, асинхронные зависимости так что бы “оно просто работало”.
- упорядочивать (разделять) объявление и использование зависимостей для лучшего кодстайла и AOT анализа и оптимизаций.

> Иногда, сову натягивают на глобус и прикручивают к DI логер или начинают заниматься декорированием зависимостей, это точно плохая практика равносильная мидлварам, т.к. по коду зависимости или ее использования совсем не понятно откуда там взялась или поменялась какая-то логика.

Раньше у нас был cjs стандарт описания зависимостей - рекваеры можно было писать где угодно и с этим была куча проблем с точки зрения архитектурны, сборки, производительности. Радость была только в том что стандарт этот был мнимый и самопальный, поэтому мы могли спокойно его модифицировать - манкипатчить require и реализовывать какие-то фичи из первого пункта (привет, jest.mock). Стандарт импортов привнес более строгое и предсказуемое апи: топ левел == статические импорты и где-угодно асинхронные импорты. Для меня крайне интересно и не понятно почему у нас есть система импортов, но в ней не интегрированы фичи IoC - какие-то юзерспейс хуки. Хотя звоночки все равно доходят - import-maps.

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

- Мокать зависимости для тестов Jest уже умеет и для ESM, но он привносит доп сложность с точки зрения сетапа, да и работает не очень быстро. Если вы хотите запускать тесты быстро и с меньшими напрягами по сборке - используйте свой DI и какой-нибудь uvu.
- Если вы не хотите городить проверки на isLoading, а просто и прозрачно использовать лениво-подгружаемые зависимости, как данные с бекенда с React Suspense - берите DI-либу которая умеет в асинхроные резолвы.
- Если вы хотите лучше структурировать ваш код для лучшей читаемости или лучшего статического анализа - берите DI-либу которая не позволяет использовать Service locator, который считается антипаттерном (если не знакомы - гуглите сами, я не нашел хороших статей 😅).

Это было общее описание. А теперь про личный опыт и немного рекламы.

По моей практике сервис локатора на зависимости которые обрабатывают IO достаточно. Если у вас axios, можно обойтись лишь https://www.npmjs.com/package/axios-mock-adapter. Но иногда есть другие IO (postMessage), иногда нужно замокать какие-то таймеры или у сетевого слоя есть своя большая обвязка, или нужно замокать какие-то сильно изолированные модули, библиотеки. Я проектировал Reatom в том числе с расчетом на то что бы можно было легко тестировать порождаемые им сущности. Апишка впринципе задизайнена так что каждый атом / экшен работает только в переданном контексте (это нужно для множества фич), так почему бы этот контекст не использовать для моков - для этого уже есть пакет https://www.reatom.dev/packages/testing, он дает общий mock или mockAction для перехвата и подмены вызова какого-то сайд-эффекта. Круто то что в реатоме это просто работает, не нужен вообще никакой доп. код 🤗. Выглядит в использовании это максимально просто - мы либо оборачиваем каждый наш эффект в отдельный экшен, либо создаем сервис атом - тупо оборачиваем сервис в атом и обращаемся к сервису через чтение атома (кода это требует минимум). Пример есть в https://www.reatom.dev/core: const api = ctx.get(apiAtom).
P.S. в реатоме и логгер красивый есть.

UPD
- https://bespoyasov.ru/blog/di-ts-in-practice/
👍3🤮1
artalog
IoC & DI Не знаю где взять хорошую статью на эту тему (поделитесь в комментариях), напишу от себя. Инверсия зависимостей (IoC) предполагает какое-то промежуточное ключ-значение (KV) хранилище через которое происходят ~все связи между модулями и библиотеками…
Забыл еще рассказать про лайфсайкл хуки и возможность инстанцирования синглтона или фабрики… Вообще IoC - это сердце и архитектурный базис (на уровне апликейшена). Надо бы поподробнее потом расписать.
👍9
Решили использовать либу от одного очень большого интеграционного сервиса, а она поставляется только с их CDN, типов нет, а в исходниках лежит их package.json (WAT?) и в нем…
🤩10👍2😢2
codeque.co

Крутой тул, давно искал что-то такое. Регексп ищет по символам, а эта штука учитывает контекст из AST. Еще и eslint плагин есть.

На скрине пример простого решения задачи, которую я не смог решить на регекспах: найти вызовы useRequest где apiMethod передается по условию (нужно было это зарефакторить).

Кстати, для автоматизированного рефакторинга по AST посмотрите на putout.
👍14
Forwarded from Reatom новости (artalar)
🔥11👍3
This media is not supported in your browser
VIEW IN TELEGRAM
Зацените снежок на WebGL. Выглядит очень реалистично!

Вот исходники френдли для подключения к себе на сайт (блог). Весят около 18кб, причем большая часть это бейс64 картинка, можно поменьше свое что-то подставить.
🎄29👍31
Big State Managers Benchmark от автора $mol.

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

Тест проверяет только скорость перевычислений, не учитывая остальные паказатели. Так, реатом потребляет меньше памяти чем мобых (!), ну и бандлсайз имеет в 8 раз меньше.

Интересно, что в моих прогонах этого теста реатом практически догоняет мол по перфу и значительно обгоняет мобых. Но в моем упрощенном бенче мол заметно быстрее реатома (мобых вообще на дне).
🔥3🤡31