melikhov.dev – Telegram
melikhov.dev
4.63K subscribers
110 photos
2 videos
2 files
203 links
Фронтенд, фронт-бек и около. Всё, что в голову пришло. Иногда котики.
Download Telegram
По поводу тайпогейта

Тут на днях всех взбудоражило, что DHH выпилил тайпскрипт из Турбо 8 (про то, как это было сделано, это отдельная тема для разговора). На этом фоне как-то незаметно прошло майское выпиливание тайпскрипта из Svelte. И вот Николас Закас вспомнил, с какой агрессией столкнулся, рассказав, что новый ESLint не будет переписан на TS. Неудобствами работы с TS делился и Маттео Коллина. И Тимур Шемсединов активно выступает против.

Что тут важно. Во всех этих случаях речь идёт про библиотеки, про низкоуровневый код. Очень хорошо Рич Харрис ответил на вопросы про Свелт:

«Мы не отказываемся от типобезопасности. Мы обожаем статическую типизацию. Мы просто переносим описание типов в JSDoc. Это не сломает ничего для потребителя фреймвока — более того, пакеты станут меньше и вы сможете по клику по функции сразу попадать в её реализацию, вместо бесполезного для вас объявления типов. Да, писать JSDoc не так удобно, но в остальном DX лучше (мы уже давно работаем так со SvelteKit)»

Полностью поддерживаю. Достаточно неудобно работать в большом проекте, разбитом на множество TS-библиотек, вся эта дихотомия ts и js файлов мешает. Код написанный только для удовлетворения TS мешает. Дебаг с сорсмапами мешает. Я ловлю большой кайф, когда для ноды пишу на чистом JS и мне не нужно никаких дополнительных инструментов и шагов транспиляции. Да, Bun и Deno решают эти вопросы, для них *.ts это входной формат файлов. Для ноды — нет (а потом мы видим как либы тащат ts-node ради копеечных скриптов).

Но, конечно, когда мы переходим к описанию бизнес-логики, вот тут я ни за что не готов слезать с TS. Вот тут бы я очень удивился, если бы какой-то проект внезапно решил соскочить со статической типизации (если, конечно, статическая типизация не состояла из обмазывания кода any). А либы — да всё нормально, это вполне понятное решение. Лишь бы тесты были, да d.ts наружу поставляли.
👍89🥴84🤔3🔥1
Почему Bun быстрее Node.js?

Уважаемый Мирипируни интересуется, почему я ничего не пишу про Bun. Ответ простой — я его ещё не попробовал. Зато на днях мнением поделился не менее уважаемый Маттео Коллина: My thoughts on Bun Давайте дам TL;DR

Несмотря на то, что Джарред Самнер и команда Bun делают потрясающие вещи, Маттео расстроен их заявлениями о совместимости с Node.js, которые не являются правдой в данный момент и приводят к наплыву пользователей в репозитории мейнтейнеров node.js-проектов с жалобами на неработоспособность в Bun.

Несколько причин, почему Bun так хорош такой быстрый:

- У Node.js маленькая команда и мало денег. В этих условиях они больше направлены на улучшение API и закрытие дырок в безопасности. Работы по увеличению производительности не приносят денег, более того, облачные провайдеры (главные источники дохода) не заинтерисованы в том, чтобы производительность росла, так как это означает уменьшение их доходов.

- Bun не парится над обратной совместимостью. Прежде всего скорость, а остальное починим, накостылим, запретим. Именно так и делаются по-настоящему быстрые вещи. Node.js продолжает поддерживать своих пользователей.

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

- Bun сейчас не совместим с Pino и Fastify. Команда Bun активно работает над добавлением отсутствующих API и выправлением поведения

- bun install быстрый, но его скорость во многом обеспечена поведением --prefer-offline по-умолчанию. Разница с pnpm --prefer-offline уже совсем не драматическая. Однако то, как добились этой небольшой разницы заслуживает уважения и повторения

Чем же ответит Node.js?

Несколько лет Node.js слишком мало инвестировали в перформанс (да, Маттео, мы заметили :). В прошлом году была собрана команда скорости и теперь это стратегическая инициатива (спасибо, bun!). Node.js будет двигаться вперёд без ломающих изменений. Что уже сделано — можно почитать тут.

