Size: a a a

Сова пишет…

2020 October 13
Сова пишет…
Продолжается тред effector devtools! Налетай!

https://twitter.com/_sergeysova/status/1316045120702218242?s=20
источник
Сова пишет…
Все каналы пишут про новый айфон. А если я не буду тут ничего писать, все уйдут?
источник
2020 October 28
Сова пишет…
О подкаст таки залетел в другие приложения:
- PocketCasts
- Deezer
- RadioPublic
- Breaker
- Gaana
- Yourcast
источник
2020 October 29
Сова пишет…
Из-за ковида люди массово (и в основном бессмысленно) принимают антибиотики. Это очень опасно и может навредить всему человечеству

Пандемия коронавируса спровоцировала массовый прием антибиотиков без явных показаний — для профилактики инфекции, «на всякий случай» и «для очистки совести». Однако это опасно и для заболевших ковидом, и для человечества в целом: такое применение антибиотиков только усиливает устойчивость бактерий к антимикробным лекарствам, и в критический момент они могут просто не сработать.

https://meduza.io/feature/2020/10/26/iz-za-kovida-lyudi-massovo-i-v-osnovnom-bessmyslenno-prinimayut-antibiotiki-eto-ochen-opasno-i-mozhet-navredit-vsemu-chelovechestvu
источник
2020 November 05
Сова пишет…
Я уже давно хотел себе сокращалку ссылок.
Но раньше я писал свою на nodejs, клал ссылку в бд, пытался упростить просто генерацией nginx конфига.

А в этот раз решил ограничиться самым простейшим решением настраиваемым за 10 минут — netlify. Оказалось, что это работает очень быстро и настраивается очень просто: создаешь сайт в netlify, подключаешь репо, кладешь в репо netlify.toml со списком редиректов и всё работает через минуту. Вот такое я люблю!

go.sova.dev/podcast/yandex
go.sova.dev/podcast/stitcher
go.sova.dev/twitter/effector-devtools
источник
2020 November 10
Сова пишет…
effector patronum ✨ близится к релизу v1.0!

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

https://github.com/effector/patronum/releases
Milestone 1.0 96% complete

Может быть есть то, чего не хватает в документации?
источник
2020 November 12
Сова пишет…
Всем привет, ищу разработчиков себе в команду на отдельный проект!

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

Задачи которые мы решали на этом проекте:
- проектировали TypeScript SDK для реалтайм чатов с кучей конверсейшенов и паблик каналов
- реализовали интерфейс визуального скриптинга в стиле Unreal Blueprint
- разрабатываем сложные интерфейсы планирования рассылок

Стек: TypeScript, Effector, React, WebAPI, D3, styled-components, antdesign, Docker

Какие скиллы нужны:
- Уметь решать на React задачи любой сложности
- Знать об Effector и иметь желание на нём писать
- Понимать базовые принципы дизайна (в этом проекте нет дизайнера)
- Знать паттерны проектирования
- Уметь писать документацию на английском
- Соблюдать чистоту в проекте: conventional commits, кросс-кодревью, линтеры
- Тестировать компоненты и бизнес-логику (unit, integration)

Что у нас есть:
- Полностью белая ЗП, ДМС
- Начало дня с 9 до 12, macbook, офис с плюшками
- Гибкость к технологиям и аргументам, внутренние митапы, профессиональный рост, менторство
- Сейчас удаленная работа в Питере, но после пандемии переберемся частично в офис(возможно)
- Стремимся сделать хорошо, за короткие сроки, планируем рефакторинги и проводим исследования

Как нас посетить:
- Написать мне и получить ссылку на полный текст вакансии
- Сразу же в первом сообщении написать, что идешь на эту вакансию
- Вилку можно узнать в личке, такова политика компании
- Приложить ссылки на свой github, личные проекты, opensource
- Отлично, если будет пару предложений почему именно к нам

У нас ограничены сроки, ищем двух разработчиков до конца года. Выбирать будем по взаимной симпатии. Собеседование в два этапа, чтобы понять случилась любовь или нет. Чем раньше найдем, тем лучше. Пожалуйста, репостните в любимые чаты и своим знакомым.
источник
2020 November 27
Сова пишет…
Именование коммитов

