Архив недели @kamyshev_code
Понедельник
Привет!
Я Игорь @kamyshev_code, работаю в команде веб-платформы @aviasales, мы делаем жизнь фронтендеров в компании чуть менее болезненной 💁♂️
Я буду рассказывать в основном про инфраструктурные штуки, но если интересно будет что-то другое — пишите.
План примерно такой: в понедельник говорим о мониторинге и метриках, во вторник про микрофронтенды, в среду про конфиги сборщиков (кек), в четверг я покажу несколько веселых возможностей JS, в пятницу расскажу больше про культуру разработки в Aviasales.
А темы на выходные пусть останутся сюрпризом 🤓
Тред (Игорь Камышев)
Давайте начнем с мониторинга фронтенда, мы делаем это с необычной стороны
Когда мы начинали отслеживать метрики, мы не сильно понимали, какие инсайты хотим из них получить
Поэтому решили сначала спроектировать систему сбора максимально широкого спектра метрик, а потом, когда придумаем что делать с конкретной цифрой, будем учиться собирать именно ее
Система сбора метрик получилась простая как железная дорога — Node.js-приложение, которое по HTTP готово отдавать какие-то метрики. К нему ходит Prometheus, забирает данные, кладет себе, а потом мы рисуем на основе этих данных графики в Grafana.
Написали этот сервис (дальше я буду называть его экспортером) и начали придумывать, какие метрики нам будут полезны
Тред (Игорь Камышев)
Мы хотели следить за общим качеством сайта. Первое, что пришло в голову — отслеживать фон ошибок. Сколько пользователей столкнулись с ними? Как релиз повлиял на это?
У нас уже был Rollbar, куда писались все ошибки. Добавили в экспортере запрос к API, чтобы получить число ошибок и стали отдавать это в Prometheus.
А потом поняли, что получившийся график очень сильно колеблется. Во-первых, ночью меньше людей пользуются нашим сайтом, а во-вторых — коронокризис, люди прибегают волнами.
Короче, этот график показывал по большей части посещаемость сайта.
Решили нормировать его на число посещений. У нас уже используется snowplow, как транспорт аналитических событий. Среди них, конечно, было событие просмотра страницы. То что нужно.
Добавили чтение кафка-стрима, парсинг сообщений (отдельный квест распарсить формат snowplow), учет числа посещений. И потом средствами Grafana поделили одно на другое.
Получилось как-то так
Потом еще много допиливали этот график, но подробности, кмк, уже не так интересны.
Тред (Игорь Камышев)
Кроме качества, очень хотелось смотреть еще и на производительность. Перформанс — сложно оцениваемая шутка. Оценка в лайтхаусе не всегда показывает что-то в реальном мире. Поэтому, мы решили на первом этапе брать какие-то другие цифры.
Взяли из web.dev/vitals/ — Largest Contentful Paint и Cumulative Layout Shift. Вообще, основных метрик три в этом скоре, еще First Input Delay. Но его нельзя измерить в лаборатории, а мы пока не хотим собирать эти данные с пользователей.
Тут уже тысячу раз рассказывали, что значат эти метрики. Если пропустили, почитайте на сайте web.dev/vitals/
К счастью, и LCP и CLS можно собирать через npm-пакет lighthouse. Правда ему требуется запущенный Хром. Пришлось в контейнере с приложением запускать еще и браузер через chrome-launcher
И, кстати, именно с ним мы хапанули гавна — есть какой-то плавающий баг, который приводит к появлению зомби-процессов. Они копились и через некоторое время мы теряли целую ноду в кластере.
Девопсы очень ругались, а мы очень чинили. К сожалению, до конца пофиксить так и не получилось, но сейчас это происходит не часто.
Получилось в итоге как-то
Сейчас экспортер собирает еще Speed Index, Total Blocking Time, Time to Interactive, First Contentful Paint и Performance Score. Их добавили уже другие команды под свои нужды.
Тред (Игорь Камышев)
Третья категория метрик, которые хотелось собирать — размеры ресурсов. Мы не хотели брать эту информацию из кода, потому что:
Не весь код, котрый грузится на сайте наш — есть рекламные сетки, трекеры, внешний шрифты и еще чорт знает что
Хочется знать сколько именно трафик прилетит в браузер — уже после всех сжатий и оптимизаций
И мы решили задачу прямо в лоб — запускаем браузер через puppeteer и записываем размеры всех скачанных ресурсов по категориям и источнику (чтобы знать кто из рекламный сетей грузит слишком много). Данные оттдаем туда же в прометеус.
Результат выглядит примерно так
Тред (Игорь Камышев)
Сейчас к разработке экспортера подключились продуктовые команды — они добавили сбор более подробных таймингов страницы (вообще все, что дает Лайтхаус), а недавно стали мерять время за которое завершается поиск билетов в вебе.
Расскажите, как вы мониторите свои фронтенды (и мониторите ли вообще)?
Кроме фронтендов, наша команда заведует рядом бекенд-сервисов на Node.js. К ним, конечно, тоже нужен мониторинг. Нам не пришлось писать отдельный экспортер — прометеус может приходить прямо к сервису и брать его метрики. Тут особенных инсайтов нет.
Мы собираем число запросов в секунду на входящем nginx по статусам ответа, если не-200 ответов становится больше чем мы ожидаем, шлем алерты в Слак.
Смотрим на время ответа сервиса — медианное, 99-перцентиль и 99.99-перцентиль, шлем алерты, если видим деградацию. Плюс, замеряем там же на входящем nginx время, которое он ожидает ответа от сервиса.
Да, все наши сервисы живут в Кубернетесе, оттуда можно удобно брать потребляемую контейнерами память и CPU. Смотрим за утечками памяти и аномалиями в нагрузке.
Ну и главное, мы собираем метрики внутреннего состояния Node.js через библиотеку github.com/siimon/prom-cl…. Она отдает тысячу разных метрик, но мы пока не придумали что с ними делать, поэтому оставили две
лаг ивент-лупа (сколько таска в ивент-лупе ждет, пока ее возьмут) и число открытых хэндлов (сколько сейчас открыто коннекшенов или файлов или других ресурсов).
Если лаг ивент-лупа становится слишком большим — нужно что-то делать. Пока просто шлем алерт в Слак, в перспективе хотим автоматически докидывать новых инстансов и балансировать на них нагрузку.
Тред (Игорь Камышев)
Мониторите Node.js-приложения? На какие показатели смотрите?
@jsunderhood Подняли недавно sitespeed.io, еще есть debugbear.com. Оба про метрики производительности.
Эти инструменты мониторинга фронтенда выглядят клево. Кажется, стоит попробовать их. twitter.com/exdeniz/status…
@MaximKislov Это не те цифры, зато стабильные. Мы смотрим не на абсолютные цифры, а на их колебания. Ну и думаем, как правильно собрать данные с пользователей, не навредив.
Я что-то сразу не подумал, что нужно объяснить, почему нас не пугает, что данные собраны в лаборатории, а не с реальных пользователей. twitter.com/jsunderhood/st…
У меня на сегодня все 🤗 пишите вопросы (не обязательно про мониторинг)
А это вид с горы недалеко от офиса.
О, я забыл рассказать, что у меня есть телеграм-канал, куда я пишу чуть менее фронтендерские штуки. Подписывайтесь🤓
t.me/kamyshev_code
Вторник
Сегодня расскажу как мы делали новый сервис, который в перспективе должен контролировать почти все страницы на aviasales.ru и случайно сделали микро-фронтенды
Сейчас у нас есть Реакт-приложение, оно при сборке рендерится в строку и кладется в html
У этой схемы есть несколько проблемок — сложно контролировать, неудобно дебажить, нельзя показать разным пользователям разный контент без танцев с бубнами.
Поэтому мы решили сделать новый сервис, который будет прямо на лету генерировать html из Реакт-компонентов. И посмотрев внимательно на сайт, мы поняли, что его удобно разбить на виджеты (оно и сейчас на них разбито, просто немножко другим способом).
В итоге получилось, что каждый виджет — отдельное Реакт-приложение, которое рендерится в своей ноде и об окружающем мире ничего особенно не знает.
Но, реальный мир жесток — часто виджетам приходиться общаться друг с другом.
Тред (Игорь Камышев)
На тот момент, у нас было два кейса, когда виджетам нужно пообщаться. Мы решили сделать систему, которая будет:
а. хорошо подходить под эти два конкретных кейса
б. легко заменяется на что угодно другое, не аффектит виджеты и вообще стоит максимально в стороне
Второе требование возникло, потому что мы понимали, что эти два кейса — это не конец. А предвидеть что будет дальше не могли.
Тред (Игорь Камышев)
У нас было три прототипа, и только последний показался нормальным. Первые два выкинули даже не дописав.
Сейчас оно работает примерно так: каждый виджет получает маленький ивент-эммитер. В него можно бросать события, а можно читать.
Виджет может кидать-читать только «свои» события, то есть виджет никогда не зависит от другого виджета
А чтобы связать два виджета мы используем специальные функции (мы назвали их релейшнами), которые по сути мапят события одного виджета в события другого. Кроме мапинга они могут делать фильтрацию, тротлинг, да и вообще что угодно.
Релелейшн знает о двух виджетах и хранит всю логику их связи.
Когда закончили делать финальный прототип, поняли, что получился кустарный RxJS. Но решили пока не переписывать на него, мало ли что.
А как вы организовываете общение независимых фронтенд-приложений?
Сделал пример релейшна, чтобы было понятно что он делает. Этот уведомляет первый виджет об изменениях во втором.
Тред (Игорь Камышев)
Кроме общения непосредственно виджетов между собой, нужно было решить задачу общения старого монолитного приложения с виджетами.
Решили просто как-то просунуть ему ивент-эммитер и разрешить кидать-читать сообщения.
Сделали просто — в новом приложении с виджетами кладем ивент-эммитер в глобальную переменную, а в старом приложении достаем.
Но в такой схеме есть проблема, мы не гарантируем какой бандл загрузиться первым, старого приложения или нового.
В итоге в ивент-эммитере сделали накопление событий, а в старом приложении проверяем, если ивент-эммитера нет — ждем пару секунд и смотрим еще раз. Ну и так, пока найдем (после скольки-то попыток можно перестать и признать, что что-то пошло не так)
Не самое красивое решение — зато простое и работает ¯(ツ)/¯
Тред (Игорь Камышев)
На сегодня все.
Сорян, получился короткий день, завтра расскажу больше.
Вот вам фоточка со вчерашней горы, но в другую сторону.
Шапка сегодня не понадобилась, но это только потому, что мне некогда было ее надеть
Давайте поможем Лене найти коллег. Классная команда, крутой продукт, ремоут ферст и вот это все 🤗
aviasales.ru/about/vacancie… twitter.com/ShibaCodes/sta…
Среда
Давайте сегодня обсудим конфигурацию сборки. Я довольно долго уже пытаюсь найти способ конфигурировать бандлер без боли и, кажется, нашёл достойное решение.
Кек, эта проблема вроде звучит супер-просто. Ну конфигурация, ну напиши и ладно. Но нет!
Вообще, в простом случае конфигурация сборщика — это просто один файл, в котором описано все что нужно. Для вебпака — это webpack.config.js, например. Чувствуете подвох?
Это js файл, то есть в нем может выполняться произвольный код для создания финальной конфигурации. В типичном приложении конфиг будет зависеть от перменных окруждения и аргументов командой строки.
У вас может возникнуть закономерный вопрос — почему вообще конфигурация сборки зависит от каких то аргументов командной строки и переменных окружения?
Причин может быть несколько. Как минимум, для разработки и для продакшена обычно используется чуть-чуть разных конфиг — минимификация только для прода, сорс-маты только для разработки и так далее.
С другой стороны, сейчас довольно часто создаются фронтенд-приложения с SSR, а код который исполнится на клиенте и на сервере должен быть разным. Тут тоже потребуются разные конфигурации.
Ну и куча более экзотических вариантов специфичных для конкретного приложения.
Короче, вариативность конфигурации бандлера — это важно.
У кого какие есть боли связанные с конфигурированием инструментов?
Самый простой способ сделать конфиг изменяющимся под нужды приложения — просто прямо в файле конфигурации завязаться на переменные окружения и аргументы командной строки.
Но, кажется, это не очень управляемая история.
Вносить правки в конфиг становится просто невозможно.
Число вариантов сборки растёт быстро — дев-клиент, дев-сервер, прод-клиент, прод-сервер. Уже 4, а пока только два параметра, по которым происходят изменения.
Впервые я столкнулся с этой проблемой на одном из проектов @BreadheadStudio
У нас было 4 конфиг-файла, в которых просто было много копи-паста. И когда решили принести в проект TypeScript, сделать эту небольшую правку было сущим адом.
Тогда я подумал (не очень хорошо, как выяснилось) и решил общие части конфигурации вынести в специальный файл, а специфичных для окружениях файлах просто его расширить.
В целом, получилось неплохо, но осталось дублирование между дев-клиентским и дев-сервеным конфигами, и между прод-клиентским и прод-серверным конфигами.
А еще было дублирование между дев-серверным и про-серверным конфигами, и соответсвенно между дев-клиентским и прод-клиентским.
И тогда я решил сделать просто — все специфичное для среды разработки вынести в отдельный файл и расширять его в специфичных конфигах, еще все специфичное для клиента тоже вынести, и для сервера, и для продакшена.
Короче, получилось 5 файлов с «базовыми» конфигами и 4 файла со «специфичными» конфигами. Да, я тогда был не сильно умным.
В итоге, стало только хуже и мы вернули все обратно, копи-паст, так копи-паст.
Следующий заход оказался удачнее. Я посмотрел прекрасный доклад youtube.com/watch?v=Tg8IVb…
И очень проникся этой идеей — вся конфигурация должна быть описана в одном файле. Просто нужно описывать ее на более высоком уровне, чем это предполагают бандлеры.
То есть, если именно в этом варианте конфига нужен хот-релоадинг, это должно определяться одной строкой — withHotReloading, а не подключением плагинов, лоадеров и вот это все.
Тогда я попробовал разбить весь конфиг на атомарные части и собрать финальную версию из этих кусочков.
Получилось как-то так
Конечно, это тоже не вариант — кусочки конфига слишком маленькие. Но можно объединить подход с общими бизонами настройками и дополнять их атомарными кусочками для каждого окружения.
В итоге, я экспериментировал с разными вариантам комбинации конфигов несколько лет, и, как мне кажется, нашёл достаточно удобный подход.
Основные штуки (транспиляция TS, например) вынесена в общий базовый конфиг, он расширяется через небольшие функции, добавляющие одно новое поведение по месту использования.
Выглядит это примерно вот так в реальном проекте. Здесь withDefaults — тот самый базовый конфиг, а все остальное — функции его расширяющие.
Внутри эти функции выглядит супер-просто, они всего лишь добавляют/расширяют поля конфига. Есть правило — функция-расширитель не может удалить что-то из конфига, и не должна ничего перезаписывать.
А как вы боретесь со сложностью и дублированием в конфигурации сборки?
Тред (Игорь Камышев)
Вообще, из-за неадекватной сложности при настройке вебпака, я полюбил @parceljs. Для огромного числа проектов в нем вообще не требуется конфигурации.
Для всех своих простых пет-проектов я использую именно его. И в @SamokatRu мы использовали parcel для всех внутренних веб-приложений.
Если у вашего приложения нет специфичных требований — смело берите @parceljs, это очень классное решение.
Пару месяцев назад начал делать пет-проект на @sveltejs, они очень советуют использовать бандлер @rollupjs. И вот от него удовольствия я вообще не понял. Да, конфигурация дружелюбнее, чем у вебпака, но ее не меньше. Особенной скорости тоже не заметил.
Расскажите, чем так хорош @rollupjs?
Тред (Игорь Камышев)
Еще, сегодня хотел пошарить довольно больший список докладов, которые считаю супер-крутыми. 👇
Последний доклад, который я посмотрел. Он про написание своего рендерера для реакта (вместо react-dom). Очень познавательно, даже если не пишите на Реакте — все равно стоит посмотреть.
youtu.be/E1G2rMKq8lc
Доклад про то как работает голова. Почему опен-спейсы — это отстой, как правильно отдыхать и вот это все.
youtu.be/ytX7Dv3K7Go
Альтернативный взгляд на проектирование приложений. В докладе весь код приводится на C#, но подходы применимы к любому языку (с небольшими правками, конечно)
youtube.com/watch?v=qJPwSv…
Контракты — способ убедиться, что программа получает корректные данные на границах (общение по сети, взаимодействие с пользователем). Доклад про реальные применения этого подхода.
youtu.be/K91G6na4ga8
Обычно все разговоры про ФП заканчиваются на маленьких изолированных примерах кода. Доклад про построение функциональной архитектуры всего приложения.
youtu.be/9s_4wpzENhg
Крутейший доклад про @hegel_js
youtube.com/watch?v=GIHrPm…
Всех нас занимают вопросы: «Как стать лучшим инженером?», «Как расти профессионально?». На них в целом, похоже нет ответов. Зато можно попробовать изменить отдельные аспекты своей работы.
youtube.com/watch?v=MzTng7…
Я уверен, что мы должны знать как работают инструменты, которыми пользуемся. Например, веб-разработчики должны понимать устройство сети, браузеров, платформы.
В JavaScript очень интересно устроен сборщик мусора, вот доклад
youtu.be/tDbRVZqwxn4
При создании приложения очень важно сохранить гибкость. То есть с течением времени сложность внесения изменений не должна увеличиваться. Это достигается, в первую очередь, низкой связанность.
Доклад об этом (там про PHP, но это неважно)
youtu.be/yRo-9qvF6EI
Простое введение в wasm
youtu.be/8MOZ44j_zFw
youtu.be/fwWA6Bugg_c
youtube.com/watch?v=wRxO5k…
Пара докладов про акторы. Тема специфическая, но, кмк, очень интересная.
Отойду на собес, вернусь и продолжим 😇
Не вышло, сори, затянулся собес, завтра закончу тред 🤗
@jsunderhood У нас похожий подход, только мы в конце пишем чистый конфиг без мёржев. И.е. есть ф-и типа configureScriptsLoader, confugureStylesLoader, и из них ты собираешь маленький нужный тебе конфиг.
Там в треде очень классный подход к конфигурированию сборок. twitter.com/hgenru/status/…
Четверг
Про кастомное решение для инструментирования кода и упрощения работы с компонентными фреймворками в браузере.
youtube.com/watch?v=aMP6j6…
Для людей, которые только пришли в индустрию большая проблема расти в ней. Это проблема, у нее нет решения, которое бы подходило всем. Но вот доклад про один из вариантов.
vmire.life/video/zn_3-Zpd…
DDD ван лав, вот простое введение
youtu.be/7HXIrEsmlzM
Вот и все. Кстати, обо всех этих докладах я рассказывал в канале t.me/kamyshev_code сразу как посмотрел их, подписывайтесь.
Тред (Игорь Камышев)
Четверг — это последний «серьезный» рабочий день. То есть, почти не рабочий. Поэтому, сегодня я хочу показать вам странные и неожиданные примеры использования JS.
Вообще, на мой взгляд, большая часть из них волне пригодна к реальному использованию. Но я не уверен.
В JS есть классная штука — Iteration protocols (developer.mozilla.org/en-US/docs/Web…), она позволяет создавать свои объекты, которые будут пригодны для итерирования (обход в цикле, создание массива, и все такое)
В обычной жизни я не очень часто создаю такие объекты — как то не приходится. Но, это может быть удобно.
Например, функция range из lodash (та которая создает массив с числами) имеет довольно простой интерфейс (3 аргумента), но я все равно умудряюсь забыть какой аргумент что значит.
Эту функцию можно переписать и использовать таким вот образом.
Я согласен, разница почти никакой =) Но я же предупредил, что сегодня будут просто размышления о необычном JS-е!
Я не буду сразу рассказывать, как такую функцию написать, чтобы у вас было время развлечься. Присылайте свои решения!
Окей, решение @ottey_xela верное )
А вот мое решение. Наверное, оно не самое элегантное, но какое есть.
Вообще, мне очень нравятся итераторы и генераторы! Однажды у меня была задача получить из API с пагинацией все элементы, но за раз запрашивать не больше скольки-то.
Мне показалось забавным, что снаружи это можно представить просто как асинхронный интератор — developer.mozilla.org/en-US/docs/Web…
Очень интересно, что вызывающий код даже не знает в какой момент будет запрошена новая пачка данных, для него каждый элемент приходит одинаково — просто из итератора.
Реализовать такую функцию можно через асинхронные генераторы. Код довольно простой
Оказывается, что эту функцию можно использовать не только для получения всех элементов, но и для более полезной штуки — бесконечной ленты. Например так (осторожно, псевдокод)
Любопытно, что обработчик скролла не думает, какими пачками и когда будут загружены посты. Он просто просит следующий пост и получает его. Если этот пост был загружен раньше — он получит его мгновенно, иначе — когда пост загрузится.
How to listen to Mouse Events in 2020: codesandbox.io/s/ecstatic-cla… pic.twitter.com/94QZnr6prm
А еще с асинхронными интераторами можно странно (но весело) подписываться на события twitter.com/johnlindquist/…
Другая забаваная особенность JS — это внутреннее состояние регулярок. После вызова метода test регулярка запоминает индекс последнего надйенного элемента и в следующий раз начинает поиск с него.
Какие интересные штуки в JS знаете? 🤣
Тред (Игорь Камышев)
Бонусный тред на сегодня — книжки, которые нужно прочитать любому разработчику (или разработчице), порядок важен👇
Роберт Мартин, Clean Code: A Handbook of Agile Software Craftsmanship (Чистый код)
Эта книга о хорошем программировании. Она полна реальных примеров кода и учит отличать хороший код от плохого, писать хороший код и преобразовывать плохой код в хороший.
Джон Сонмез, Soft Skills: The Software Developer’s Life Manual (Путь программиста)
Исчерпывающая инструкция о жизни программиста: что нужно для успешной карьеры,как коллег, оставаться востребованным на рынке труда, развиваться и получать от работы подлинное удовольствие.
Владстон Феррейра Фило, Computer Science Distilled: Learn the Art of Solving Computational Problems
Сложность алгоритмов, комбинаторика, теория вероятностей, устройство баз данных, архитектура компьютеров. Это необязательно для написания программ, но очень полезно.
Роберт Мартин, The Clean Coder: A Code of Conduct for Professional Programmers (Идеальный программист)
Методы, инструменты и подходы разработки «идеального ПО». Внутри много всего: от оценки проекта и написания кода до рефакторинга и тестирования.
Чад Фаулер, Passionate Programmer (Программист-фанатик)
Сборник практических советов и рекомендаций, касающихся ситуаций, с которыми сталкиваются разработчики: отсутствие мотивации, выбор приоритетов, психология программирования, отношения с руководством и коллегами.
Роберт Мартин, Clean Architecture. A Craftsman’s Guide to Software Structure and Design (Чистая архитектура)
Прямые ответы на ключевые вопросы архитектуры и дизайна. Книга объясняет, что делать, зачем и почему именно так.
Брюс Тейт, Seven Languages in Seven Weeks: A Pragmatic Guide to Learning Programming Languages (Семь языков за семь недель)
Вместе с семью языками программирования получится исследовать и важные современные модели программирования.
Джордж Спаффорд, Кевин Бер, The Phoenix Project: A Novel about It, Devops, and Helping Your Business Win (Проект «Феникс»)
Это книга о том, почему DevOps-практики критически нужны бизнесу, насколько важна интеграция разработки и эксплуатации, в чем ценность ПО и как ее извлекать
Эрик Эванс, Domain-Driven Design: Tackling Complexity in the Heart of Software
Книга рассказывает о систематическом предметно-ориентированном подходе — как с помощью модели предметной области придать разработке сложной системы нужное направление и динамику.
Это определенно не все хорошие книги, но эти я считаю "масиридами", их нужно прочесть однозначно.
Если хочется поделиться с кем-нибудь этим списком, у меня есть специальная страничка
read.kamyshev.me
Тред (Игорь Камышев)
На сегодня все🙌
Завтра мне удаляют зуб мудрости, так что не уверен, насколько я буду способен писать штуки в твиттер, но постараюсь🤣
Фоточка моего любимого пляжа с дрона
Кстати, по моим фотографиям вы могли подумать, что тут нет ничего кроме моря. Это не так — у нас есть настоящий город, совсем маленький, но настоящий.
@jsunderhood Вместо чтения книжек я всем и всегда рекомендую писать код. После написанных и выброшенных 100К строк плохого кода — на хотя бы пяти разных языках — появится понимание, как надо. От книжек появляется только ложное чувство осведомленности.
Интересная мысль со стороны практики💁♂️ twitter.com/mudasobwa/stat…
@jsunderhood Мысль из разряда «знание есть припоминание: припомни мне теорему Ферма». Никакое педаляние не снимая сапог не научит правильно проектировать код. Максимум — подрихтовать стиль и усвоить корпоративные требования. SOLID придётся «интуитивно» открывать годами, не говоря уже об FP.
Я больше придерживаюсь все таки позиции, что читать книжки полезно. Если не делать из них культа. twitter.com/argent_smith/s…
@mudasobwa @jsunderhood Или появится понимание, что выбрасывание кода - это норма. Или не появится понимания 🤷. В любом случае есть шанс, что после 100К строк плохого кода человек продолжит писать плохой код. Или человек научится писать в два раза больше плохого кода за единицу времени - сеньором стал
Тоже возможно. Я встречал много разработчиков, которые за 10 лет написали много разного кода, но программировать так и не научились. Нет универсальных рецептов. twitter.com/SosnovMax/stat…
@jsunderhood Есть Immediately-invoked Function Expression (IIFE), но также сразу вызываться могут объекты. Иногда это повышает читабельность по сравнению с if/else, switch/case pic.twitter.com/3cumHrHyNT
Кстати, кмк, это почти всегда лучше switch/case. twitter.com/ottey_xela/sta…
@jsunderhood @meowthsli Запросто. Из того, что сходу приходит на ум, и что будет действительно полезно: — Introduction to the Theory of Computation, — Domain-Specific Languages Made Easy, — Category Theory for Programmers, — Type-Driven Development with Idris, — Erlang and OTP in Action.
В дополнение к треду про книжки чувак принёс свой список. Не могу ручаться за его адекватность правда, не читал. twitter.com/mudasobwa/stat…
О, кстати Type-Driven Development у меня в списке для чтения.
Пятница
@jsunderhood @akmt_dev @SosnovMax Ну и ты сходи нахуй, и нет, это не постирония. Я брезгую фронтендом, для него в мире существуют тупые макаки, которые дрочат верстку и скриптики до изнеможения. Текст виден? — Ну и заебца, мне больше не надо.
Я вчера показал вам книжки которые советует этот чувак. Теперь я ещё больше не уверен, что к его советам стоит прислушиваться. Но вы сами смотрите 🤣 twitter.com/mudasobwa/stat…
Ладно, кажется, я пережил стоматологические штуки. Только говорить не получается. Здорово, что можно писать в твиттер.
@jsunderhood Моё имхо, то нюанс в том что каждую книгу надо прочитать в своё время. Сначала ты сталкиваешься с проблемой, а потом пытаешься найти для нее решения читая книги и анализируя возможные варианты решения под свою проблему.
Во, еще одно взвешенное мнение про книжки, лайк. twitter.com/zmitriy/status…
Пятница — самый нерабочий день из рабочих. В нашей команде в пятницу принято делать особенные — пятничные — задачки.
Пятничная задачка — это что-то веселое, экспериментальное, полезное для продукта и приятное для разработчика. Поэтому я подготовил две темы, которые кмк и веселые и полезные.
И я хочу, чтобы вы выбрали тему на день 🤓 Я могу рассказать про свои факапы (для которых уже истёк срок НДА), или рассказать какие интересные технологии связанные с фронтенд-разработкой появляются прямо сейчас.
🤔
67.5%
факапы🤔
32.5%
интересные новые технолог@jsunderhood Я всем рекомендую "Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems". Если вам интересно, как на ненадежных компонентах строить надёжные масштабируемые системы, то это must read.
Кстати, прямо сейчас читаю эту книжку, в t.me/kamyshev_code пишу конспект 😉 twitter.com/MeFCorvi/statu…
Мне кажется, что надувать щеки и показывать какой ты классный, никогда не факапишь и вообще молодец — глупо. Все ошибаются, кто-то больше, кто-то меньше.
Ошибаться нормально, главное учиться на ошибках и не косячить два раза одинаково.
Самый старый и самый скучный. Я когда-то делал сайты на PHP за небольшие деньги, и на одном из них была самописная админка. В ней была очень тупая уязвимость — из куки читалось значение и оно отправлялось в SQL запрос без экранирования.
Соответсвенно, достаточно было угадать имя таблицы с пользователям и можно было вписать туда нового пользователя с админскими правами отправив в куке SQL-запрос.
Кстати, никто не заметил, сайт проработал пару лет, контора закрылась, все хорошо.
Любопытно, что потом, через 5 лет я встретил сайт, который делала серьёзная студия с такой же проблемой. Это вообще популярная уязвимость.
Однажды я делал небольшой бекенд на Node.js, в нем был запрос на получение всех записей пользователя. Через пару недель работы в продакшене нагрузка на сервера начала заметно расти, почему — не понятно.
Я очень долго искал проблему, пока не понял, что криво написал запрос через TypeORM, я получал все записи (не только для конкретного пользователя). А потом, уже в другом месте приложения лишние случайно отфильтровывались.
Забавно, что два бага в сумме дали корректно работающую программу и проблему мы заметили только из-за нагрузки на процессор (фильтровались миллионы записей на каждый запрос).
Как-то раз я делал сайт, и из-за криворукости переодически приходилось лазить руками в базу, чтобы исправить какие-то проблемки.
База была в контейнере на сервере и в нормальной жизни вообще не торчала наружу — доступ до неё был только внутри локальной сети на сервере.
Но чтобы залезть туда со своего компьютера, я ее высовывал наружу. И в однин прекрасный момент забыл спрятать обратно 🤪
А потом обнаружилось, что на сайте сломалось все — на клиенте любой запрос заканчивался ошибкой 500.
В логах были странные сообщения — схема базы не соответствовала представляем приложения о схеме. Я зашёл в базу, а там одна таблица README, в которой одна строчка — сообщение, что база похищена и требования выкупа в биткоинах.
Это, пожалуй, был самый страшный факап в моей жизни.
Но, все закончилось плюс-минус хорошо, базу восстановили из бекапа и кажется, заказчик не имел претензий. И, даже, похоже что похититель никуда не выложил украденные данные.
После следующего факапа я приучил себя читать исходный код используемой библиотеки 😝
Делал приложение, которое должно было поддерживать не самые свежие браузеры (типо ie11). И после очередного релиза оно начало валиться прямо сразу, до белого экрана.
В консоли сообщение, что const — это не понятно. Логично, да.
Оказалось, что одна из библиотек поставлялась в современном js, и мы не бабелили ее, конечно. Исправили быстро, но было неприятно.
С тех пор я топлю за то, чтобы библиотеки ВСЕ поставлялись в виде максимально современного js, а я бы уже сам решил до какой версии их бабелить 🤗
И тогда же привык смотреть что вообще на зависимость которую я ставлю, читать ее исходные тексты и смотреть, что по факту прилетает в бандл. Потом это помогло мне избежать гигантского числа проблем.
На этом все, простите, но челюсть болит так, что даже сериал смотреть тяжело, не то что писать что-то осмысленно.
Тред (Игорь Камышев)
Суббота
Вчера посмотрел доклад про рефлексию в TypeScript и снова подумал, что декораторы вроде и не стоит использовать, а вроде они и супер-удобные ಠ_ಠ
Что думаете о декораторах в JS/TS? twitter.com/kamyshev_code/…
Меня все еще мучает зуб (вернее, его отсутствие), но давайте я кратенько расскажу про новые странные веяния фронтендов.
Все вокруг шутят, что в мире фронтенда новый фреймворк появляется каждую неделю. Штош, было бы здорово, но основные технологии стагнируют уже много лет.
Вебпак 5 не принёс ничего кардинально нового, Реакт 17 вообще вышел из фич. Мейнстримовый фронтенд стагнирует и не развивается. Поэтому давайте поговорим о странных, экспериментальных или просто непривычных технологиях.
Я, если честно, не верю, что одна из них станет популярной в обозримом будущем, но, мне кажется, что на их основе вырастет что-то очень клевое лет через 5.
Помните статью про то что фронтенды собираются неадекватно долго? habr.com/ru/company/vds…
Ну правда же очень медленно. Один из моих рабочих проектов на топовом MacBook Pro 13 собирается 160 секунд. А на моем прошлом компьютере собирался почти 10 минут.
И с этим ничего не поделать — медленно, долго. Вероятно, эту проблему нельзя решить с помощью JS-тулинга.
Сейчас набирает популярность esbuild (github.com/evanw/esbuild) — это бандлер js написанный на go. И он прямо блейзинг фаст. Говорят в 10-100 раз быстрее чем классические сборщики.
Я пока не пробовал его в бою, только на небольших демо-проектах, но выглядит он впечатляюще.
Кто-нибудь использует esbuild для продакшна?
Другое интересное решение, связанное со сборкой проекта swc (github.com/swc-project/swc) — это компилятор js/ts, написанный на Rust. Он быстрее бабеля в 20 раз.
Конечно, в нем пока сильно меньше возможностей (swc.rs/docs/compariso…), но для многих проектов они и ненужны.
Следующая интересная штука, это замена nvm, снова написанная на Rust — fnm (github.com/Schniz/fnm). В нем я вижу чуть меньше смысла, чем в предыдущих двух, версию ноды мы все-таки меняем не так часто, как собираем проект.
RSLint (github.com/RDambrosio016/…) — это как ESLint, только быстро. Меня очень утомляет долгий линтинг большого проекта на CI, а тут все будет быстро.
Пока этот проект совсем сырой (намного сырее первых трёх), но пощупать уже можно.
Это касалось тулинга вокруг разработки. Теперь давайте обсудим библиотеки, которые помогают строить приложения проще, надежнее, быстрее.
Пару недель назад попробовал @sveltejs и он оказался интересным. twitter.com/kamyshev_code/…
Меня последнее время очень прет @sveltejs, вот тут делился первыми впечатлениями —twitter.com/kamyshev_code/… Если вы не пробовали его, то попробуйте. Он правда прикольный.
Другая интересная штука — @stenciljs
Это по сути способ писать веб-компоненты, а потом использовать их в приложениях на привычных js-фреймворках. Там вообще много интересного, но я пока не добрался до вдумчивого изучения.
Стейт-менеджеры нового поколения — мой краш: @effectorjs, recoiljs.org, reatom.js.org. Я совсем не специалист в стм, чтобы рассказывать о них подробно, послушайте лучше умных людей тут youtu.be/cUSyJk6k2rk
Но после любого пет-проекта на любом из них, возвращаться к написанию логики внутри редакса — жуткая боль.
Тред (Игорь Камышев)
Вот ещё советуют solid (github.com/ryansolid/solid) twitter.com/kmmbvnr/status…
@jsunderhood Мне нравится история про тулинг на быстрых языках. Но развитие и поддержка для таких инструментов кажется проблемой. Контрибуторы этих штук — подмножество фронтендеров, умеющих низкоуровневость и многопоточность + какие-то люди из этого языка, которых почему-то интересует тулинг
Вот те же мысли абсолютно twitter.com/N_Lopin/status…
@jsunderhood Если забыть о проблемах декораторов и жестко ограничивать их применение, то они конечно дают возможность писать удобно и красиво. Тот же код на несте читабельней и лаконичней именно благодаря декораторам. Но слишком легко шагнуть в бездну, если не контролировать их применение.
Очень хорошая мысль twitter.com/amel_true/stat…
Воскресенье
Так уж получилось, что я живу в Таиланде. И тут есть пара особенностей, относящихся к работе.
Все время, что я тут живу, меня поражают розетки. Везде в Таиланде делают розетки, которые понимают ЛЮБЫЕ вилки.
Все зарядки из России работают, тостер с британской вилкой — работает, местная техника с китайскими вилками — работает.
Ну чудо же! Мечтаю, чтобы во всем мире применили эту тактику.
Зимой 2019 я жил месяц на Кипре. Там британские вилки-розетки и это было довольно неудобно — приходилось использовать громоздкие переходники. В доме их было мало, а покупать на месяц и выкидывать мне показалось глупо.
Примерно половину года тут низкий сезон — не очень жарко и очень дождливо. В целом кайф, но есть нюанс.
Интернет во время сильного дождя либо становится жутко медленным, либо полностью ломается.
Во время сильного ветра иногда выключается даже свет. После таких дней, в офисе обычно половина зарядок от ноутбуков сгорает, кек.
По очевидными причинам в магазинах продаются компьютеры с тайскими буквами на клавиатуре. Чтобы купить компьютер только с английскими буквами — нужно специально заказывать его, я ждал почти месяц.
Ну, понятно, с русскими буквами клавиатуру тут достать нельзя. Я сначала очень волновался что будет супер-неудобно, но нет — быстро привык.
Интересно, что даже не привычная по форм-фактору клавиатура айпада без русских букв не вызывает проблем.
Не так сильно относится к работе, но — тут очень хорошая медицина.
Правда довольно дорогая, но правильная страховка покрывает все кейсы. В начале лета надорвал связку в лодыжке. Все лечение получилось около тысячи долларов, из своего кармана заплатил 10 баксов за дополнительный эластичный бинт (первый я испачкал чем-то).
Когда приехал с травмой в больничку, почувствовал себя в фильме — медбрат помог выйти из машины, усадил на кресло-каталку. Меня сразу опросили по небольшой анкете, завели карту и покатили к доктору. Потом рентген, снова доктор, наложили гипс — все заняло около 40 минут.
Весь стафф был супер-вежливым, все хорошо говорили по английски. По больнице меня катали на кресле.
После наложения гипса отвезли в комнату восстановления — всякие беговые дорожки, тренажеры, небольшая лестница построена. Там люди восстанавливаются после травм.
Мне показали два вида костылей, я выбрал одни и меня научили ими пользоваться — нарядили в специальную обвязку, чтобы если я начну падать, медсестра могла меня удержать и научили ходить по ровной поверхности, по лестнице, садиться и вставать.
А вот с оплатой была беда — сумма за тот день была больше 500 баксов, такие траты страховая не одобряет без согласования. Я прождал их ответа в больничке почти 4 часа, оплатил из своего кармана и уехал домой. Деньги вернулись через неделю.
В пятницу ездил удалять зуб мудрости. Это не входит в страховку, я должен был оплатить все сам, поэтому поехал не в ту лакшери-клинику, где обычно мы лечимся, а в небольшую частную стоматологию на районе.
Пару недель назад у меня очередной раз воспалилась восьмерка, я приехал в эту клинику, они сделали рентген-фото, посмотрели и посоветовали зуб удалить. А пока дали обезболивающее и антибиотики (чтобы убить инфекцию, которая делала зубу больно). Прием стоил 500 бат (15 баксов).
В четверг я закончил пить антибиотики, и уже в пятницу приехал удалять зуб. Операцию заняла около часа, больно не было вообще (кайф!), все ласковые и приветливые. Стоило 4000 бат (140 баксов).
На следующей неделе нужно будет съездть к ним, снять швы. Пока — это был лучший контакт со стоматологами в моей жизни.
В целом, жить на Пхукете прикольно, но немного раздражает деревенскость. Хочется в город.
Приятный бонус — билеты до Бангкока по 60 баксов. Доехать до аэропорта и потом от аэропорта до дома стоит примерно столько же, кек.
Пишите вопросики, расскажу подробнее про отдельные аспекты жизни на райском острове.
О, еще можете подписаться на телеграм-канал специальный
t.me/thai_ecaspates
Тред (Игорь Камышев)
На этом все 🥳 спасибо вам, было весело.
До вечера ещё готов отвечать на вопросы, ну и если что, пишите в личный аккаунт.
С вами был @kamyshev_code, подписывайтесь, ставьте лайки.