Если вы хотите сделать Node.js быстрее, то приходите с пул-реквестами либо помогайте финансово.
👍677🔥65😁1
Но мне есть чем дополнить: две мысли от Джеймса Снела (один из ключевых контрибьюторов в ноду)

1. Твит: «Given that tc39 pushed ESM into the ecosystem without guidance from implementations, I'm increasingly less sympathetic to the idea we need to be completely spec complaint there but also, it doesn't help developers if we aren't. Tradeoffs can be expensive.»
Тут особо и нечего добавить. Про ESM я много писал до этого.

2. Ещё один твит: «Bottom line: Node.js could have these tools also. It needs to stop worrying about competing with it's own ecosystem and make bolder choices when it comes to developer experience.»
А вот тут интересней: давным-давно в ноде решили, что не будут конкурировать с существующей экосистемой — пусть комьюнити напишет удобный тест-раннер, и люди сами определятся какой им лучше подходит (а их, в итоге, оказалось слишком много). Успех (успех ли? Ну, определённое возбуждение точно) вокруг bun и deno и опыт других языков показали, что разработчики хотят видеть необходимые инструменты встроенными в рантайм. И вот у ноды уже есть свой тест-раннер node:test.
🤔85👍3
Если вас интересует, чем я занимался последние десять месяцев — почти всё тут https://datalens.tech/

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

В любом случае, сегодня у нашей команды большой праздник, поздравляю нас.
👍113🎉95🔥30171🤮1
Монтировал тут директорию в контейнер постгреса, ну знаете, чтобы данные не терять при перезапусках. Решил проверить, с какими правами директория создаётся по-умолчанию на MacOs, а там
drwx------@
. О как. Что это за цветочек такой, я такого и не замечал (хотя конечно должен был, но вот так глаз замылился). А это оказался признак наличия той самой мета-инфы, которую на маке можно посмотреть через xattr.

А вот то, чего я не знал, так это то, что мета можно смотреть через забавное ls -l@.


>ls -l@ .us-data

drwx------@
com.docker.grpcfuse.ownership


Кстати, странно, сейчас же VirtioFS в docker desktop, хм.
🔥22👍3🤔1
Приключения DI в мире функционального программирования

Когда-то давным-давно (в 2011 году), Марк Симан написал отличную книгу «Внедрение зависимостей в .NET». Всё, что нужно знать про DI в ООП там есть. Маст рид. А несколько лет спустя Марк ударился в функциональное программирование и написал достаточно резонансную серию небольших статей "From dependency injection to dependency rejection" (а также поездил с докладом).

Сегодня у нас будет TL;DR по этой серии.

Итак, Марк начинает с демонстрации «классического» ООП внедрения зависимостей через конструктор объекта. Классика. Все мы делали это. А дальше Марк задаётся вопросом: а как быть в с ФП? Конструктора у нас нет, а значит все параметры нужно передавать на вход функции. Это неудобно, наш API становится чудовищным.

