https://nodejs.org/api/esm.html#importmetadirname
Славься мир. Больше никаких
Славься мир. Больше никаких
import { dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
👍16🤡3💩1
Ограничения - цэ добро
После https://news.1rj.ru/str/xavescor_code/77 я решил доказать это на практике, заменив xhr внутри axios на fetch. Это позволило бы и уменьшить размер аксиоса и позволить людям перейти на более простое, вебосовместимое решение.
Но я столкнулся с проблемами, о которых должен думать разраб библиотеки, но о которых не подумали разработчики аксиоса:
Целковый. Каждая новая перегрузка апи должна решать новый спектр задач. К примеру, у реатома хук useAtom может принимать как атом, так и функцию, которая возвращает значение. Эти перегрузки не взаимозаменяемы. AxiosHeaders же может принимать в себя кучу разных типов, которые потом очень хитро превращаются в строку при превращении в хедеры. И эта хитрость очень сильно мешает как во внутренней реализации, так и при написании адаптеров. Но если бы AxiosHeaders принимал только строки, то и реализация была бы проще, и клиентам было бы не особо сложнее.
Приведу другой пример: Куча либ позволяет принимать в себя как тип T, так и Array<T>, а внутри уже T приводится к [T]. Даже если специальная функция в npm: arraify. Но, заставив пользователя писать не foo(x), а foo([x]) мы бы сэкономили и на размере либы, и на упрощении контракта.
Вывод: все приведения типов должны быть снаружи библиотеки, а не внутри. Делайте апи максимально скудным. Это очень упрощает жизнь и в тестах, и в реальной жизни
Полушка. Обновляйте библиотеки и меняйте устаревшие решения на современные. Аксиос для тестирования в браузере использует karma + jasmine. А для того чтобы отслеживать запросы, они мокают xmr. Ну, это хорошее решение, пока у нас не появился второй примитив для отправки запросов. А сейчас нормальным решением является какой-нибудь playwright, который через вебдрайвер уже получает информацию о запросах от браузера, а не с помощью моков конкретной стуруктуры. В итоге из-за кривых тестов мне для проверки своей реализации нужно ещё переписать тесты
Четвертушка. РАЗНЫЕ ТЕСТЫ НА РАЗНЫЕ ОКРУЖЕНИЯ. axios - делаем запросы по-разному. Я не знаю что в голове у людей, которые пилят аксиос, но у них 2 набора тестов: для ноды и не для ноды. Причём это РАЗНЫЕ ТЕСТЫ. Они не пересекаются. И дело не в моках. Я проверял. Тесты реально разные и проверяют разную логику. Axios - библиотека, которая работает по-разному в разных окружениях. Велкоме.
Так и живём...
После https://news.1rj.ru/str/xavescor_code/77 я решил доказать это на практике, заменив xhr внутри axios на fetch. Это позволило бы и уменьшить размер аксиоса и позволить людям перейти на более простое, вебосовместимое решение.
Но я столкнулся с проблемами, о которых должен думать разраб библиотеки, но о которых не подумали разработчики аксиоса:
Целковый. Каждая новая перегрузка апи должна решать новый спектр задач. К примеру, у реатома хук useAtom может принимать как атом, так и функцию, которая возвращает значение. Эти перегрузки не взаимозаменяемы. AxiosHeaders же может принимать в себя кучу разных типов, которые потом очень хитро превращаются в строку при превращении в хедеры. И эта хитрость очень сильно мешает как во внутренней реализации, так и при написании адаптеров. Но если бы AxiosHeaders принимал только строки, то и реализация была бы проще, и клиентам было бы не особо сложнее.
Приведу другой пример: Куча либ позволяет принимать в себя как тип T, так и Array<T>, а внутри уже T приводится к [T]. Даже если специальная функция в npm: arraify. Но, заставив пользователя писать не foo(x), а foo([x]) мы бы сэкономили и на размере либы, и на упрощении контракта.
Вывод: все приведения типов должны быть снаружи библиотеки, а не внутри. Делайте апи максимально скудным. Это очень упрощает жизнь и в тестах, и в реальной жизни
Полушка. Обновляйте библиотеки и меняйте устаревшие решения на современные. Аксиос для тестирования в браузере использует karma + jasmine. А для того чтобы отслеживать запросы, они мокают xmr. Ну, это хорошее решение, пока у нас не появился второй примитив для отправки запросов. А сейчас нормальным решением является какой-нибудь playwright, который через вебдрайвер уже получает информацию о запросах от браузера, а не с помощью моков конкретной стуруктуры. В итоге из-за кривых тестов мне для проверки своей реализации нужно ещё переписать тесты
Четвертушка. РАЗНЫЕ ТЕСТЫ НА РАЗНЫЕ ОКРУЖЕНИЯ. axios - делаем запросы по-разному. Я не знаю что в голове у людей, которые пилят аксиос, но у них 2 набора тестов: для ноды и не для ноды. Причём это РАЗНЫЕ ТЕСТЫ. Они не пересекаются. И дело не в моках. Я проверял. Тесты реально разные и проверяют разную логику. Axios - библиотека, которая работает по-разному в разных окружениях. Велкоме.
Так и живём...
Telegram
Андруша пишет код
Уродливое, но родное
В прошлой заметке я попытался показать почему редакс, по-моему мнению, плох. Существуют даже конкуренты. И их много. И они неплохи на фоне редакса.
Конкуренты:
- jotai
- zustand
- mobx
- effector
- reatom
Эти все инструменты как минимум…
В прошлой заметке я попытался показать почему редакс, по-моему мнению, плох. Существуют даже конкуренты. И их много. И они неплохи на фоне редакса.
Конкуренты:
- jotai
- zustand
- mobx
- effector
- reatom
Эти все инструменты как минимум…
👍7🤡4💩1
Ожидания == реальность
Часто данный тезис неверен, но если много людей верят во что-то, то это вполне может стать правдой. Например, фондовый рынок: что-то дорожает или дешевеет, потому что люди верят, что что-то должно быть дороже или дешевле. Или люди торгуют между собой в долларах, потому что верят, что через месяц их бумажки будут что-то стоят. Поэтому будущее или ближайшее настоящее в некоторых вещах можно вполне прогнозировать по ожиданию людей, если этих людей много.
Так вот. FF мёртв, как минимум по ожиданиям разрабов. Потому что у меня нет обоснования как можно было допустить багу в такой базовой вещи как AbortController.
https://github.com/microsoft/playwright/issues/29101
Буду благодарен, если вы тоже проверите у себя эту багу, так как у меня сейчас только 1 ноут под рукой. Проверка отнимет от силы 2-3 минуты вашего времени.
Часто данный тезис неверен, но если много людей верят во что-то, то это вполне может стать правдой. Например, фондовый рынок: что-то дорожает или дешевеет, потому что люди верят, что что-то должно быть дороже или дешевле. Или люди торгуют между собой в долларах, потому что верят, что через месяц их бумажки будут что-то стоят. Поэтому будущее или ближайшее настоящее в некоторых вещах можно вполне прогнозировать по ожиданию людей, если этих людей много.
Так вот. FF мёртв, как минимум по ожиданиям разрабов. Потому что у меня нет обоснования как можно было допустить багу в такой базовой вещи как AbortController.
https://github.com/microsoft/playwright/issues/29101
Буду благодарен, если вы тоже проверите у себя эту багу, так как у меня сейчас только 1 ноут под рукой. Проверка отнимет от силы 2-3 минуты вашего времени.
GitHub
[BUG] Playwright isn't catching the `requestfailed` event in Firefox · Issue #29101 · microsoft/playwright
System info Playwright Version: [v1.41.1] Operating System: [macOS 14.2.1] Browser: [Firefox] Other info: Source code Reproduction: git clone git@github.com:XaveScor/playwright-firefox-requestfaile...
🤡3👍2💩1
https://9to5mac.com/2024/01/25/third-party-default-browsers-engines/
Раз в 10 лет ЕС кардинально меняет рынок браузеров. В 2012 ЕС убил десктопный IE, а в 2024 походу он пришёл за мобильным сафари. Тестеры поздравляю, вам чуток работы подъехало.
Раз в 10 лет ЕС кардинально меняет рынок браузеров. В 2012 ЕС убил десктопный IE, а в 2024 походу он пришёл за мобильным сафари. Тестеры поздравляю, вам чуток работы подъехало.
9to5Mac
Apple will prompt users to set default browsers and allow third-party web engines on iPhone in the EU - 9to5Mac
Apple is making major changes to how web browsers can operate on iPhone for customers in the EU. iOS 17.4...
❤4🤯2💩1
Недавно эпол частично прогнулась под ЕС в рамках сайдлоадинга https://www.macrumors.com/2024/01/25/ios-17-4-alternative-app-marketplaces-eu/ и люди опять оказались людьми:
"Почему государство указывает компаниям как вести свой бизнес? Если я захочу устанавливать приложения откуда-то снаружи, то я могу пойти на Android".
Это забавно, так как почему-то люди думают, что мир крутится вокруг них. Хотя это не так. В данном случае, почему-то никто не думает о разработчиках сервисов, которые для успеха должны иметь приложение и там, и сям. Без исключений. Но нет, второй стороны не существует, а мир крутится вокруг меня.
Эта же история напомнило мне что компании перестают быть плохими, когда достигают целей(Так как можно просто не видеть неудобную информацию). Пример прост: Амиго, Яндекс.Браузер и прочие. Де кась "эти продукты плохие, так как распространяюлись предустановками или же параллельными установками вместе с другим софтом". Возможно, открою Америку части людей: Google Chrome распространялся точно такими же методами. В 2012 году существовал сверхпопулярный продукт, которым пользовался практически каждый пользователь интернета - Abode Flash. И, не поверите, флеш устанавливал хром, если ты забывал снять галочку. Огромное количество миллионов инсталяций принесла эта "плохая" практика. И я даже не вспоминаю истории про гугл.тулбар, который устанавливался в IE вообще при любом чихе.
Эпол и Гугл вообще, кмк, стоит поставить на уровень естественных монополий, так как Android и iOS - это вещи, которые настолько сильно интегрированы в нашу жизнь, что без них жить уже невозможно. А вот пытаться их защищать, что против них делают что-то несправедливо - это уж точно.
А так же всем людям советую искать в первую очередь факты, которые не подтверждают вашу точку зрения, а опровергают. Так куда проще добраться до истины.
"Почему государство указывает компаниям как вести свой бизнес? Если я захочу устанавливать приложения откуда-то снаружи, то я могу пойти на Android".
Это забавно, так как почему-то люди думают, что мир крутится вокруг них. Хотя это не так. В данном случае, почему-то никто не думает о разработчиках сервисов, которые для успеха должны иметь приложение и там, и сям. Без исключений. Но нет, второй стороны не существует, а мир крутится вокруг меня.
Эта же история напомнило мне что компании перестают быть плохими, когда достигают целей(Так как можно просто не видеть неудобную информацию). Пример прост: Амиго, Яндекс.Браузер и прочие. Де кась "эти продукты плохие, так как распространяюлись предустановками или же параллельными установками вместе с другим софтом". Возможно, открою Америку части людей: Google Chrome распространялся точно такими же методами. В 2012 году существовал сверхпопулярный продукт, которым пользовался практически каждый пользователь интернета - Abode Flash. И, не поверите, флеш устанавливал хром, если ты забывал снять галочку. Огромное количество миллионов инсталяций принесла эта "плохая" практика. И я даже не вспоминаю истории про гугл.тулбар, который устанавливался в IE вообще при любом чихе.
Эпол и Гугл вообще, кмк, стоит поставить на уровень естественных монополий, так как Android и iOS - это вещи, которые настолько сильно интегрированы в нашу жизнь, что без них жить уже невозможно. А вот пытаться их защищать, что против них делают что-то несправедливо - это уж точно.
А так же всем людям советую искать в первую очередь факты, которые не подтверждают вашу точку зрения, а опровергают. Так куда проще добраться до истины.
MacRumors
iOS 17.4 Introduces Alternative App Marketplaces With No Commission in EU
Apple today announced major changes to its app ecosystem in the European Union, implementing updates that will allow iPhone and iPad users to...
👍8🤡6💩1
Forwarded from UX Live 🔥
Это просто ОХУЕННО!
Жаль не знаю даже имени этого героя из комментариев который придумал этот метод, но это фантастически быстро и удобно!
Создал пустую группу сейчас
Запустил стрим внутри неё
Включил запись экрана и выбрал окно
Файлик с видео просто упал в сохраненки
Please open Telegram to view this post
VIEW IN TELEGRAM
🤡7💩1
Interop 2024
В девяностые и нулевые были войны браузеров, когда каждый придумывал свои стандарты, который позволяли делать веб лучше, функциональнее, удобнее. Но это привело к огромной проблеме: такое понятие как кроссбраузерность было редкостью. В десятые ситуация стала куда лучше, так как разработчики браузеров стали общаться и несовместимости почти пропали. Но почти - это не полностью.
Веб стал настолько огромным, что невозможно уследить за всем, чтобы всё было одинаково. Но мы живём уже в двадцатых. И появился новый проект: Interop xxxx. И уже было 3 итерации 2021, 2022, 2023. И каждый год браузеры выбирают сферу, в которой они унифицируют своё поведение. И самое клёвое в этом проекте, что это не какой-то caniuse с просто написанной статистикой. Это набор тестов, которые непредвзяты и каждый может проверить работает ли та или иная штука в браузере и появилась ли деградация.
И вот настал 2024, а значит пора ставить новые цели. И цели были поставлены: https://hacks.mozilla.org/2024/02/announcing-interop-2024/. Так же в конце статьи вы можете увидеть ссылки на других вендоров, которые описали собственный взгляд на этот проект.
Самое удивительное для меня в Interop XXXX то, что в него вписалась Apple. А значит жить нам будет куда проще.
Текущую статистику вы можете увидеть тут: https://wpt.fyi/interop-2024?stable
В девяностые и нулевые были войны браузеров, когда каждый придумывал свои стандарты, который позволяли делать веб лучше, функциональнее, удобнее. Но это привело к огромной проблеме: такое понятие как кроссбраузерность было редкостью. В десятые ситуация стала куда лучше, так как разработчики браузеров стали общаться и несовместимости почти пропали. Но почти - это не полностью.
Веб стал настолько огромным, что невозможно уследить за всем, чтобы всё было одинаково. Но мы живём уже в двадцатых. И появился новый проект: Interop xxxx. И уже было 3 итерации 2021, 2022, 2023. И каждый год браузеры выбирают сферу, в которой они унифицируют своё поведение. И самое клёвое в этом проекте, что это не какой-то caniuse с просто написанной статистикой. Это набор тестов, которые непредвзяты и каждый может проверить работает ли та или иная штука в браузере и появилась ли деградация.
И вот настал 2024, а значит пора ставить новые цели. И цели были поставлены: https://hacks.mozilla.org/2024/02/announcing-interop-2024/. Так же в конце статьи вы можете увидеть ссылки на других вендоров, которые описали собственный взгляд на этот проект.
Самое удивительное для меня в Interop XXXX то, что в него вписалась Apple. А значит жить нам будет куда проще.
Текущую статистику вы можете увидеть тут: https://wpt.fyi/interop-2024?stable
Mozilla Hacks – the Web developer blog
Announcing Interop 2024
Following the success of Interop 2023, we are pleased to confirm that the project will continue in 2024 with a new selection of focus areas.
👍4❤1💩1
https://twitter.com/Hinkali4/status/1753172405260812770
Почему-то в 2024 году люди всё ещё не научились в цифровую гигиену.
Делюсь великим секретом: не смешивайте работу и личную жизнь. Максимально разграничивайте их. На работе старайтесь пользоваться исключительно рабочими мессенджерами(Slack, MS Teams, etc.). Если работа лезет в телегу(привет, Яндекс!), то не поленитесь и заведите отдельный рабочий аккаунт. К примеру, у меня это @XaveScorWork.
И в таком случае у вас не будет никаких проблем в коммуникации. У вас будет возможность просто взять и отключить во внерабочее время все способы связи.
Но если и после подобных вещей вам будут пытаться долбиться по личным контактам по несрочным вопросам, то только в таком случае я могу присоединиться к вашему негодованию.
Если опустить вопрос коммуникации, то я так же советую вам обзавестись отдельным рабочим оборудованием, отдельным календарём, отдельной почтой и отдельным всем-всем-всем. Не надо работать с устройств и аккаунтов, где вы держите личные данные. Смешивание работы и личной жизни - цэ мэрзость. Цэ рэально мэрзость. Чем дальше будет ваша работа от вашей личной жизни, тем лучше вы будете себя чувствовать.
Почему-то в 2024 году люди всё ещё не научились в цифровую гигиену.
Делюсь великим секретом: не смешивайте работу и личную жизнь. Максимально разграничивайте их. На работе старайтесь пользоваться исключительно рабочими мессенджерами(Slack, MS Teams, etc.). Если работа лезет в телегу(привет, Яндекс!), то не поленитесь и заведите отдельный рабочий аккаунт. К примеру, у меня это @XaveScorWork.
И в таком случае у вас не будет никаких проблем в коммуникации. У вас будет возможность просто взять и отключить во внерабочее время все способы связи.
Но если и после подобных вещей вам будут пытаться долбиться по личным контактам по несрочным вопросам, то только в таком случае я могу присоединиться к вашему негодованию.
Если опустить вопрос коммуникации, то я так же советую вам обзавестись отдельным рабочим оборудованием, отдельным календарём, отдельной почтой и отдельным всем-всем-всем. Не надо работать с устройств и аккаунтов, где вы держите личные данные. Смешивание работы и личной жизни - цэ мэрзость. Цэ рэально мэрзость. Чем дальше будет ваша работа от вашей личной жизни, тем лучше вы будете себя чувствовать.
X (formerly Twitter)
Hinkali (@Hinkali4) on X
Ну не сдержалась я до завтра
Я в ахуе просто
Руководитель мечты, блять
Я в ахуе просто
Руководитель мечты, блять
👍4💩2
Ну, время написать что-нибудь и о программировании. Сейчас я занимаюсь рефакторингом одной нашей внутренней библиотеки, вторая версия которой будет иметь куда более удобный, как нам кажется, интерфейс.
Но есть 2 важных НО:
1) нужна совместимость со старым контрактом
2) либа принимает на вход функции из кодгена, и для комфорта разрабов кодген должен корректно приниматься как старой версией либы(для обратной совместимости), так и новой(для нового кода).
И из второго пункта появляется очень большая засада: нам нужно сохранить как-то типы, которые либа выводит из кодгена, а TS не имеет механизмов сохранения одного типа внутри другого.
Другими словами:
https://www.typenoscriptlang.org/play?#code/C4TwDgpgBAgswEMDGALAjAHgAoBooA0A+KAXiiwChRIoBRAD2ACdlhMZiyYoJGIA7ACYBnWPGToMCfiDwBLfgDMITAsQD8BKAC4o-CADcVAbgpnq0OIlQRBaUmOuSA3gl38ArgFsARioC+eMLMCgDmhKYWdIwsSMC29mQMzKzs4jZ2EVAA9NlQHvwA1vwA9gDu-BRAA
Но если добавить ограничения, что тип
https://www.typenoscriptlang.org/play?#code/C4TwDgpgBAgswEMDGALATAHgApQgD2AgDsATAZygHsAjAKwiWABooANAPigF4ocAyKAG8A+qLAAnAJYA3BIQD8ALjYBfAFChIUAKIFxyYJhiceMXAWLlY8ZOgw16jFpKIAzCOLad5bKMqIQ0h4A3GphmtBwiKgQJGjc1tF2ggj+AK4AttQeKixkwFJEAObsoRE6egax8Ty6BQZGNjFxpVAA9G1Q+YVFakA
Да, это некрасиво и ts будет показывать внутреннее поле. Но в рантайме можно туды ничего не класть и тогда всё будет типа ок. Кмк, для обратной совместимости с кривыми контрактами, вполне хорошее решение. У нас в библиотеке этот способ позволяет на уровне кодгена запихивать в типы любую дичь, которую можно потом достать из слоя обратной совместимости
Но есть 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 будет показывать внутреннее поле. Но в рантайме можно туды ничего не класть и тогда всё будет типа ок. Кмк, для обратной совместимости с кривыми контрактами, вполне хорошее решение. У нас в библиотеке этот способ позволяет на уровне кодгена запихивать в типы любую дичь, которую можно потом достать из слоя обратной совместимости
www.typenoscriptlang.org
TS Playground - An online editor for exploring TypeScript and JavaScript
The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.
👍4💩2
Даже jquery выпускает новые релизы https://blog.jquery.com/2024/02/06/jquery-4-0-0-beta/
А реакт все сидит на версии 18.2.0
А реакт все сидит на версии 18.2.0
Jquery
jQuery 4.0.0 BETA! | Official jQuery Blog
jQuery: The Write Less, Do More, JavaScript Library
😁13💩2🔥1
Если внезапно вам приспичит верстать письма, то есть супер дока по поддерживаемым фичам webview в разных почтовых клиентах
https://www.caniemail.com
https://www.caniemail.com
Caniemail
Can I email…
Support tables for HTML and CSS in emails
👍7✍1💩1
Вчера мне для кодгена нужно было генерировать цепочку выражений для ts:
Пустой объект был нужен, так как
Но вот какая засада:
Но есть пакет, содержащий утилити типы, которые работают так как вы ожидаете: https://github.com/sindresorhus/type-fest
К примеру, пустой объект тут выглядит уже нормально https://github.com/sindresorhus/type-fest/blob/main/source/empty-object.d.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
Не горячо, но советую. Упрощает жизнь, так как можно забыть о тупняках тайпскрипта.
GitHub
GitHub - sindresorhus/type-fest: A collection of essential TypeScript types
A collection of essential TypeScript types. Contribute to sindresorhus/type-fest development by creating an account on GitHub.
👍3😈3💩2
Сейчас каждый фронтенд разраб знает об nvm. О тулзе, которая позволяет очень просто устанавливать почти любую версию ноды, но не каждый читает доку к nvm.
А если почитать доку, то можно там найти сверхудобную автоматизацию https://github.com/nvm-sh/nvm?tab=readme-ov-file#deeper-shell-integration
Она позволяет автоматически включать нужную версию ноды, в зависимости от директории, которая сейчас открыта. Вы можете не переключаться каждый раз руками через
#база
А если почитать доку, то можно там найти сверхудобную автоматизацию https://github.com/nvm-sh/nvm?tab=readme-ov-file#deeper-shell-integration
Она позволяет автоматически включать нужную версию ноды, в зависимости от директории, которая сейчас открыта. Вы можете не переключаться каждый раз руками через
nvm use#база
GitHub
GitHub - nvm-sh/nvm: Node Version Manager - POSIX-compliant bash noscript to manage multiple active node.js versions
Node Version Manager - POSIX-compliant bash noscript to manage multiple active node.js versions - nvm-sh/nvm
👍15👎2🔥2💩1🤡1
Андруша пишет код
Сейчас каждый фронтенд разраб знает об nvm. О тулзе, которая позволяет очень просто устанавливать почти любую версию ноды, но не каждый читает доку к nvm. А если почитать доку, то можно там найти сверхудобную автоматизацию https://github.com/nvm-sh/nvm?tab=readme…
В комментариях подсказали более лучшее решение. https://github.com/Schniz/fnm как минимум в том, что оно тупо удобнее. Не нужно руками ставить нужную версию ноды.
Жить стало ещё чуть проще.
Жить стало ещё чуть проще.
👍5💩3
Не так давно мой хороший знакомый https://news.1rj.ru/str/kelin2play/573 задал простой вопрос: как подчистить ненужный мусор со своего компьютера.
Очевидное решение для меня - windirstat, но в комментариях подсказали ещё wizTree.
На примере этих продуктов можно проследить какая пропасть в между современными продуктами и хорошим маркетингом: на странице windirstat на первом же экране понимаешь как хорошо эта программа решает вашу проблему. У wizTree же - куча текста, в который надо вчитываться. И даже пролистывание главной не помогает.
Если вы в компании верстаете или дизайните вашу продающую страницу, то пытайтесь вмешиваться и не делать так как сделано у wizTree. Я, лично, ненавижу вчитываться в километры текста, когда вижу что-то новое. Да и никто не любит. Это сложно.
Очевидное решение для меня - windirstat, но в комментариях подсказали ещё wizTree.
На примере этих продуктов можно проследить какая пропасть в между современными продуктами и хорошим маркетингом: на странице windirstat на первом же экране понимаешь как хорошо эта программа решает вашу проблему. У wizTree же - куча текста, в который надо вчитываться. И даже пролистывание главной не помогает.
Если вы в компании верстаете или дизайните вашу продающую страницу, то пытайтесь вмешиваться и не делать так как сделано у wizTree. Я, лично, ненавижу вчитываться в километры текста, когда вижу что-то новое. Да и никто не любит. Это сложно.
👍5💩3
Попробую вам сегодня продать GitHub Copilot. Эта штука всё же сносит мозг даже после года использования.
Главная вещь: правильно описанные типы позволяют почти не писать логику вовсе. Copilot реально понимает что тебе надо. Да, этот код нужно чуток подрихтовать, но даже в таком виде его спокойно можно отправлять в прод.
Главная вещь: правильно описанные типы позволяют почти не писать логику вовсе. Copilot реально понимает что тебе надо. Да, этот код нужно чуток подрихтовать, но даже в таком виде его спокойно можно отправлять в прод.
👍7🍌1
React.memo и React.forwardRef - это постоянная заноза в заднице с точки зрения типов, если вы в проекте используете TS.
И о решении одной из этих заноз написал https://news.1rj.ru/str/ru_react_notes/404
Подобное решение может казаться верным, но только в случае если вы не понимаете как работает React.forwardRef. Потому что React.forwardRef возвращает ОБЪЕКТ. Да, можно много рассуждать верно или нет это с точки зрения архитектуры, но имеем что имеем.
А в предложении поста говорится "а давайте обманём рантайм и скажем, что возвращается функция".
Не обманывайте себя. Да, кажется, что это необходимое зло, но это не так. Простой пример. Вы рефакторите уже существующий компонент и хотите добавить к нему ref. И вот тут вы не можете гарантировать, что его не вызывают как функцию. Потому что, увы, это так. В проектах куча говна, в котором встречается любой код, который не запрещён ESLint'ом. А и запрещённый им тоже есть.
Поэтому максимальными силами старайтесь сохранять все инварианты существующего кода.
По этой причине более корректным решением будет
Как минимум потому что все вызовы компонента напрямую продолжат корректно вызываться.
И о решении одной из этих заноз написал 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} />
}
}
Как минимум потому что все вызовы компонента напрямую продолжат корректно вызываться.
Telegram
Заметки про React
Как использовать forwardRef с generic компонентами
Одно из ограничений forwardRef в том, что он отключает выведение типа для generic компонентов. Например:
const Table = <T,>(
props: {
data: T[];
renderRow: (row: T) => React.ReactNode;
},
…
Одно из ограничений forwardRef в том, что он отключает выведение типа для generic компонентов. Например:
const Table = <T,>(
props: {
data: T[];
renderRow: (row: T) => React.ReactNode;
},
…
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 раз всё-таки пригодилось.
Пара примеров того к чему может привести немонотонность времени - в комментариях.
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 раз всё-таки пригодилось.
Пара примеров того к чему может привести немонотонность времени - в комментариях.
Главные новости Казахстана - Tengrinews.kz
Казахстан переходит на единое время: кто и когда должен перевести стрелки: 16 февраля 2024, 20:00 - новости на Tengrinews.kz
Tengrinews.kz ▶ Казахстан переходит на единое время: кто и когда должен перевести стрелки: 16 февраля 2024, 20:00 ▶ Читать подробнее актуальные новости и события на сайте.
🔥3👍2