Немного о фронтенде, дизайне, работе и жизни. Пишу, когда есть чем поделиться. https://isqua.ru/
587подписчиков сейчас
0.0цитируемость
Русскийязык
Россиягео
Подписаться в Telegram
Данные обновлены 22.07.2020
Публикации всего: 42
Диктовка
На работе нам раскатили Wispr Flow — аппка для распознавания речи в любом текстовом поле. Ставишь курсор в слак тред, зажимаешь Fn и надиктовываешь, а он за тебя печатает.
На этой волне я решил и в айфоне чаще пользоваться встроенной диктовкой, ну где микрофончик у клавиатуры нажимаешь.
И то ли у меня с дикцией чё-то не то, то ли я натолкнулся на парадигму «сначала ориентируем продукт в США, а потом может быть когда-нибудь и на остальной мир». Потому что для меня диктовка работает откровенно плохо.
На компе общаюсь с коллегами — диктую на английском. Но произношение моё недостаточно american, и 1-2 words в каждой sentence распознаётся неправильно, you know. В итоге это занимает больше времени чем печать — а печатаю я быстро.
А с телефона диктую на русском. Тут уже распознавалка видимо на недостаточном корпусе обучена, и то половины слов не знает, то тоже не слышит мою вполне себе нормальную речь. У меня нет «дефектов» особенностей речи, я их в детстве с логопедом отработал.
Когда уже нормальное будущее с нормальными языковыми технологиями наступит?
😁 11 👍 1
Перейти к публикации →
Видели уже страничку с пулреквестами в гитхабе? Я только сегодня обнаружил редизайн, обычно как-то захожу в конкретную репу свои PR смотреть. Удобно в целом!
https://github.com/pulls/inbox
Европу накрыла heat wave, поэтому сегодня у нас рубрика РАСПАКОВКА В Германии кондиционеры делают, но не устанавливают. Как охлаждаться? Сгонял в аптеку и магаз, купил: 1. Охлаждающий гелевый пакет (справа снизу). В морозилку его, он замерзает, потом кладёте…
😁 17 🔥 13
Перейти к публикации →
Европу накрыла heat wave, поэтому сегодня у нас рубрика РАСПАКОВКА
В Германии кондиционеры делают, но не устанавливают. Как охлаждаться? Сгонял в аптеку и магаз, купил:
1. Охлаждающий гелевый пакет (справа снизу). В морозилку его, он замерзает, потом кладёте на голову или куда вам там надо
2. Пакет гипотермический одноразовый (большой белый). На экстренный случай, если уходите куда-то или холодильник помер. Для использования ударьте его, внутренняя капсула порвётся, и он начнёт замерзать
3. Изотоник в таблетках. С потом теряем электролиты, с водой их не восполняем. Работает как терафлю — кидаете таблетку в воду, она шипит и растворяется, пьёте.
4. Протеиновое мороженое (ведёрко). Совмещаем приятное с полезным.
5. Физраствор, он же NaCl 0,9% (ампулки по центру). Это не от жары, я всегда ношу с собой и пополнил запасы. Мало ли что в глаз попадёт — промыть, да и в целом в экран смотрю, глаза сохнут — капаю иногда. Или ранку промыть
Берегите себя
❤ 15 🔥 11 😁 6 · всего 33
Перейти к публикации →
Жизнь научила меня не смешивать разные изменения в одном PR
Фичи, багфиксы, рефакторинг — у этих изменений разный контекст и разный уровень риска. Бывает, сядешь за новую фичу, и видишь, отрефакторить бы немного, тогда фича отлично ляжет. Ну рефачишь, по дороге еще какой-то баг обнаружил в соседней фиче, его поправил, заливаешь пулрик на 1к строк с этим всем. В чём проблема?
Сложно одновременно всё ревьюить (разные контексты) но вам об этом ревьюеры и так скажут. Или будут морозить неделю, потому что такой PR читать лень. Но это не главное.
Вот вас кое-как оревьюили, тестеры протестировали, выкатили на прод. Бум! Какая-то проблема проскочила все защиты и надо срочно откатывать. Тоже не проблема — мы же умные, роллбечим релиз.
Но в мастере-то код сломан. И следующий релиз будет сломан. Тут головняк пропорционален частоте ваших релизов. Надо мастер тоже чинить. Быстрее всего — ревертнуть. Но как? Допустим, проблема в той новой фиче, и откатить нужно именно её. Но вы в том же PR ещё багу починили, отревертите тот PR — бага вернётся. А ещё рефакторинг сделали (разный уровень риска). А ваши коллеги может уже понаписали там что-то поверх, будете ревертить — конфликтов не оберётесь. Короче, удачи.
А если бы вы в трёх отдельных PR сделали то же самое, ревертнули бы только фичу. Опенсорс тоже говорит об этом, вспомните React 18.3. Они там прямо говорят, что к предыдущей версии они добавили лишь ворнинги для подготовки к react 19. Чтобы обеспечить 3-шаговое обновление:
Шаг 1: Обновляетесь до 18.3 — если вы были на 18.2, то код совместим
Шаг 2: Чините все ворнинги и deprecations — короче активно шатаете кодовую базу
... тут вы даже можете пожить с этим какое-то время и убедиться что всё ок ...
Шаг 3: Обновляетесь до 19.0 — это должно пройти практически бесшовно, если вы на шаге 2 всё починили
сгорел прод? ну откатываете версию, а код не надо трогать
То же самое при внедрении новых правил линтеров:
1. Сначала приводите код в соответствие правилу
2. Потом врубаете его на всех
Это перекликается с идеей Branch by abstraction из TBD. Там большие изменения не могут долго жить в отдельной ветке. Их дробят на маленькие безопасные шаги, которые можно быстро влить и быстро откатить.
О чём надо себя спросить перед открытием PR: как я буду в случае чего это ревертить?
🔥 7 ❤ 4
Перейти к публикации →
Привет, а вот и новое видео!
В прошлой серии мы залезли в одну функцию сортировки и улучшали её. В этот раз смотрим шире — почему так больно работать с компонентом и откуда берутся данные.
А конкретно:
— выносим бизнес-логику из React компонента
— разбираемся с концепцией derived state
— используем селекторы в Zustand
— пишем тесты 💚 на стор без React и DOM
— и даже ловим классическую ошибку с
getSnapshot в Next.js
Постарались сделать формат более живым, много обсуждений, сомнений и реальных решений по ходу.
Получился почти час 😅 наливайте чайку и залетайте к нам
https://youtu.be/oKbi-K2kj4Q
🔥 6 ❤ 2
Перейти к публикации →
Layers vs Vertical Slices
Кирилл Мокевнин (Hexlet) набросил, как файлы класть — по типу или по домену?
Для меня меня на фронтенде это вопрос давно решенный: если сервис больше чем 2 странички, то, конечно, по фичам. Иначе, чтобы поправить какую-то мелочь, надо по 5 папкам лазить.
📗 Главный принцип: low coupling, high cohesion
Недавно был на проекте: 90к строк кода, 4 фронтендера. Код разложен по слоям: consts, utils, hooks, api, components, pages. Так там утилит было на ~20к строк (четверть кодовой базы!), в них лежала почти вся логика приложения. В константах лежало 202 файла. Тип пропсов компонента из
src/components/statistics/CohortsTable.tsx лежал в src/types/statistics/CohortsTable.d.ts. Постоянные проблемы с циклическими зависимостями. Ребята генерили новый код, похожий на старый — трудно было найти нужное.
Когда в ру-язычной фронтенд-тусовке говорят про vertical slices, вспоминают FSD. Имхо, челы перегибают палку. Зачем деление на widgets/features/entities? Это тащит нас обратно — в low cohesion, high coupling. Поэтому туда не ходим, keep it simple, stupid.
И вот мы пару недель обсуждали, какие есть проблемы, почему больно это поддерживать, почему даже мелкие задачки занимают столько времени. В итоге проблема «хз че где» вышла на первое место по скору ICE (Impact × Confidence × Ease).
Мы выработали структуру и правила. Самое сложное было — выделить доменные сущности, об этом никто раньше не думал. Ещё за неделю раскидали 80% файлов, жить сразу стало легче. Подробнее писал в блоге компании (опубликовали в мой последний день там лол)
В src осталось три папки:
• app — рутовый компонент, провайдеры
• features — самая соль по доменам
• shared — общие компоненты
В каждой фиче (опционально): pages, ui, store, api, utils, const, types. При этом если какие-то константы, типы или хелперы нужны только для одного компонента, они идут в папку этого компонента. На уровень фичи поднимается только то, что нужно для нескольких модулей в ней.
Один коллега боялся, что пути/будут/вот/такие/длинные/ужас/кошмар. Но .../ui/Component это последний левел глубины. Внутри компонента всё плоско. Если меньше 10-15 файлов в папке, доп. уровни не нужны:
src/features/apps/ui/AppsTable/ AppsTable.tsx AppsTable.module.css DesktopRow.tsx MobileRow.tsx CellWrapper.tsx useColumns.tsx formatter.tsДальше учимся давать имена сущностям из вонючего ящика
utils и выделять их из файлов по тыще строк. Типовые куски:
• adapters/mappers — из ответов API в структуру, удобную для фронтенда и обратно — обычно в src/features/<feature>/api
• validators — валидаторы/схемы для формочек — к соотв. компоненту
• formatters — как мы даты форматируем и т.п. — к компоненту
Выкидываем barrel-файлы (index.ts с реэкспортами) из папок, которые не являются модулями:
• src/features/apps/ui/AppsTable — модуль (компонент), кладём index.ts, реэкспортируем «публичный интерфейс» — скорее всего, это сам <AppsTable /> и его пропсы. А всякую внутреннюю шелуху типа форматтеров или useColumns не реэкспортим
• src/shared/routing — модуль, кладём index.ts, реэкспортируем всякие константы маршутов, функции для их построения и тп
• src/features/apps/ui/ — не модуль, а просто папочка организационная
👉 Писал про barrel-файлы у себя в блоге.
Откуда я знал, что всё это сработает? Потому что уже строил такую архитектуру на проекте в Яндексе, который был крупнее, и мы жили так пару лет и всё отлично работало и скейлилось. Сейчас, посмотрев на проекты в других компаниях, понимаю, что dev experience на этом проекте был лучшим.
Зачем мы 2 недели обсуждали, если я сразу «знал, как надо»? Чтобы:
• провалидировать, что это решит проблемы именно текущего проекта, и именно самые больные
• адаптировать подход к проекту и команде, срезать углы, что-то улучшить
• ребята вовлеклись и участвовали в принятии решения, люди гораздо лучше делают то, что решили сами, чем что-то навязанное
Кстати, AI-агентам в такой структуре проще ориентироваться.
А вы в каком лагере?
🔥 features first: src/features/<feature>/ui
🤔 layers first: src/ui/<feature>/blabla
⭐️ уже иду рефакторить
🔥 13 ❤ 2
Перейти к публикации →
Структура файлов на проекте, импорты, barrel файлы. Пост ниже ↓
Неужели мы выпустили видео? Конечно выпустили!
Ну и шляпу там нам AI нагенерил, сортировка пузырьком. Рефакторим по TDD, максимально упрощая логику. Объясняем, в чём прикол разных локалей при сортировке.
Улучшили качество видео. Пока мы ещё не супер-блоггеры, но стремимся!
Энджой, лайк, подписка
https://youtu.be/rTbZ38qX_6Q
❤ 10 👍 2 🔥 1
Перейти к публикации →
Мифы про отличия Zustand и Redux
Работаю сейчас с zustand, который уже обогнал redux по загрузкам. Вот что говорят адепты zustand, сравнивая его с redux:
Миф 1: В Zustand можно создавать множество сторов вместо одного!
По факту и правда можно, но в доке Zustand советуют «single store». А если мол ваше приложение большое, можете разделить стор на слайсы.
В redux тоже single store, который можно разделить на слайсы. И в отличие от zustand, есть встроенное решение для динамической подгрузки слайсов, что позволяет делать код-сплиттинг и загружать только нужные слайсы.
Миф 2: В Zustand меньше бойлерплейта!
По факту и правда меньше, пока у тебя стор размером с "counter, increment, decrement". Как только тебе надо обновить поле где-то глубоко в дереве:
updateNestedParam: (value: string) => {
set((state) => ({
deep: {
...state.deep,
nested: {
...state.deep.nested,
obj: { ...state.deep.nested.obj, param: value }
}
}
}))
}
В то время как в redux уже давно можно просто:
updateNestedParam: (state: MyState, value: string) => {
state.deep.nested.obj.param = value
}
Чтобы решить эту проблему документация zustand советует нам immer. На этой библиотеке как раз работает redux, просто она уже встроена. А с zustand нужно писать всё вручную. Есть ещё опция прикрутить immer middleware, чтобы получилось ну-вот-уже-почти-как-в-redux, только вместо одной функции надо две писать:
updateNestedParam: (value: string) => {
set(state => {
state.deep.nested.obj.param = value
})
}
Миф 3: Ура, не нужно использовать Provider!
И правда не нужно. А это точно преимущество? Чтобы написать тесты на компонент, использующий redux, нужен враппер с preloadedState. В Zustand советуют мокать (!) методы самого zustand, чтобы добавить в каждый стор метод очистки, и вызывать это в afterEach — а что если мне в тесте нужен не initialState, а какой-то уже наполненный. Опять всё руками? ЛИБО, внимание, использовать Context API, чтобы предоставить компонентам конкретный инстанс стора. В чём разница с Redux Provider?
Миф 4: Zustand лучше перфоманс!
И показывают бенчмарки на батчевую запись в стор, где в redux используется immer, а в zustand его не добавляют, и пишут тот самый бойлерплейт из мифа №2. Мы точно сравниваем полноценные решения на реальном юз-кейсе? Или подгоняем задачу под ответ?
Я повидал разные проекты. Вопрос производительности библиотек встаёт на масштабах главной страницы Яндекса, где сам код приложения уже оптимизирован донельзя. Проекты поменьше, даже если там сложные графики с 5-летними данными с дневной гранулярностью (зачем), или формы с 200 селектами (зачем), тормозят не из-за стейт-менеджера, а из-за того, как написано само приложение.
Миф 4.1: В Zustand селекторы более гранулярные, именно это влияет на перфоманс!
В zustand можно так:
useMyStore(state => state.very.deep.object.prop)Но в redux можно точно также:
useSelector(state => state.very.deep.object.prop)В чём разница? Получили ли мы что-то новое в Zustand, или авторы просто строят очередной Redux?
❤ 8 🔥 7 🤔 4 · всего 22
Перейти к публикации →
История названий канала
14.08.2026
название
isqualog
→
isqualog • front-end • productivity
Дата — момент, когда изменение заметил наш обход.
Rozetked
ВИЛСАКОМ РЕД / WYLSACOM RED
Библиотека программиста
[netstalkers]
Типичный программист
СТАС БОМБИТ