melikhov.dev – Telegram
melikhov.dev
4.63K subscribers
110 photos
2 videos
2 files
203 links
Фронтенд, фронт-бек и около. Всё, что в голову пришло. Иногда котики.
Download Telegram
Я как-то уже писал, что полностью перешёл на разработку на удалённой linux-машине. В VSCode работает прекрасно, позволяет бесшовно жить на два ноута (офисный 16" и домашний/дорожный 14"). Но вот ещё что важно, мои ноутбуки на M1. А это, помимо всех плюсов, и минусы:

- относительно тормозной Докер (ещё и платный, в случае Docker Desktop/OrbStack)
- проблемы с нативными биндингами node.js

Второй момент проявляется так. Запускаем приложение и ловим какой-нибудь dyld[42703]: missing symbol called. Дальше два варианта: забить и переустановить все зависимости с --target_arch=x64 или найти виновника, и понять, что делать дальше: поднимать версию, выкидывать и менять на другую реализацию, форкать, поднимать транзитивные через override и т.д. Не самое приятное развлечение.

Из хорошего то, что таких случаев всё меньше и меньше, да и Rosetta 2 получилась удивительно хорошей. Но всё же тонкие клиенты — это кайф. Пока не сядешь в поезд.
👍44🔥7😁6🤔1
Пока ещё пишу итоги (ну ждёте же?). Прервался на запись просто огромного новогоднего выпуска Веб-стандартов. С видео. Как вы любите.

Как Вадим будет это всё монтировать — даже не знаю. Пошлите ему лучиков поддержки.
🔥89🎄17💩1095🦄1
Итоги 2023

Жизнь и около

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

Почти не пропускал подкаст. 35 эпизодов по 2 часа + ~1.5 часа подготовки. 122,5 часа получается. Нехило. Хорошо, что монтирует Вадим.

Примерно 140 часов провёл в дороге. Обычно работал. Перевёл домашний 14” ноутбук в режим рабочего. В дороге-то самое оно.

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

Много плавал, регулярный бассейн для спасения спины. Купил сап, штука ленивая, но приятная. В гидрашке даже в сентябре хорошо.

На сноуборде катался до середины марта и открыл сезон с первых чисел декабря. В конце прошлого сезона обновил доску (прошлой уже лет 15 минимум было. Ох ты ж). Сменил крепы Flow на классику, сначала чуть не плакал, но сейчас уже привык.

Программирование

Вернулся в ШРИ, сделал лекцию по node.js. Одной лекции явно недостаточно, весь материал не запихнуть, добивал внезапным мастер-классом, но всё равно. Надо что-то сделать тут.

По работе — много ковырял node.js, девопсил. Мало трогал UI, в основном чинил баги. Всё как люблю. Плакал от багов gRPC. Настраивал Webpack, выравнивал зависимости. Будни фронтендера.

Полностью поменял воркфлоу. Слез с Idea/WebStorm и полюбил VSCode. vim конечно никуда не делся, когда надо поковырять файлики. Вообще, уменя ощущение, что сейчас мы видим начало конца традиционных больших IDE, вместо них снова приходят текстовые редакторы, но дополненные LSP, LLM-моделями и плагинами.

Перешёл на разработку на удалённой машине (отчасти следствие перехода на arm-процессоры, работать локально на маке стало больней). Разрабатывать прямо в linux со всеми сетевыми доступами — счастье. Перестал носить с собой ноут каждый день.

Разочарование года — декораторы в TypeScript. Ждали, ждали, они вышли и что? Будем ждать нативных.

Боль года — ESM. Очень больно. Ну вы и сами знаете.
57👍16
Техника и гаджеты

Традиционно раз в три года обновил телефон. Дождался падения цен на iPhone 15 (не про) и взял. Ожидаемо ничего нового, но type-c, хорошая камера и dynamic island дают радость новизны. Type-c вообще провоцирует на эксперименты «а если я в тебя вот это воткну, то что получится?». Докупил кошелёк — подставку от Moft. Удобно! Лучший недорогой гаджет в этом году.

Андроид обновлять не стал. Pixel 5A в целом справляется с задачей поглядеть на приложения, а как основную OS для жизни я Андроид рассматривать всё ещё не могу. Хотя уже близко.

Основной клавиатурой в этом году стала NuPhy Air 75. Так как работаю в основном в офисе, то взял на красных. Сойдёт. Хотя отсутствие на ней F5-F6 без Fn — огромный недостаток.