До этого момента во всех личных и рабочих проектах, я продвигал использование структурированного текста коммитов, а именно conventional commits через commitizen. Это подход в котором текст коммита (сообщение и тело) пишется в особом формате, легко поддающемся программному анализу. Что нам предлагает эта спецификация? Разделить текст коммита на несколько секций: тип изменений, скоуп, сообщение и расширенное тело.

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

Например, добавление параметра в функцию, это новая функциональность, тип пусть будет feature, исправляются или дописываются типы — tests, документация — docs, система сборки — build и так далее. Список жестко задан.
Область изменений(scope) также должна быть либо одна, либо сразу всё приложение: исправил что-то в локальной библиотеке функций — тип fix, scope my-lib, добавил новую страницу — тип feat, scope pages.
Даже сообщение об изменениях имеет заданную спецификацию и должно быть описано в определенном падеже.

Что это дает на практике: все коммиты пишутся в общем формате, такое проще читать, так как вся необходимая информация на виду, за дополнительной можно проследовать в тело коммита, текст можно валидировать через линтеры, стимулируя команду писать в едином формате, текст можно генерировать через cli, ответив на несколько типичных вопросов о характере изменений, а из истории коммитов можно генерировать списки изменений для релизов.
источник
Сова пишет…
Остановимся на последнем примере — чейнджлоги изменений. Если взять в пример open source фреймворк или библиотеку, насколько действительно пользователю нужны полные списки изменений, “Вася изменил имя внутренней функции в ядре фреймворка, но при этом совместимость для пользователей не сломалась”. Гораздо правильнее и практичнее ситуация, когда авторы самостоятельно выбирают какие изменения нужно подсветить пользователю, пишут для них наглядные примеры подчеркивающие отличия, и такое сгенерировать уже невозможно.

В больших проектах все изменения, большие и маленькие добавляются через PullRequest, название которого выбирается осмысленно, да и причина наглядно объясняется в теле PR. Можно же использовать список PR для генерации release notes? Да, и в своих opensource проектах я перешел на такой подход, это даже отбивает желание пушить напрямую в мастер, ведь тогда изменения не будут видны в release notes, придется писать вручную, а я люблю автоматизацию.
Но с другой стороны это слегка вербозно, особенно если ведешь проект самостоятельно.

С энтерпрайз разработкой всё ещё бесполезнее, ведь там release notes либо вообще не пишутся, либо их пишет продуктовая команда на основе списка story из JIRA, а разработчикам генерировать release notes для себя не особо надо. Кроме случая, когда пишешь внутреннюю библиотеку для нескольких команд, но и там решается через PullRequests.

Какой же тут может быть вывод? Я вижу основной плюс в conventional commits — это дисциплина и чистота. Когда все участники команды стараются четко описывать характер изменений, особенно если лид проекта держит историю git в чистоте. Такой подход помогает выявлять изменения и причину сразу через git blame, без томных походов в задачи JIRA и перечитывание сотен комментариев, если они вообще остались, ведь в теле коммита можно сразу описать причины такого кода “поговорил с Васей, он утверждает, что может быть дыра в безопасности, если не подставить костыль сейчас”.

Инструментарий вроде commitizen и commitlint позволят сгенерировать и провалидировать полученный коммит автоматически, сохранив при этом ясную структуру. Я бы рекомендовал выбрать тот формат, который удобен команде, conventional commits слишком длинный, я бы посмотрел на gitmoji как альтернативу.

Я не вижу практического смысла в программном анализе истории коммитов и генерации release notes из этого, ведь там не будет бизнес-ценности, а вычленять её и писать сложные эвристики ради этого кажется нерациональной тратой времени. Release notes лучше генерировать из списка PullRequest.
источник
2020 December 05
Сова пишет…
sergeysova
Немного обсуждений в @effectorjs чате натолкнули меня на мысль изменить подход к описанию логики в effector+react.

Я стараюсь разделять представление и логику. Если взять в пример страницы, рядом с файлом компонента страницы лежал файл логики на эффекторе.
pages/counter/{index.tsx, model.ts}

В файле компонента я напрямую импортировал сторы и ивенты из модели и использовал в компонентах:

import * as React from ‘react’
import { useStore } from ‘effector-react’
import { $counter, incrementClicked, pageMounted } from ‘./model’

export const CounterPage = () => {
 const counter = useStore($counter)
 React.useEffect(() => { pageMounted() }, [])

 // show counter and use events
}


И это работало весьма хорошо, тестировать просто (импортируем сторы в тест и setState(data)). Объявляем контрактом любые экспорты из model.ts и очень осторожно их изменяем.

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

