Андруша пишет код – Telegram
Андруша пишет код
1.25K subscribers
137 photos
1 video
1 file
218 links
Download Telegram
https://twitter.com/Hinkali4/status/1753172405260812770

Почему-то в 2024 году люди всё ещё не научились в цифровую гигиену.
Делюсь великим секретом: не смешивайте работу и личную жизнь. Максимально разграничивайте их. На работе старайтесь пользоваться исключительно рабочими мессенджерами(Slack, MS Teams, etc.). Если работа лезет в телегу(привет, Яндекс!), то не поленитесь и заведите отдельный рабочий аккаунт. К примеру, у меня это @XaveScorWork.

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

Если опустить вопрос коммуникации, то я так же советую вам обзавестись отдельным рабочим оборудованием, отдельным календарём, отдельной почтой и отдельным всем-всем-всем. Не надо работать с устройств и аккаунтов, где вы держите личные данные. Смешивание работы и личной жизни - цэ мэрзость. Цэ рэально мэрзость. Чем дальше будет ваша работа от вашей личной жизни, тем лучше вы будете себя чувствовать.
👍4💩2
Ну, время написать что-нибудь и о программировании. Сейчас я занимаюсь рефакторингом одной нашей внутренней библиотеки, вторая версия которой будет иметь куда более удобный, как нам кажется, интерфейс.
Но есть 2 важных НО:
1) нужна совместимость со старым контрактом
2) либа принимает на вход функции из кодгена, и для комфорта разрабов кодген должен корректно приниматься как старой версией либы(для обратной совместимости), так и новой(для нового кода).

И из второго пункта появляется очень большая засада: нам нужно сохранить как-то типы, которые либа выводит из кодгена, а TS не имеет механизмов сохранения одного типа внутри другого.
Другими словами:

type Attach1<P, X> = P
type Extract1<A> = A extends Attach1<any, infer X> ? X : never;


type Attached1 = Attach1<{a: number}, string>;
type Extracted1 = Extract1<Attached1>; // unknown

https://www.typenoscriptlang.org/play?#code/C4TwDgpgBAgswEMDGALAjAHgAoBooA0A+KAXiiwChRIoBRAD2ACdlhMZiyYoJGIA7ACYBnWPGToMCfiDwBLfgDMITAsQD8BKAC4o-CADcVAbgpnq0OIlQRBaUmOuSA3gl38ArgFsARioC+eMLMCgDmhKYWdIwsSMC29mQMzKzs4jZ2EVAA9NlQHvwA1vwA9gDu-BRAA

Но если добавить ограничения, что тип P - это всегда объект, то можно сделать костыль:

type Attach2<P extends object, X> = P & {___private?: X}
type Extract2<A> = A extends Attach2<object, infer X> ? X : never;


type Attached2 = Attach2<{a: number}, string>;
type Extracted2 = Extract2<Attached2>; // string

https://www.typenoscriptlang.org/play?#code/C4TwDgpgBAgswEMDGALATAHgApQgD2AgDsATAZygHsAjAKwiWABooANAPigF4ocAyKAG8A+qLAAnAJYA3BIQD8ALjYBfAFChIUAKIFxyYJhiceMXAWLlY8ZOgw16jFpKIAzCOLad5bKMqIQ0h4A3GphmtBwiKgQJGjc1tF2ggj+AK4AttQeKixkwFJEAObsoRE6egax8Ty6BQZGNjFxpVAA9G1Q+YVFakA

Да, это некрасиво и ts будет показывать внутреннее поле. Но в рантайме можно туды ничего не класть и тогда всё будет типа ок. Кмк, для обратной совместимости с кривыми контрактами, вполне хорошее решение. У нас в библиотеке этот способ позволяет на уровне кодгена запихивать в типы любую дичь, которую можно потом достать из слоя обратной совместимости
👍4💩2
Даже jquery выпускает новые релизы https://blog.jquery.com/2024/02/06/jquery-4-0-0-beta/

А реакт все сидит на версии 18.2.0
😁13💩2🔥1
Если внезапно вам приспичит верстать письма, то есть супер дока по поддерживаемым фичам webview в разных почтовых клиентах

