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

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

В голову сразу же приходит viewport, но это довольно топорный инструмент, который просто скейлит весь экран. Было бы здорово иметь возможность динамически изменять размер контролов, не менять или менять по другому размер контента и применять ко всему этому медиа-выражения.

Решение - цсс-шлюзы. Демку с описанием можно найти тут, а в заголовке поста есть ссылки на английскую и русскую статьи с детальным объяснением идеи.

Базовый принцип такой: берем среднюю (медианную) ширину экрана целевой аудитории, под которую будем верстать, переводим 16px (базовый размер шрифта) в vw: для 1600px - это 1vw, для 1336px (стандартное для windows ноутбуков) - это 1.2vw и выставляем как font-size на html.
Теперь, чем меньше или больше будет размер экрана отличаться от базовой ширины, тем сильнее будет меняться и размер шрифта, что будет отражаться на всей нашей верстки, если мы будем описывать все размеры в em.

Но это не все, три важных уточнения! em наследуется по дереву, все может непропорционально меняться в случае необходимости изменения шрифта в каком-то узле, поэтому везде используем rem. Что бы не ломать пользовательский скейлинг (зум и системные настройки размера шрифта), стоит добавить в наш код абсолютные еденицы. И стоит поставить ограничения для слишком узких и огромных экранов. В итоге, получаем такой код:

html {
font-size: clamp(0.7em, calc(0.5vw + 0.7em), 1.4em);
}


Подогнал для красоты и запоминания все под семерки, но лучше значения настраивать самому и не пугаться больших дробей.
👍5
Очередная жертва дефолтных экспортов. Комичность еще и в том что импорт в модуле добавления рекламного тега - AddTag (неймспейс adTags), из-за чего становится совсем не ясно, нарочно ли был импорт так назван.
👍5🤔4💩2
artalog
🛑 в этом посте есть ошибки 🛑 Идемпотентность. TLDR: не мутируйте в useEffect! 1. Реакт позволяет с помощью useEffect описать какой-то эффект в ответ на изменение данных. 2. В рамках конкурентного рендеринга эффекты могут перевызываться лишний раз, под StrictMod…
Я был сильно не прав, useEffect не вызывается лишний раз.

Очень стыдно, простите 🙃

Избыточно перевызываться могут только хуки мемоизации.

За поправку спасибо @BuggyTheClown.

Но я еще подкину интересного по теме: Design decision: why do we need the stale closure problem in the first place? Старый и до сих пор не закрытый ишьес, в котором можно найти много занятный примеров. Может, повычитываю его потом повнимательней и скину сюда самое интересное.

UPD: useEffect без зависимостей все же может вызываться дважды в девелопе со стрикт модом.
👍4🤔2🔥1
Live stream started
Live stream finished (32 minutes)
Resumability: a no-overhead alternative to hydration

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

Напомню проблему: всякие реакты и даже свелт после загрузки HTML от SSG / SSR предполагают загрузку его копии внутри JS в виде шаблонов, для построение биндингов к дому. Выглядит очень избыточно и статья о том и говорит. А еще это способствует не гранулярной работе с ДОМом и последующим томозам в рантайме.

Проблема делать иначе в том что для построения биндингов ЖСа к событиям и атрибутам ДОМа без наличия всего тела темплейта нужен достаточно хитрый компайлер, который все равно будет вас сильно ограничивать.

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

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

Будет чудо, если в этом году я найду время на то что бы этим заняться 👀
👍12
rome.tools

Идея унифицированного инструмента для всех AOT (билд-тайм) преобразований очень здравая, зачем парсить текст и выделять семантику несколько раз. За Ромом стоят опытные разработчики (автор Babel), они уже подняли инвестиции и все бы ничего… Но продукта небыло очень долго и лично меня это сильно смущает. Говорят много, пощупать можно было мало. Два года потребовалось что бы выпустить форматтер, о котором я сегодня и хотел рассказать.

Начал понемногу пробовать его через расширение для vscode на реатоме, скорее по фану, пока что. Но оно preview, не отрабатывает и не пишет ошибки в output, если таковые есть - просто ничего не происходит. В плейграунде можно увидеть ошибки, но я вот вставил туда 600 строк кода и интерфейс фризится на секунды на моем m1.

Разницу с prettier можно увидеть тут. Правда, туда залетели дефолтные табы, использование которых странно для тех кто близок к OSS и гитхабу и знает как ужасно они там отображаются.