Но если нужно маппить данные из стора по какому-то ключу или ещё какие операции со списками, то эта логика затаскивалась прям в компонент вместе с useStoreMap и useList. Это мне не очень нравится, ибо тестировать становится сложнее.

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

Использовать хуки, для получения данных и ивентов из модели.
Я предлагаю из модели экспортировать реакт-хуки, вместо сущностей и ивентов. Этот подход имеет смысл в первую очередь для моделей страниц. Разделяемые сущности чаще всего не нужно отдельно заворачивать в хуки, так как часто хочется создавать computed от общих сторов.

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

import { useCounter, useEvents } from ‘./model’

export const CounterPage = () => {
 const counter = useCounter()
 const { pageMounted, incrementClicked } = useEvents()

 React.useEffect(() => { pageMounted() }, [])

 // show counter and use events
}

Можно пойти дальше, и унести React.useEffect() внутрь useEvents, чтобы модель сама устанавливала нужные реакции. Но тут спорно и нужно обдумать. Возможно это нужно выделить в отдельный хук.

А теперь зачем это.
1. Семантика. Теперь, контракт выглядит как независимая сущность. Можем заменять STM как нам захочется, внутри хука может быть React.useReducer, или же Redux.useSelector, или же Effector.useStore. Все равно.
2. Сокрытие сложности. Всякие useStoreMap могут быть скрыты внутри хука, разработчику компонента теперь не нужно знать детали реализации модели, чтобы разработать компонент. Ведь теперь, чтобы рабоать независимо достаточно спроектировать контракт на хуках, описать типы и вернуть dummy-данные.
3. Тестирование. Тесты упрощаются, до мока конкретных хуков, а не сторов. Ведь теперь разработчик компонента, может спокойно написать тесты только на вью, не трогая при этом сторы модели. Логика моделей при этом может быть разработана действительно независимо.

Я пока не могу понять, имеет ли смысл разделять контракт и модель? pages/counter/{contract.ts, model.ts, index.tsx}
- contract — импорты из model завернутые в react-хуки
- model — чистая логика, без примесей хуков
- index — компонент, использующий контракт, без примесей STM

Как думаете?
Год назад я описал свои размышления по разделению логики и представления при описании страниц на Effector + React.

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

Раньше, я импортировал сторы и ивенты из модели прям в файл с компонентом. Такой подход позволяет легко тестировать саму модель — замокал api и внешние сервисы и погнали.

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

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

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

Я не хочу разделять свою модель на state, init и index, потому то не люблю, когда логика размазывается по нескольким файлам. Да, мы все помним .h файлы в C++, только вот новые языки не разделяют определение и реализацию, потому что определение это зачастую важная часть логики. В моем случае так же: combine, attach, .map и прочие фабрики сущностей должны быть размещены в state и index по дефолтной рекомендации эффектора, в то время как в них лежит логика.
Например:
$formPending = combine(fx.pending, email.map(fn), ...)

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

А работает это очень просто:
- в модели как и ранее описывается вся логика и все ивенты необходимые для работы. Только полностью удаляются любые упоминания view-слоя, в моём случае React.
- в файле компонента описывается jsx и привязки к сторам и ивентам эффектора, но никаких импортов модели не производится. Все необходимые юниты создаются сразу же в файле компонента и экспортируются. Теперь файл компонента я называю page.tsx
- init-файл я называю index.ts и в нем размещаю связи между сторами/событиями компонента и модели. Фактически производится форвард из сторов модели в сторы страницы и из событий страницы в события модели.

События страницы всегда пересылаются в модель, но не наоборот. Модель не может влиять на страницу через события, react-компонент просто не подписывается на события, ему это не нужно.
А вот сторы всегда пересылаются в обратном направлении — из модели в страницу. Реакт компонент становится функцией от состояния, он умеет только отправлять события и рендериться на основе данных.

Тесты писать крайне просто: импортируем компонент, форкаем root-домен, проставляем нужные значения в сторы компонента и проверяем результат. Аналогично поступаем с событиями, просто проверяем, что они вызываются с правильными ивентами и значениями.
источник
Сова пишет…
sergeysova
Год назад я описал свои размышления по разделению логики и представления при описании страниц на Effector + React.

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