https://www.caniemail.com
👍71💩1
Вчера мне для кодгена нужно было генерировать цепочку выражений для ts:

type X = {} & {a: A} & {b: B} & ...

Пустой объект был нужен, так как {x: X} генерился по условию, в зависимости от заранее описанной спеки

Но вот какая засада:
type X = {} - это не пустой объект. Я даже не помню что это, но точно не пустой объект. ESlint-typenoscript для таких выражений рекомендует Record<string, never>, но это ломает первое выражение.

Но есть пакет, содержащий утилити типы, которые работают так как вы ожидаете: https://github.com/sindresorhus/type-fest

К примеру, пустой объект тут выглядит уже нормально https://github.com/sindresorhus/type-fest/blob/main/source/empty-object.d.ts

Не горячо, но советую. Упрощает жизнь, так как можно забыть о тупняках тайпскрипта.
👍3😈3💩2
Сейчас каждый фронтенд разраб знает об nvm. О тулзе, которая позволяет очень просто устанавливать почти любую версию ноды, но не каждый читает доку к nvm.

А если почитать доку, то можно там найти сверхудобную автоматизацию https://github.com/nvm-sh/nvm?tab=readme-ov-file#deeper-shell-integration
Она позволяет автоматически включать нужную версию ноды, в зависимости от директории, которая сейчас открыта. Вы можете не переключаться каждый раз руками через nvm use

#база
👍15👎2🔥2💩1🤡1
Не так давно мой хороший знакомый https://news.1rj.ru/str/kelin2play/573 задал простой вопрос: как подчистить ненужный мусор со своего компьютера.
Очевидное решение для меня - windirstat, но в комментариях подсказали ещё wizTree.

На примере этих продуктов можно проследить какая пропасть в между современными продуктами и хорошим маркетингом: на странице windirstat на первом же экране понимаешь как хорошо эта программа решает вашу проблему. У wizTree же - куча текста, в который надо вчитываться. И даже пролистывание главной не помогает.

Если вы в компании верстаете или дизайните вашу продающую страницу, то пытайтесь вмешиваться и не делать так как сделано у wizTree. Я, лично, ненавижу вчитываться в километры текста, когда вижу что-то новое. Да и никто не любит. Это сложно.
👍5💩3
Попробую вам сегодня продать GitHub Copilot. Эта штука всё же сносит мозг даже после года использования.

Главная вещь: правильно описанные типы позволяют почти не писать логику вовсе. Copilot реально понимает что тебе надо. Да, этот код нужно чуток подрихтовать, но даже в таком виде его спокойно можно отправлять в прод.
👍7🍌1
React.memo и React.forwardRef - это постоянная заноза в заднице с точки зрения типов, если вы в проекте используете TS.
И о решении одной из этих заноз написал https://news.1rj.ru/str/ru_react_notes/404

Подобное решение может казаться верным, но только в случае если вы не понимаете как работает React.forwardRef. Потому что React.forwardRef возвращает ОБЪЕКТ. Да, можно много рассуждать верно или нет это с точки зрения архитектуры, но имеем что имеем.
А в предложении поста говорится "а давайте обманём рантайм и скажем, что возвращается функция".

function fixedForwardRef<T, P = {}>(
render: (props: P, ref: React.Ref<T>) => React.ReactNode
): (props: P & React.RefAttributes<T>) => React.ReactNode {
return React.forwardRef(render) as any;
}

Не обманывайте себя. Да, кажется, что это необходимое зло, но это не так. Простой пример. Вы рефакторите уже существующий компонент и хотите добавить к нему ref. И вот тут вы не можете гарантировать, что его не вызывают как функцию. Потому что, увы, это так. В проектах куча говна, в котором встречается любой код, который не запрещён ESLint'ом. А и запрещённый им тоже есть.
Поэтому максимальными силами старайтесь сохранять все инварианты существующего кода.

По этой причине более корректным решением будет