Самая бесполезная покупка года — iPad mini. Продал. Обычный iPad Pro 11 так же пылится в шкафу. Не буду говорить, что планшеты это тупиковая ветвь развития, многим они заходят. Мне пока никак.

RØDECaster Duo. Это король. Запись подкастов уже не будет прежней.

Shure SM7B — перешёл на классику. Окончательно понял, что проблема не в микрофонах, а в моём голосе. Но всё равно приятно. Такой у меня и у Майкла Джексона (был).

В рюкзаках перешёл на роллтопы. Раньше посматривал на них с сомнением (где же мои 50 кармашков), но понял, что кроме ноутбука ношу только продукты. Зато если нужно, то влазит и куртка и вообще всё влазит. Взял для города Lefrik Roll и для поездок Pinqponq Block Medium.

Интернет

Интернет для меня схлопнулся до Телеграма, Гитхаба и инди-блогов. Спасибо каналам в Телеге, что вернули ощущение тёплой ламповости того, олдскульного веба. Хотя это конечно не веб, надо это понимать 🙂 Зато в Телеге не так стыдно не уметь писать.

Книги
Читал катастрофически мало. Ну очередной Пелевин, конечно, как без него. «Бронепароходы» Иванова не дочитаны (хотя очень хочется дочитать). Очередной занудный графоманский Стивенсон («Падение, или Додж в Аду») не дочитан. «Однажды в Голливуде» Тарантино — не дочитана. Что-то с этим надо делать.

Фильмы
Запомнил только «Всё, везде и сразу».

Ну вот вроде и всё. Прощай 2023, скучать не буду.
84👍31🍾12
Притча про монорепы

Приходит молодой программист к седому опытному гуру и жалуется: «О умнейший из фронтендеров, у меня такая тяжелая жизнь, у меня 10 проектов, все связаны зависимостями, постоянно всё разъезжается везде... кошмар...»
Седой и строгий отвечает: «Собери все проекты в монорепу»
Программист: «Какую монорепу? Зачем? Как я ее в гитхаб положу!!!???»
Опытный: «Сделай монорепу»

Программист подумал-подумал, прикинул плюсы и минусы, пошел и сделал монорепу.
Через неделю приходит к опытному, тот его спрашивает «Ну, как жизнь»? Программист заламывает руки, кричит : «Еще хуже стало, эта монорепа чёртова, тулинг ужасный, все PR и ишью вперемешку, все тесты ломаются на каждый чих, всё тормозит... ужас!»
Умный почесал бороду и говорит: «Удали монорепу»
Программист страшно удивляется: «Что??? Зачем же я ее делал???"»
Опытный продолжает напирать: «Удали монорепу»
Программист подумал, подумал, пошел и удалил монорепу.

Через неделю возвращается программист к высокогрейдовому гуру и чуть не плачет от счастья: «Боже, друг, как же мне хорошо...»
😁156🥴12👍4🍓32🤓21🤡1
А я напомню, что таких долгоживущих веток делать конечно же не надо. Хорошая ветка живёт день-два и уезжает в main (ну или в версию, если у вас одновременно несколько веток живёт).

И не забываем ребейзить и сквошить.

https://news.1rj.ru/str/mefody_dev/119
💯28👎3🤔2🤝2😁1
Хорошее замечание, что при таком подходе можно перегрузить QA. Ответ тут в том, что QA не должны быть узким местом. Разбираем монолиты на библиотеки и микросервисы, покрываем всё автотестами, подключаем ручное QA только в критичных местах, либо на релизную ветку.

Цель CI в том, чтобы код постоянно вливался и шарился между всеми. Чем раньше мы упрёмся в проблему, тем менее она болезненна. К сожалению, это не особо совместимо с ручным QA, либо придётся приставить по одному QA к каждому разработчику. И что должен этот QA делать с неготовой задачей, закрытой флагом от прода? Только проводить регрессы и смоуки. А с этим автоматика отлично справляется.
👍27
Прохладная история про LCP и SPA

Есть такая метрика в Core Web Vitals — Largest Contentful Paint (LCP). Устроена она достаточно банально — просто показывает время от старта запроса до рендера самого большого элемента на странице. В Яндексе измерение метрик скорости построено так, что мы не просто смотрим на каждую метрику в отдельности, у нас есть специальный индекс скорости, который высчитывается из совокупности Web Vitals.

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