В общем, как вы могли заметить, у меня впечатления от всей этой истории негативные. Но, честно говоря, это потому что я многого ожидаю от этой тулзовины и хочется получить сразу все здесь и сейчас. Надеюсь, у них все получится.
👍5🤔2
Вот несколько примеров отличия от prettier, которые не касаются конфигурационных параметров.
🔥3🤔1
Так, пояснение. Я не верю в единственный правильный форматтер и только ради условно красившего форматирования уходить с преттиера, который стандарт индустрии, не стал бы.

У рома главная фича в экосистеме, которой сейчас нет 🙃.

Но! У него есть возможность парсить даже синтаксически ошибочный код - это может быть полезным во время разработки.
👍5
Live stream started
Live stream finished (20 minutes)
Асинхронная очередь.

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

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

Мне показалась моя же реализация сложной и не очевидной / не надежной и я решил еще подумать. После пары экспериментов в голову стукнуло максимально простое и понятное решение:


let chain = Promise.resolve()
export const add = cb => chain = chain.then(cb)


Тут здорово что then не хранит ссылку на предыдущий промис и нам не нужно заботиться об очистке памяти, под капотом список выглядит как односвязный linked list, голову которого подчищает GC, а мы храним только хвост.
👍16🔥4
Вот еще одна простая, но очень полезная утилита для очередей.

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

Заводить под это дело очередь и кидать в нее колбеки не удобно, код перестает выглядить синхронно и могут появляться конфликты имен переменных в скоупах колбека и кода после него.

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



Посмотрел на предыдущий пост, можно было бы сделать еще проще:

freeMsgLimit = () => add(sleep(TLG_MESSAGE_LIMIT))

😀
👍6
Дождаться завершения всех промисов.
Продолжаем про асинхронные очереди 🙂

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

Придумали?

Т.к. в редаксе есть единая централизованная точка входа на все IO сделать там это очень просто: накинуть мидлвару, которая создаётся из функции которая принимает колбек и создаёт в замыкании каунтер эффектов. Если из диспатча возвращается instanceOf Promise - инкрементим каунтер и вешаем finally с колбеком на декремент каунтера, где еще проверяем, если каунтер стал нулем - вызываем колбек окончания всех эффектов.


store.dispatch = (…a) => {
i++
originalDispatch(…a).finaly(() => {
if (--i === 0) resolve()
})
}


Для реатома я делал что-то похожее.

И эффектор за кажущейся простой так же требует централизованную точку входа (scope, fork) и под капотом ведёт такой же каунтер.
👍5
react-admin

Я искренне считаю что будущее программирования за low-code решениями.

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

Но такие библиотеки есть, react-admin позволяет одним JSX описанием одновременно запросить, отобразить и дать изменить данные с API. Количество кода и его поддержка сокращается в разы. Квинтесенция компонентной архитектуры!

Конечно, есть миллион краевых случаев, где оно что-то не может, а где-то не интуитивно. Но со многими задачами справляется на ура. Я пробовал эту либу год назад, столкнулся с кучкой проблем, но в общем понравилось. Недавно вышла 4 версия в которой провели серьезный технический рефакторинг (redux -> react-query и mui5).

Рекомендую попробовать, хотя бы что бы посмотреть как вообще бывает.

#lowcode
👍9👎3🤔2💩2
hasura.io

Ещё одно прекрасное #lowcode решение - на стыке фреймворка и графического интерфейса.

Хасура - это платформа для быстрого построения оптимального бекенда. Основной сценарий такой: запускаем ее с кредами к одной из поддерживаемых БД, открываем сайт админки, создаем новую таблицу / колонку / связь / запись или что-то еще делаем в визуальном редакторе и мгновенно получаем обновленный GraphQL апи с типовыми CRUD операциями и базовыми констрейтами. Система пермишенов и гайды как ее настраивать есть из коробки. Для валидации и сложной / асинхронной логики есть экшены - что-то вроде встроенного serverless.

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

Вообще, фич у Хасуры очень много: миграции, REST апи, кеширование, оптимизации SQL и куча всего. И мне хочется похвалить их документацию, за пол года пользования у меня почти не появлялись неотвеченные вопросы.

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

При этом, им уже лет или больше, они в опенсурсе, написано оно на хаскеле 🙃 и за все мое время пользования этот продукт воспринимался не как поломанный стартап, что сейчас стандарт, а как надежный и готовый продукт.
👍13
Live stream scheduled for
Live stream started
Пол часа поговорим про хасуру. Расскажу про свой опыт. Будет запись
👍4