function fixedForwardRef<T, P>(
render: (props: P, ref: React.Ref<T>) => React.ReactNode
): (props: P & React.RefAttributes<T>) => React.ReactNode {
const Forwarded = React.forwardRef(render);
return (props: P & React.RefAttributes<T>) => {
return <Forwarded {...props} />
}
}

Как минимум потому что все вызовы компонента напрямую продолжат корректно вызываться.
https://github.com/tc39/proposal-set-methods

Ого, какая штука, оказывается есть. Походу кто-то всерьёз решил заняться над комфортом работы с коллекциями. Оно аж уже в Хроме и Сафари есть. Походу пора ставить полифилы и вовсю использовать
👨‍💻2
Так как моя страна собирается в очередной раз переставить кровати в виде смены часовых поясов, то мне даже интересно какие системы попадают в Казахстане 1 марта.
https://tengrinews.kz/kazakhstan_news/kazahstan-perehodit-edinoe-vremya-i-doljen-perevesti-strelki-526671/

По мотивам этого вспомнил интересную историю как люди решают проблемы с синхронизацией времени в реальной жизни:
Как вы знаете, у нас есть такая штука как високостная секунда, которая раз в несколько месяцев "добавляется" или "вычитается" из текущего времени. Но как оказалось, иметь реальное время - это прямо проблема в куче систем, так как люди предполагают что время идёт только вперёд, а стоять на месте не может.
В итоге компании договорились в случае добавления високосной секунды ускорять время так, чтобы через какой-то момент заданное время догоняло реальное, а в случае отнимания - замедлять, чтобы в какой-то момент достичь синхронизации. Так что, внезапно, часто 1с != 1с. И такое время решили назвать монотонным:
https://medium.com/@xenonchikmaxxx/а-вы-знали-что-на-ваших-серверах-есть-по-сути-два-вида-часов-1d5cb6af4dbb

Если серьёзно, то эта штука пригождалась мне только 1 раз в жизни года 3-4 назад. Но, 1 раз всё-таки пригодилось.

Пара примеров того к чему может привести немонотонность времени - в комментариях.
🔥3👍2
Время - это настолько сложная штука, что люди не только не могут справиться с сложнопредсказуемыми ситуациями типа "правительству стало скучно и они поменяли таймзону", но и с вполне предсказуемыми вещами типа 29 февраля, который понятно что бывает раз в 4 года(если мне не изменяет память)

https://codeofmatt.com/list-of-2024-leap-day-bugs/
🤡41👍1💩1
Forwarded from artalog (artalar)
Temporal

Ну и история! 13 мая 2017 появляется первый коммит Temporal Proposal - нового апи для управления датами, вдохновленный moment и luxon.

Ключевые отличия от Date: продуманная работа с часовыми поясами, иммутабельное апи, работа с интервалами (Duration). Схема ключевых сущностей.

В 20 году идет активная работа над полифилом. Игалия вкладывает в него много сил, написано куча тестов, многое сделано типобезопасно и даже в рантайме расставлено куча ассертов - все по лучшим практикам.

Я сам использовал этот полифил в течении года, пока пилил проект на ноде, остался очень доволен! С багами не сталкивался, только сделал ПР с улучшением типов (приятно делать даже небольшой вклад в такие крупные проекты)

Уже в 21 году я считал сам пропосал и полифил к нему самым продуманным и проработанным тулом для работы с датами. И сейчас так считаю, но смущает 200 kB (50 kB gzip), что бы тянуть на фронт. Хотя стоит учитывать, что когда оно появится в браузере вы сможете просто вырезать полифил не меняя сам код, чего не скажешь про остальные либы для дат из NPM.

Но почему это все еще не стандарт?

Ключевая фича нового апи - работа с часовыми поясами, не могла быть реализована из-за недоработки самого стандарта часовых поясов. Ужвал - сотрудник Игалии и основной разработчик Temporal, а так же просто очень крутой чел, внес предложение в стандарт дат всея интернета по расширению формата хранения и передачи времени с возможностью расширять его дополнительной информацией. Например?

По закону на Гаваях время должно быть одно, но все местные живут по другому, кто прав? Это не придуманная ситуация, а реальная проблема с которой столкнулся разработчик у нас в чате. Предложенное расширение стандарта позволяет указать не только часовой пояс, но и конкретный “календарь”, который может иметь свою специфику.