Начинаем вспоминать и понимаем, что включали на праздники новогоднюю анимацию в меню. Тааак. Вот оно! Наши страницы в сервисе — это чистые SPA, серверный рендер приносит только менюшку. Дальше включается лоадер, который тянет конфиги с бэка и рисует контент. И в нормальных условиях LCP возникает после ответа бэка. А когда мы добавили картинку в меню, то получили новый Большой Элемент, который начал рисоваться значительно раньше. LCP подросло и подтянуло за собой общую метрику.

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

А мы будем думать, как добавить немного хорошего быстрого SSR.
😁42👍26🏆64🎄3🔥2🎉1🐳1
Случайно наткнулся на относительно живой форк request в котором хотя бы латают уязвимости — @cypress/request

Хотя, конечно, пожелал бы команде сайпреса слазить уже с request и, тем более, request-promise, который вообще на bluebird.

Но если вам временно нужна затычка вместо оригинального request, то, наверное, сойдёт.
👍103🤔3
Как-то совсем без большого хайпа ребята запустились. Не то, что Bun, где из каждого утюга кричали.
Костылик для GitHub Action

Вот читаете вы про Statoscope, например, и видите в статье готовое решение, как прикрутить его в GitHub Actions. Чтобы полный отчёт грузился на S3, а краткий — прямо в комментарии к пулл-реквесту.

Вот, такой вот yml для воркфлоу https://github.com/statoscope/statoscope.tech/blob/main/.github/workflows/ci.yml . И вот есть в нём большой подвох, если вы прикрутите это к публичному репозиторию — в случае PR из форков GitHub не даст вам доступа к секретам. И пермишенов на публикацию комментариев не даст. Связано это с тем, что в GitHub actions в триггере


on:
pull_request:


весь код для воркфлоу берётся из текущей ветки, а, следовательно, он может быть изменён и креды утекут. Я не нашёл способа изменить поведение и заставить GitHub Actions всегда брать воркфлоу-файл из main-ветки. Получается, нужен костылик.

Костылик получается такой:

1 На пулл-реквест мы делаем нужные дела в ветке (например, собираем отчёт статоскопа)
2 Паблишим отчёт и информацию о пул-реквесте в артефакты гитхаба
3 Создаём ещё один воркфлоу. Триггером будет


on:
workflow_run:
workflows: [Наш первый воркфлоу]
types:
- completed


4 Выкачиваем наш артефакт


- name: Download Artifacts
uses: dawidd6/action-download-artifact@v3
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
run_id: ${{ github.event.workflow_run.id }}

5 Этот воркфлоу запущен из main и у него есть доступ к секретам. Паблишим в S3 и пишем ссылку в комменты PR.


Дополнительно — в исходном решении избыточным выглядит mustache, достаточно взять обычный советский темплейт литерал. А для публикации отчёта в комменты PR удобно использовать https://github.com/marocchino/sticky-pull-request-comment

Ещё раз:

На пул-реквесте собираем артефакт и сохраняем его
https://github.com/datalens-tech/datalens-ui/blob/main/.github/workflows/statoscope_tests.yml#L38

На main ветке распаковываем артефакт и паблишим в S3 и комменты PR
https://github.com/datalens-tech/datalens-ui/blob/main/.github/workflows/statoscope_tests_report.yml#L19
👍36🔥6🤯32❤‍🔥1💋1
Forwarded from mefody.dev
«Я💛Ф» CTF 2024

Вот уже четвёртый год мы небольшой командой делаем фронтенд-игру в стиле Capture the Flag. Участникам нужно найти спрятанные в разных местах текстовые флаги и ввести их в терминалы, чтобы перейти на следующий уровень. Кто первым соберёт обязательные флаги — победит. Кто первым соберёт вообще все флаги — тоже победит. И всё это с приятной музыкой, красивым оформлением и даже полноценным сюжетом.

Если считаете, что разбираетесь во фронтенд-технологиях, заходите сегодня после 20:07 по минскому времени, чтобы поучаствовать в гонке за призами.

https://ctf-2024.ilovefrontend.ru/
29💩5
Ещё раз — старт в 20:07 по GMT+3.

Пока можете вспомнить прошлые

https://ctf.ilovefrontend.ru/
https://ctf-2023.ilovefrontend.ru/
https://ctf-2024.ilovefrontend.ru/
👍18🔥5💩2
Сейчас, когда А* уже официально банкрот и прошла через делистинг на Nasdaq, хочется немного порефлексировать про свой опыт в этом интересной компании. Я же туда заходил, когда она была ого-го, единорог, гремела на рынке! Но через 4 месяца ушёл, не выдержал, возненавидел.