Раньше, я импортировал сторы и ивенты из модели прям в файл с компонентом. Такой подход позволяет легко тестировать саму модель — замокал api и внешние сервисы и погнали.

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

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

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

Я не хочу разделять свою модель на state, init и index, потому то не люблю, когда логика размазывается по нескольким файлам. Да, мы все помним .h файлы в C++, только вот новые языки не разделяют определение и реализацию, потому что определение это зачастую важная часть логики. В моем случае так же: combine, attach, .map и прочие фабрики сущностей должны быть размещены в state и index по дефолтной рекомендации эффектора, в то время как в них лежит логика.
Например:
$formPending = combine(fx.pending, email.map(fn), ...)

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

А работает это очень просто:
- в модели как и ранее описывается вся логика и все ивенты необходимые для работы. Только полностью удаляются любые упоминания view-слоя, в моём случае React.
- в файле компонента описывается jsx и привязки к сторам и ивентам эффектора, но никаких импортов модели не производится. Все необходимые юниты создаются сразу же в файле компонента и экспортируются. Теперь файл компонента я называю page.tsx
- init-файл я называю index.ts и в нем размещаю связи между сторами/событиями компонента и модели. Фактически производится форвард из сторов модели в сторы страницы и из событий страницы в события модели.

События страницы всегда пересылаются в модель, но не наоборот. Модель не может влиять на страницу через события, react-компонент просто не подписывается на события, ему это не нужно.
А вот сторы всегда пересылаются в обратном направлении — из модели в страницу. Реакт компонент становится функцией от состояния, он умеет только отправлять события и рендериться на основе данных.

Тесты писать крайне просто: импортируем компонент, форкаем root-домен, проставляем нужные значения в сторы компонента и проверяем результат. Аналогично поступаем с событиями, просто проверяем, что они вызываются с правильными ивентами и значениями.
Хотелось бы написать, что я на этом остановился, но нет.
Писать пачку forward в index.tsx оказалось несколько утомительно. К тому же, пришлось группировать forward по ивентам и сторам, чтобы случайно не перепутать порядок:
сторы — из модели в страницу
ивенты — из страницы в модель

Поэтому поковырявшись в Typescript я написал функцию bus(), типизировать которую оказалось задачей не из легких, решить которую мне помог @uid11, отдельное большое спасибо за это.

Фактически, функция делает forward за меня, сразу в несколько target. То есть позволяет просто и наглядно соединить пары ивентов и пары сторов.

Практиковать этот подход я начал на проекте Accesso, а pull request с изменениями можно посмотреть здесь — go.sova.dev/effector/split-page-and-model

Как писать тесты покажу позже, сразу с практическими примерами и практиками.
источник
2020 December 06
Сова пишет…
За что я не люблю экосистему React.

Сборка проекта разваливается после установки react testing library, которая никаким образом типы роутера и реакта не обновляла.

Ещё и как чинить не понятно
¯\_(ツ)_/¯
источник
2020 December 07
Сова пишет…
Я сижу на BigSur с бета теста для разработчиков. Утекло очень много всяких багов и к релизе пофиксили почти все, что я нашел.

Но вот этот, лично у меня самый частый баг новой ОС
источник
Сова пишет…
В процессе написание текста для следующих выпусков подкаста возник неожиданный вопрос.

Как лучше обращаться к слушателю?
Анонимный опрос
49%
На "ты" (представь себе такое, сколько у тебя в команде)
11%
На "Вы" (представьте себе такое, сколько у Вас в команде)
35%
На "вы", как к аудитории (не вывез придумать пример, где будут отличия от уважительного "Вы")
4%
Есть ещё вариант
Проголосовало: 228
источник
2020 December 08
Сова пишет…
НАКОНЕЦ-ТО!
источник
Сова пишет…
ГОСПОДИ!
Не прошло и трех лет
источник
2020 December 09
Сова пишет…
У меня две претензии:
- Почему гугл решил не писать "Day 1" и "Day 2" в локальной таймзоне? Че это за прикол.

- Имя докладчика? Неее, зачем вообще такое надо.
источник
2020 December 12
Сова пишет…
Субботним утром обсудили что не так с фронтендом и сообществом.

https://youtu.be/vMLLyWWd6So
источник
2020 December 13
Сова пишет…
Сейчас немного постримлю livecoding.
Буду подключать аутентификацию через accesso к cardbox.
https://youtu.be/ffRthDqp1sI
источник
2020 December 16
Сова пишет…
источник