23 октября 2023 предложение апрувнули!

Работа над темпорал продолжается, серьезных блокеров, кажется, больше нет. Текущий статус трекатеся тут: https://github.com/tc39/proposal-temporal/issues/2628

Мне сложно сказать, когда предложение станет стандартом и мы увидем его в браузерах, но вот в V8 реализация Temporal занимает уже больше 2.6% бинарника и вы уже можете использовать его в Deno.

Напоследок, очень порекомендую великолепный доклад Пару календарей назад я был совсем другим Алексея Охрименко, для понимания всей проблематики. А вот доклад конкретно про Temporal: How to Outsmart Time Building Futuristic JavaScript Apps Using Temporal
🔥5💩21
Сепарация

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

Да, вы можете сказать "компиляция шаблонов" у ангуляра, свелта и вью - это прямо пушка. Я могу согласиться, но если вы посмотрите на то как устроены эти компиляторы, то увидите, что их самая важная часть - это биндинг реактивных частей к DOM элементам.

И поэтому абсолютно все фреймворки в той или иной степени реализуют ровно один способ организации логики: реактивный. И причина проста: руками следить за изменениями стейтов и понимать стоит ли делать ререндеринг - сверхсложно(я смотрю на тебя реакт). И продвинутость именно этой части отличает одну систему от другой:
- свелт изобретает свой язык
- вью пилит своё велосипед, который позволяет описывать весьма неплохо реактивные связи
- ангуляр2+ взял для себя RX и благодаря этому становится прямо конфеткой
- реакт плюнул на всё и дал людям только способ рендеринга и биндинга к рендеринг слою. В итоге все пилят свои стейт менеджеры.

По этой причине, если вы хотите повышать свои скиллы во фронтенде, то вам необходимо не осваивать всякие финтифлюшки, которые можно делать в конкретном фреймворке, а качать базу: то как работают реактивные системы. Потому что теория - это важнейшая вещь, когда ты уже научился говнякать всякие решения. А эта база уже и используется почти везде.
И тут нам, русскоязычным, внезапно повезло. У нас есть огромное количество ребят, которые очень хорошо шарят в этой теме: @artalog, @effector_news, http://mol.hyoo.ru

И на последнее я рекомендую очень сильно обратить внимание. Да, вам может не нравится Карловский(как и мне, так как у него совершенно на нуле софт скиллы и он не очень хороший продажник), но чувак реально несёт базу. К примеру, тут: https://habr.com/ru/companies/timeweb/articles/586450. Чувак очень умный в этом отношении и мол имеет огромное количество прекрасных идей. Реализация, конечно, под вопросом, но именно теоретическая база, которая там лежит - эпохальна. И всё это есть, внезапно, почти только на русском.
Так что если хотите качать себя как фронтендера, то изучите что такое $mol и какие идеи он в себе несёт. Потому что это, не побоюсь сказать, одно из самых технологичных решений во фронте, которое сейчас есть на рынке.
👍44😁5🤩43💩2🥰1
Диверсификация(не о js)

Последние 2 года я веду жизнь ИП, из-за чего приходится взаимодействовать +- активно с государством. И ногда государство любит делать всякие пакости, чтобы взаимодействие было более удобным для него.
И вот ситуация: Я в Канаде и получаю блокировку всех счетов в Казахстане(где живу, плачу налоги и в общем работаю), а так же не стоит забывать что между Казахстаном и мной сейчас 12 часов разница, так что я не могу целые сутки узнать в чём причина блокировки, так как ночью, очевидно, никто не работает.

Сейчас же я узнаю, что я получил блокировку всех своих финансов из-за долга по налогам в 0.07USD. Весело, правда?