Первое и самое главное, испытательный срок — это двусторонний процесс. Не только компания смотрит на тебя, но и ты смотришь на компанию. И компания может его не пройти. Это нормально.

Второе — разок в большой громкий стартап точно стоит зайти. Узнаешь, что такое IPO, SPAC, размытие доли, обратный сплит и другие чудесные вещи, которые помогут разобраться в мире акций. Посмотришь, как выглядит хайп-дривен изнутри и какие существуют опасные звоночки.

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

Левая рука выбрала Пайтон, а правая решила на Скале. Левая нога деплоится через Тимсити в Кубер, а правая предпочитает Дженкинс и EC2. Везде одни синьоры, но критерий синьорства определяется тимлидом. В это время обе руки крутят один и тот же вентиль, разными способами и в разные стороны. Потому что не договорились.

Всё это очень весело, пока инвестиции не проели.

* все совпадения с реальными компаниями случайны.
👍47🤣15🔥8😢43🤔3🤡3🤝2
Техника тысячи маленьких пиаров — это когда ты параллельно с большими рабочими задачами постоянно находишь какие-то мелкие штуки и улучшаешь, улучшаешь, улучшаешь и свой проект и остальной опенсорс каждый день.
🔥56👍11🤔65👎2👏2🤡2🤓1
Блуждающий ECONNRESET

Достаточно частый кейс в node.js-разработке, когда мы видим в логах блуждающую ошибку ECONNRESET при запросах в другой бэкенд. Начинаем искать, идём на вторую машинку, а там тишина, ошибок в логах нет. Как обычно отвечают — у нас всё хорошо, проблемы на вашей стороне.

Одна из причин это включенный keepalive. Идея keepalive в том, что мы можем переиспользовать коннекшены, не создавать новый коннекшн на каждый запрос. Клиент стучится на сервер, открывает коннекшн, удерживает его и при следующем заходе обращается к уже созданному коннекшену. А что произойдёт, если клиент удерживает коннекшн дольше, чем сервер? Т.е. сервер имеет например keepalive_timeout 4, а клиент создал http.Agent с timeout: 5? Мы и получим тот самый ECONNRESET.

И даже при равных значениях можно достаточно легко войти в состояние гонки:


import http from 'node:http';

const server = http.createServer((req, res) => { res.end('some stuff') });

server.keepAliveTimeout = 5000; //default

server.listen(1337, '127.0.0.1', startSendingRequests);

function startSendingRequests() {
const keepAliveAgent = new http.Agent({keepAlive: true, timeout: 5000});

setInterval(() => {
http.get('http://127.0.0.1:1337', {agent: keepAliveAgent}, (res) => {
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
}).on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
}, 5000)
}


Как решить проблему? Во-первых, если это возжно нужно покрутить таймауты. На клиенте таймаут должен быть меньше чем на сервере. Это даст возможность клиенту закрыть соединение самостоятельно, не дожидаясь ошибки.

Во-вторых, документация node.js предлагает такой паттерн ретрая:


.on('error', (err) => {
// Check if retry is needed
if (req.reusedSocket && err.code === 'ECONNRESET') {
retriableRequest();
}
});


UPD

И конечно важно помнить, что причины, по которым коннекшен может быть закрыт со стороны сервера — разные. Таймаут keepalive лишь один из случаев.
🔥91👍3910
WASM и Докер

Есть одна штука в андроид смартфонах, которая мне бесспорно нравится — это бесконечная лента интересных ссылок по свайпу влево с главного экрана. Буквально вчера подкинули статейку. Оказывается, в оригинальном Docker Engine (который на containerd), можно красиво запускать упакованные в контейнер wasm-приложения. Из уже поддерживаемых рантаймов: WasmEdge, Spin, Slight и Wasmtime.
Штука эта есть в Docker Engine в бета-режиме достаточно давно. Но я-то на OrbStack ушёл. И там пока из поддержки только такой ишью https://github.com/orbstack/orbstack/issues/585

Так ли оно нужно, я пока честно говоря не понял. Но прикольно смотреть куда идёт WASM.
👍25🤔52👎1🔥1
Готовил на Субботник классный доклад про песочницы на Node.js (vm, vm2, v8 isolates, wasm QuickJS и т.д.) и их проблемы. Но, к сожалению, накладка, не попадаю физически. Зато будут другие классные доклады, а свой расскажу как-нибудь попозже.
🔥47😢25👍13