Первое, что приходит в голову, это частичное применение. Напишем функцию с 4 параметрами, первые 3 из которых это зависимости (код на F#):


let tryAccept capacity readReservations createReservation reservation =
let reservedSeats =
readReservations reservation.Date |> List.sumBy (fun x -> x.Quantity)
if reservedSeats + reservation.Quantity <= capacity
then createReservation { reservation with IsAccepted = true } |> Some
else None



«Приклеим» зависимости


let tryAcceptComposition =
let read = DB.readReservations connectionString
let create = DB.createReservation connectionString
tryAccept 10 read create


На выходе имеем функцию tryAcceptComposition в которую уже внедрены зависимости и остался один входной параметр reservation.

Дальше Марк делает классный трюк, и превращает код из F# в C# средствами .NET (через его промежуточное представление IL). И код на C# выглядит как обычный объект с внедрением в конструкторе!

Решена ли задача? Можно ли сказать, что частичное применение решает задачу внедрения зависимостей в ФП? Марк предлагает решить спор используя Haskell. F# язык хороший, но он позволяет много больше, чем «настоящие» ФП языки. И что же у нас происходит в Хаскеле? Если мы объявим tryAccept чистой функций, то код не скомпилируется. Потому что зависимости несут сайд-эффекты (походы в базу данных).

Т.е. частичное применение решает вопрос внедрения зависимостей, но оно делает код нефункциональным. Чтобы функции остались чистыми, мы должны отказаться от внедрения зависимостей. И тут Марк переходит к последнему шагу. Он переписывает tryAccept так, чтобы на входе были только «чистые» значения:


let tryAccept capacity reservations reservation =
let reservedSeats = reservations |> List.sumBy (fun x -> x.Quantity)
if reservedSeats + reservation.Quantity <= capacity
then { reservation with IsAccepted = true } |> Some
else None


Эта функция не требует внедрения зависимостей, в ней нет сайд-эффетов. Сайд-эффекты поднимаются на уровень функции-композиции, в ней происходит вся «грязь»


let flip f x y = f y x

let tryAcceptComposition reservation =
reservation.Date
|> DB.readReservations connectionString
|> flip (tryAccept 10) reservation
|> Option.map (DB.createReservation connectionString)


В итоге Марк постулирует, что функциональное программирование должно отказаться от понятия внедрения зависимостей. Чистые функции не могут вызывать нечистые функции. Мы должны оставить наше ядро чистым и поднять всё нечистое до уровня границы с внешним миром (и снова привет тебе, архитектура портов и адаптеров).
👍35🤔123🤮2
Так, мне нужен ваш опыт

Подскажите хорошие примеры качественной работы с текстами и переводами в опенсорс-проектах? Вот чтобы не просто
md
и
json
файлы абы как коммитили, а был построенный процесс, как во взрослых коммерческих проектах.

Под процессом я понимаю примерно следующее:

- Изменение или добавление ключей в ветке блокирует пулл-реквест;
- Приходят переводчик и техпис, забирают тексты в свою систему;
- По готовности текстов они выгружаются обратно и коммитятся автоматикой в ветку PR;
- Блок снимается, PR заезжает в main.

Это значит, что где-то нужно поднять платформу локализации (тот же Weblate), как-то удобно следить за текстами, понимать статус задачи на вычитку/перевод. Хочу посмотреть, как это устроено в других проектах.
16👍2
Как мы ничему не научились на примере жизни и смерти Yarn

Статья от Джареда Вилкарта про Bun в моём любимом жанре «дедовское брюзжание». Как многие опытные программисты знают — выбирать надо скучные технологии. И сидя на берегу дождаться, пока мимо проплывут останки недавно хайповой штуки.

И вот Джаред проводит параллели между Yarn и Bun:

— продают «скорость»,
— раскалывают экосистему,
— не про обратную совместимость,
— в стабильной 1.0 версии не поддерживают Windows.

Yarn на старте был быстрее npm. Но npm догнал его по скорости, а создателям Yarn пришлось объяснять, что вообще-то они были не про перформанс, а про фичи. Сложно конкурировать с владельцем npm-серверов.

В итоге, все фичи yarn внедрены в npm и npm ещё и быстрее (тут Джаред почему-то забывает про Plug'n'Play, который пусть не сразу, но появился в Yarn, но так и не был реализован в npm). Да, есть нюансы, кому-то они важны, но для большинства людей подходит npm.

Вот и Bun — он не делает ничего, что нельзя было бы достичь в Node.js не ломая обратную совместимость. Так что в какой-то момент Node.js скорее всего получит паритет по скорости. И маркетинговая шумиха про скорость сойдёт на нет.

Ок, Yarn пришёл, пошумел и умер. В процессе подстегнул npm. В чём проблема? В том, что пока Yarn шумел и продавал функции, которые на самом деле в большей степени были нужны только Facebook, команде npm пришлось гнаться за ним и добавлять схожие фичи, чтобы экосистема не раскололась сильно. При этом были изменены приоритеты, фактически Facebook косвенно повлиял на порядок внедрения фичей в npm.

А дальше Yarn проник в Readme. Куча проектов стала ориентироваться на Yarn и писать инструкции, как развернуть их с помощью Yarn. Смущая новичков и тратя время синьоров на объяснения, почему в наш конкретный проект так ставить зависимости не нужно.

Вместо того, чтобы контрибьютить в npm Facebook потратил силы на создание собственной его копии. И ради чего?

Но bun гораздо опасней

Bun предлагает скорость и опасные фичи:

1. Макросы — ваша сборка теперь гвоздями прибита к Bun
2. bun.x API. Собственные «более быстрые» API. Ваш код будет «отравлен» ими. Придётся ставить зависимости — полифиллы. Ура, ещё одна зависимость.
3. Встроенную поддержку мета-языков. Тут подробнее.

Мета-языки временны. Их задача сделать программирование удобней, пока основной язык не дотягивает. Как только возможностей основного языка достаточно, мы отстреливаем мета-язык. Как выкинули CoffeeScript, как многие отказываются от Sass, потому что CSS сам по себе уже достаточно неплох. Но вот в Bun теперь встроен ужасный JSX и TypeScript.

А TS уже прошёл свой пик. Графики показывают первые признаки разворота сообщества с сторону более лёгких альтернатив, таких как eslint-plugin-jsdocs, а на горизонте маячит добавление статической типизации на комментариях в ES202X. В какой-то момент TS может сказать, что его работа закончена. Sass тут отличный пример — из популярнейшего дефолтного инструмента для всех он уходит в сторону узкоспециализированного продвинутого инструмента для профи.

А если бы Bun вышел в 2019 году на пике популярности Sass, то Sass был бы встроен в него. И что бы они делали в момент смены API? Вы уже не можете написать npm install <версия Sass>. Не нужно прибивать мета-языки к рантайму.

Bun приносит абстракции для кучи технологий, но он не абстрагируется от этих технологий. Он не берёт что-то сложное и делает это проще и универсальней — нет, он засовывает это в себя как есть. И всегда будет отставать от оригиналов (нужно следить за изменениями API и добавлять код в свою реализацию). При этом абстракции эти находятся в критически важных местах: установка зависимостей, тесты и сборка.

Дальше Джаред пишет про Windows. Сборка под неё экспериментальная и обещают позже дать стабильную. И Джаред сомневается, что столь небольшая команда сможет одновременно догонять фичи для Windows и пилить новые в Linux/OSX. А не пилить фичи нельзя. И как-то придётся выравнивать версии. Возможно через год у нас будет v1.8 для Linux и v1.0 для Win.
👍75🤡6👎42🤔2💯2😁1
А мир во фронтенд-разработке меняется достаточно быстро. Как скоро мы увидим конкурента Vite? Как скоро уйдём с ESBuild? Внедрит ли Bun новые абстракции и будет ли поддерживать старые? Или просто удалит их?

А если мы нашли проблема в JS Runtime — можем ли мы обновить рантайм, не потеряв инструменты, на версии которых мы завязались? О нет. Кажется нужно всё переписывать.

Что будет, например, когда запустят JavaScript Shadow Realms? Vitest уже ждёт их, готов использовать. Вот только Bun будет ждать, пока Shadow Realms прорастут в WebKit. Что будет в этот промежуток с совместимостью с Vitest? (Джаред забывает, что первая реализация Shadow Realms внедрена как раз в WebKit. Но пример достаточно корректный, так как позже имплементация была убрана за флаг, потому оставим тут).

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

• Если бы Bun вышел в 2012 году, в него был бы встроен Grunt.
• Если бы Bun вышел в 2014 году, в него был бы встроен Gulp.
• Если бы Bun вышел в 2016 году, в него был бы встроен Webpack.
• Если бы Bun вышел в 2018 году, в него был бы встроен Rollup.
• Если бы Bun вышел в 2020 году, в него был бы встроен ESBuild.
• Если бы Bun вышел в 2026 году, в него был бы встроен ...

Это не значит, что Bun отстой. Bun хорош. Но седые и строгие деды уже чуют запах будущих проблем. Прогноз Джареда, что Bun будет с нами лет 5, прежде чем все про него забудут. Ну а все проекты, которые Bun встроил в себя и ускорил — наверстают упущенное за год.
👍509🔥8🤔4🌚2
Смотрите, что подвезли в Телеграм Beta

```javanoscript
console.log('Hello world');
```
🔥198👍267🤯1
История про баг в Safari

Недавно решил поправить browserslist в проекте и оторвал правило Chrome >= 72 как явно для нас устаревшее. После релиза получаю всплеск жалоб от пользователей Safari 15 (их много!). Бегу проверять, вижу ошибку (самое смешное, что ошибка не проявляется при включенных девтулз), откатываюсь. Дальше мучительный поиск проблемы.

Прописываю Chrome >= 74 — бага есть. Chrome >= 73 — баги нет. Ясно, дело в полях классов. Начиная с Chrome 74 у нас есть полная поддержка публичных и статических полей классов, полифилл больше не нужен. Но в Safari 15 тоже полная поддержка! Can I Use врать не будет же. Где же баг и почему его не лечит правило Safari >= 15?

Долго ищу как запустить Safari 15. Проблемное место нахожу достаточно быстро — это описанные через static propTypes, в которые прилетает внешнее значение/ссылка. Вот это место

Ищу дальше. Да, в Safari 15 есть такой баг! https://bugs.webkit.org/show_bug.cgi?id=236843 Поля классов в нём поддерживаются, но иногда не работают.

Остаётся понять последнее, почему preset-env не помогает? Ищем дальше. А вот оно как, в Babel заведена ишью уже больше года как. В комментах и @valya_reads_issue отметился. Как же лечить? Вот, например, так, как сделали в Графане. Прописать @babel/plugin-transform-class-properties в плагины.

Мораль тут такая, что спецификации спецификациями, но тестировать надо на реальных браузерах.
😨32👍136😱5🤣4😢3
Почитайте тоже https://news.1rj.ru/str/valya_reads_issue/329

TL;DR «Начиная с 7.22.6 в @babel/compat-data указано, что class properties поддерживаются в iOS 14.5, а до этого было указано что в iOS 15, т.е. с Safari 15 сдаунгрейдили поддержку до Safari 14.1. Напомню, без багов эта фича работает начиная с Safari/iOS 16. »
👍6😨31
После раскрытия кода Даталенс весь ноябрь проходит в каком-то бесконечном девреле. В декабре финальное, расскажу на YaTalks докладик и, надеюсь, эту тему пока поставить на паузу. Хотя бы до января, снежок же выпал, склоны запустились, найти бы свободный выходной.

Хочется и продуктовых задач уже поделать, фичей для юзеров позапиливать, хотя вопросов о взаимодействии с внешними контрибьюторами местами всё так же больше, чем ответов.

Не лезь туда, оно тебя сожрёт! Но тебе даже понравится.
👍274😁3🔥1
Про билд-секреты в докере

Давно хотел написать. Вот есть задача закинуть секреты в docker build. Это не рантайм-секреты, это секреты необходимые только на этапе билда. В итоговом образе они светиться не должны (как и любые секреты).

Как тут правильно поступить? --build-arg (ARG в Dockerfile) не подходит для передачи секретов, запомните это. Достаточно docker history --no-trunc <img> и вот они, секреты, как на ладони. Значит, какие у нас варианты:

1 Вытягивать секреты из секретницы в самом билде — не всегда возможно;
2 Multi-stage билд — может существенно замедлить сборку;
3 Закинуть секреты через встроенный механизм докера!

Как оно работает. Создаём файл с секретами. Например, .secrets. Обычный текстовый файл, куда мы закинем секреты строчка за строчкой.


cat <<EOT > .secrets
SUPER_SECRET_1=$SUPER_SECRET_1
SUPER_SECRET_2=$SUPER_SECRET_2
EOT


Включаем BuildKit через env DOCKER_BUILDKIT=1. Если у ваc Docker >= 23.0 то BuildKit включен по умолчанию.

Скармливаем файл с секретами:


DOCKER_BUILDKIT=1 docker build --secret id=secrets,src=.secrets .


В Dockerfile монтируем секреты в RUN и загоняем их в env


RUN --mount=type=secret,required=true,id=secret,target=./.secrets \
export $(cat .secrets) > /dev/null && \
npm run build


Можно не только через файл, но и через ENV но это мне кажется наименее удобным.
🔥82👍19
Satechi делает много классных вещей, но вот именно эти два кабеля меня в дороге выручают постоянно: длинный type-c с переходником на HDMI и супер-короткий type-c на lightning
👍51
Forwarded from Веб-стандарты (Vadim Makeev)
Приходите в субботу 16 декабря в 12:00 (UTC+3) на стрим подсмотреть как мы записываем 400-й эпизод Веб-стандартов вживую и обсуждаем новости фронтенда за неделю. Обычный эпизод, ничего такого 🤓

https://youtube.com/live/-QyzkZ0sHRA
👍33🔥13🥱1🍾1
Я как-то уже писал, что полностью перешёл на разработку на удалённой 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