Короч, какой я могу сделать вывод: можно сколько угодно пенять на несправедливое государство, но жить как-то надо. То бишь не стоит держать все финансы в одной юрисдикции. После разблокировки счетов я займусь тем, что раскидаю часть денег по разным местам, которые одновременно не смогут заблокировать:
1. Часть денег унесу в США, Грузию, Вьетнам или Кыргызстан(как мне посоветовали в чатиках, так как это самые безгеморные зоны, но это не точно)
2. Часть денег переведу в РФ, так как сделать обмен на Тинькофф <=> деньги в любом другом регионе стало не так сложно. Спасибо войне и рассредоточившимся россиянам по всему миру
3. Часть денег уведу в какой-нибудь стейблкойн типа USDT, чтобы их всегда иметь при себе.
4. Иметь друзей, которые дадут тебе одолжить карту(благо такие уже есть)

Всё-таки не прикольно жить с $20 в кармане налички и не иметь доп. денег. Очень сильно бьёт по психике
👍142💩2🤔1
Невидимая глазу работа

Недавно я попал в очередное набрасывание на вентилятор в теме "линтер vs форматтер".
Да, всё ещё есть люди, которые считают, что в 2024 году нужно иметь собственные правила форматирования и что надо этим управлять самостоятельно.

На фоне этого, я решил заглянуть в репозиторий Prettier'a и прямо подивился какого уровня проблемы там пытается решить сообщество.

Например:
- https://github.com/prettier/prettier/issues/14754
- https://github.com/prettier/prettier/issues/187#issuecomment-1971232175
- https://github.com/prettier/prettier/issues/15515

И я уж точно понял, что подобные проблемы у меня решать самостоятельно уж точно никакого желания нет. Пусть этим занимается сообщество. Потому что это прямо гиганский труд, который, по факту, достаётся нам бесплатно.
💯4💩2👍1👎1🔥1😱1
Хватит сжимать изображения руками

Сейчас я чуток начал торговать своей задницей(https://news.1rj.ru/str/xavescor_meetings_logs/6) и занимаюсь, в том числе, созданием рекламных материалов, чтобы привлечь людей.
Одним из способов доказать свою квалификацию я решил пробежаться по крупным казахстанским(и не очень) сайтам и провести онолитегу как их можно изменить минимальными телодвижениями, чтобы они работали шустрее.

И, к сожалению, я вижу, что у 99% ресурсов нет такой штуки как сжатие изображений. Как менеджер запихнул фото на лендинг, так оно и отдаётся. Не делайте так. Да, я не говорю что надо погружаться в теорию отдачи изображений(но ознакомиться стоит https://evilmartians.com/chronicles/images-done-right-web-graphics-good-to-the-last-byte-optimization-techniques). Хотя бы жмите изображения автоматом. Те же марсиане давно сделали прекрасный imgproxy(https://evilmartians.com/products/imgproxy), который сам сожмёт изображение в наилучший формат для каждого клиента.

Не позволяйте своей лени ухудшать пользовательский интерфейс. А то получится как у jusan.kz, у которого на главной находится 5 огроменных картинки, под 1 мб каждая.
👍10💩2🔥1👏1
TTI всё

Вышел наконец-то https://developer.chrome.com/blog/lighthouse-10-0, где основным изменением стало как раз удаление TTI из метрик.

TTI(time to interactive) - одна из метрик, которая показывала время от момента открытия страницы до момента, когда пользователь может взаимодействовать со страницей.
TBT(total blocking time) - сколько времени выполняются таски до статуса IDLE эвент лупа
CLS(cumulative layout shift) - насколько сильно ваша вёрстка "дергается" в процессе загрузки

Гугл считает, что мерять TTI не имеет смысла, так как эта метрика очень хорошо кореллирует с TBT. И по этой причине 10% оценки лайтхауса теперь уходит в сторону CLS. Теперь корпеть над рендерингом и структурой страницы стоит побольше времени, если хочется иметь хорошую оценку от гугла. А её хочется иметь, так как относительно этих метрик гугл, в том числе, ранжирует свою выдачу. Поэтому если вы хоитте иметь хорошее SEO, то стоит выбивать около сотни в лайтхаусе.

Так же добавили несколько новых эвристик. Но на них смотреть не так важно: просто запустите новый лайтхаус у себя на сайте и постарайтесь всё исправить о чём он говорит. Он весьма подробно рассказывает в чём может быть проблема.
👍3💩21🔥1