cherkashin.dev @cherkashindev Channel on Telegram

cherkashin.dev

@cherkashindev


Александр Черкашин. Бойскаут, Борец с перфекционизмом.

Фулстек разработчик в decisions.com. Работаю со стеком TypeScript, React, C#

Пишу о программировании и не только.

LinkedIn: www.linkedin.com/in/cherkalexander
Блог: https://cherkashin.dev

cherkashin.dev (English)

Are you a tech enthusiast looking to stay updated with the latest trends and developments in the world of software development? Look no further than cherkashin.dev - a Telegram channel curated by the talented developer behind the username @cherkashindev. This channel is your one-stop destination for all things related to software development, coding tips, and programming tutorials. Whether you are a seasoned developer or just starting your coding journey, cherkashin.dev has something for everyone. Join now to connect with like-minded individuals, share your knowledge, and level up your coding skills. Stay ahead of the curve with cherkashin.dev!

cherkashin.dev

13 Jan, 10:09


🗂️Папка с Курскими ИТ-каналами

В прошлом году решил, что было бы неплохо собрать все Курские ИТ каналы в одну папку, и вот что получилось

👉 https://t.me/addlist/CcKwwK_1G9AxMjEy

Даже если вы не из Курска — обязательно добавляйте папку, точно найдёте для себя что-то интересное.

Пара слов о каждом:

@cherkashindev — это собственно я, пишу в основном о вебе, GTD и иногда о C#

@polovnyov_journal — Вася - техдир в Бюро Горбунова, пишет о разработке, тестировании и рабочих процессах

@rich_developer — Саша - CEO в HaaS Platform, пишет про найм, поиск работы и публикует вкусные вакансии

@andvink — Андрей пишет про ИИ и автоматизацию разработки. Сменил стек с веба на ML

@likelivinghere — Виталик - QA Lead, пишет о стендапе, релокации и возвращении в Россию

@tony_malyshev — Антон пишет об аналитике, маркетинге и нейросетях

@gameFromTheInside — Кирилл пишет о разработке игр, в прошлом году опубликовал "Танки 3D: Дикая арена" в Яндекс Играх

@kavyrshing — Саша пишет про около-айти, аджайл и коучинг

Если кого-то упустил, то обязательно пишите — добавлю

👉 Папка - ИТ Курск

cherkashin.dev

10 Jan, 07:12


React приложение без сборщиков

Иногда нужно набросать небольшой пример или демку на реакте, но не хочется создавать новый проект, где установится +100500 пакетов. Создавать проект в песочнице типа codesandbox тоже лень. Есть вариант попроще:

1️⃣ Подключаем react и react-dom через CDN


<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>


2️⃣ Подключаем babel через CDN


<script src="https://unpkg.com/@babel/standalone/babel.min.js">


3️⃣ Добавляем root


<div id="root"></div>


4️⃣ Добавляем script с типом "text/babel", внутри которого мы можем использовать JSX


<script type="text/babel"></sciprt>


Получаем следующий код


<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React Without Bundler</title>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>

<body>
<div id="root"></div>
<script type="text/babel" defer>
function App() {
const [count, setCount] = React.useState(0);

return (
<div style={{ textAlign: "center", marginTop: "50px" }}>
<h1>Счётчик: {count}</h1>
<button onClick={() => setCount(count - 1)}>-</button>
<button onClick={() => setCount(0)} style={{ margin: "0 10px" }}>
Сброс
</button>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
};


ReactDOM.createRoot(document.getElementById("root")).render(<App />);
</script>
</body>

</html>


5️⃣ Для максимальной простоты — создаём сниппет в VS Code

👉 CMD + SHIFT + P > Configure Snippets > New Global Snippets file и вставляете туда


{
"React Without Bundler HTML": {
"prefix": "react-html",
"scope": "html",
"body": [
"<!DOCTYPE html>",
"<html lang=\"en\">",
"",
"<head>",
" <meta charset=\"UTF-8\">",
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">",
" <title>React Without Bundler</title>",
" <script src=\"https://unpkg.com/react@18/umd/react.development.js\"></script>",
" <script src=\"https://unpkg.com/react-dom@18/umd/react-dom.development.js\"></script>",
" <script src=\"https://unpkg.com/@babel/standalone/babel.min.js\"></script>",
"</head>",
"",
"<body>",
" <div id=\"root\"></div>",
" <script type=\"text/babel\" defer>",
" const { useState } = React;",
"",
" function App() {",
" const [count, setCount] = useState(0);",
"",
" return (",
" <div style={{ textAlign: \"center\", marginTop: \"50px\" }}>",
" <h1>Счётчик: {count}</h1>",
" <button onClick={() => setCount(count - 1)}>-</button>",
" <button onClick={() => setCount(0)} style={{ margin: \"0 10px\" }}>",
" Сброс",
" </button>",
" <button onClick={() => setCount(count + 1)}>+</button>",
" </div>",
" );",
" };",
"",
" ReactDOM.createRoot(document.getElementById(\"root\")).render(<App />);",
" </script>",
"</body>",
"",
"</html>"
],
}
}


#react #vscode

cherkashin.dev

08 Jan, 16:22


Выходные пролетели, как обычно! Успели отдохнуть?

Я первую половину выходных батонился на кровати и смотрел сериалы, а вторую гулял по Владимиру и Суздали.

Во время поездки погода была отличная — на несколько дней ударил мороз, и удалось насладиться зимой, которая в Курск заглядывает всё реже (сегодня +6).

Суздаль — это что-то особенное, словно русская сказка оживает наяву:
- Около 50 церквей на небольшой городок — удивительное ощущение духовности.
- Старинные дома в центре с резными наличниками и деревянными воротами — будто из прошлого века.
- Лошади с санями, неспешно везущие туристов, — атмосфера уюта и зимнего волшебства.

Теперь как-то нужно вырваться туда летом ...

#travelling@cherkashindev

cherkashin.dev

31 Dec, 11:47


Декабрь подходит к концу, поэтому пора подводить итоги года, в котором было немало как хорошего, так и плохого.

Начнём с хорошего:

🔥 В этом году старался доделать то, что долгое время откладывал:

- вычистил небольшой техдолг на работе, который обсуждали несколько лет
- написал статью о нашем опыте миграции на Реакт 
- дописал тулзу для анализа код-ревью и подготовил внутренний доклад
- договорился о еженедельных созвонах для фронтендеров, чтобы шарить знания 
- перевёл блог с Jekyll на Astro

🏡 Съездил с отцом в Москву. Показать ему как она изменилась за последние 20 лет.

🇮🇳 Слетал на недельный тимбилдинг в Индию. В очередной раз понял, что удалёнка — это очень удобно, но когда вы знакомы с людьми лично — ваше общение и взаимопонимание выходит на новый уровень.

✈️ За год этот канал вырос в 4 раза, спасибо, что читаете 🫶

Посетил конференции:
- Teamly
- Впервые сходил на подлодку и получил бесплатный билет на следующую в феврале 2025
- Я 💛 Frontend
- Я.Субботник в Москве и Питере


Путешествия:
- 🇷🇺 Сочи, Москва, Питер, Липецк, Воронеж, Ростов-на-Дону
- 🇪🇬 Шарм, Каир
- 🇮🇳 Мумбаи


И ещё немного:
🪚 Наконец-то сделал ремонт на балконе
💪 Начал ходить в зал
🎾 30 тренировок по теннису
🇬🇧 25 уроков английского
🎙️ Дал небольшое интервью
🏃🏼‍♂️ Пробежал ещё один полумарафон
🧑‍🏫 Провел 13 ментор сессий
💻 Чуть не потерять ноут в Каире
🚀 Летел 2 дня из Каира в Мумбаи с 2-мя пересадками
💎 Переехал с Notion на Obsidian
🎭 Сходил на Лебединое Озеро в Москве
🥃 Прошелся по барам в Питере


Не обошлось и без ложки дёгтя:

🕵️‍♂️ Первое написанное заявление в прокуратуру. Оказывается у нас в стране очень просто взять деньги и не возвращать. Достаточно просто не иметь имущества, чтобы с тебя нечего было взять.

🚨 Шокирующие события августа и участившиеся сирены за окном. Нашел фото рабочего места в коридоре.


Самое главное, чему научил 2024 год — ценить то, что у нас есть. То что кажется данностью, очень просто может исчезнуть.

Всех с наступающим новым годом! 🎉 🎄❄️☃️🌨️

#newyear #итогигода

cherkashin.dev

23 Dec, 10:02


Когда говорят об истории JavaScript часто упоминают, каким незаменимым он был при украшении сайтов снежинками ❄️ в канун Нового года 🎄.

А между тем, Новый год уже на следующей неделе, поэтому пора поспешить и принарядить свои сайты.

🗣️ Я попросил ChatGPT:
- на основе существующего логотипа сгенерировать новогодний
- написать код для реализации тех самых снежинок

Я сравнил код ChatGPT с кодом из статьи Доки "Снежинки" от Алёны Батицкой, взял от обоих решений лучшее, и вот что получилось.

✍️ Кратко о реализации:
- Берём символы Unicode для снежинок — ❅ ❆
- В разметке создаём нужное количество снежинок — у меня 120
- Каждая снежинка состоит из 2-х частей
- контейнер — для анимации падения
- сама снежинка — для анимации поворота
- Все снежинки кладём в один контейнер и выставляем ему pointer-events: none, чтобы не мешать взаимодействию со страницей
- Контейнеру выставляем flex-direction: row, чтобы равномерно распределить снежинки по экрану
- Начальное и конечное положения снежинок находится немного за пределами экрана, чтобы они плавно появлялись и исчезали
- Выставляем случайным образом:
- размер снежинок (`font-size`) — от 0.7em до 1.5em
- длительность анимации падения — от 10 до 30 секунд
- задержку анимации — от 1 до 30 секунд
- Задержка анимации нужна, чтобы снежинки падали постепенно
- Выставляем разные цвета снежинок

- Исходники здесь 💾
- Демо здесь 🖥️

@cherkashindev

#newyear #blog

cherkashin.dev

20 Dec, 07:42


Я давно не рекомендовал ничего почитать, но эта короткая статья не оставила меня равнодушным.

"Всего несколько строк CSS для плавных переходов между страницами"
- перевод на хабре
- оригинал

Я много раз слышал, про View Transitions API и о том, что теперь можно настраивать анимации перехода между страницами, но никогда не пробовал.

В статье автор предлагает сделать переходы между страницами плавными с помощью одной строчки кода.


@view-transition { navigation: auto; }


Чтобы понять о чём говорит автор просто посмотрите прикреплённое видео:
- или откройте оригинал статьи и воспроизведите видео
- или же откройте мой блог и попробуйте перейти на одну из последних статей

В SPA приложениях также есть возможность использовать View Transitions API. Можете посмотреть демки в статье: "Введение в View Transitions API". Анимация реализуется с помощью startViewTransition


document.startViewTransition(() => updateTheDOMSomehow());


При использовании View Transitions API происходит следующее:
- делается снимок текущего состояния страницы
- выполняется обновление DOM (updateTheDOMSomehow)
- делается снимок нового состояния страницы
- переход между этими состояниями анимируется с помощью дефолтного плавного затухания или с помощью кастомной анимации


Более сложные примеры можно узнать отсюда:
- The View Transitions API And Delightful UI Animations (Part 1)
- The View Transitions API And Delightful UI Animations (Part 2)
- Никита Дубко. По-настоящему красивые переходы средствами браузера

Для блогов на Astro:
- Документация View Transitions в доке Astro
- Как починить темную и светлую темы после внедрения view transitions — читать тут

#frontend #fridayreading

@cherkashindev

cherkashin.dev

17 Dec, 07:15


В прошлом году я каким-то образом умудрился написать 6 статей. В этом же с трудом нашел силы на одну — Как мы мигрируем с JQuery на React.

Во время миграции мы столкнулись со многими трудностями, поэтому я решил описать наш подход в виде статьи.

Из статьи вы узнаете:

1️⃣ как мы писали код до React
2️⃣ какой подход мы выбрали для миграции
3️⃣ как нам мешали пространства имён тайпскрипта
4️⃣ как конфигурировали webpack
5️⃣ что делать, если нужно использовать легаси код внутри React
6️⃣ как мы писали кастомный генератор типов
7️⃣ почему выбрали Zustand для управления состоянием

Обязательно переходите и читайте.
Буду признателен если сделаете репост или проголосуете за статью на Хабре, это поможет её продвижению 🔥. Кто-то поставил минус за обложку статьи, так что спасайте 😄

#article #react #habr

cherkashin.dev

12 Dec, 09:27


Программа на эти выходные. Попал сразу на оба мероприятия оффлайн 🔥.

#conference

cherkashin.dev

05 Dec, 12:57


В прошлом году мы с женой летали в Стамбул, но запомнил я от силы процентов 10. Фото есть, но хочется запомнить и свои ощущения. В этот раз в Египте я стал делать заметки, и вот дошли руки собрать из них что-то читаемое.

Про почти потерянный ноут вы уже читали 😅.

🧳 Подготовка

Отпуск был запланирован на конец сентября. Обычно на море мне становится скучно через пару дней (но не в этот раз!), поэтому я стараюсь выехать на несколько дней в город.

Решили ехать в:
- Шарм-эль-Шейх
- и Каир

🛩️ План: Москва — Шарм — Каир — Москва

Билеты "Москва — Шарм" на двоих - 100к 😳. Тур туда/обратно — столько же (без отеля). Поэтому мы решили взять тур и отказаться от обратных билетов. Была небольшая надежда, что туроператор вернёт деньги. Этот вариант выгорел пару лет назад в Турции, но тут систему надурить не удалось.

Итог: тур в Шарм, билеты до Каира и Москвы отдельно.

🙏 Ожидания

Я старался не строить завышенных ожиданий от поездки, особенно после того как начитался отзывов интернетных экспертов:

- Одни утверждали, что все будут стараться тебя на**ать (и были не далеки от истины)
- Вторые говорили, что сервис — отстой, а если не оставлять чаевые — то и "под дверью нагадят".

🚧 Если кратко

- Обслуживание — хорошее, под дверью пусто
- Море — пушка, маска для снорклинга — обязательно
- Шарм — класс
- Манго и еда — шик
- Пиво — пойдёт
- Вино — ужас
- Торговцы — наглые
- Для такси — InDrive

🏝️ Шарм

Добрались до отеля мы рано утром. Носильщик донёс чемодан до номера, собрался уходить, но я его остановил и всё-таки дал доллар. Ну на всякий случай.

Немного отдохнув, мы собрали вещи и пошли на пляж. Жена провела мне инструктаж, мол "рыб не трогай, к кораллам не лезь". Я надел маску и сразу полез в воду.

Открыв глаза под водой, я увидел множество рыб вокруг себя, растерялся и попытался отплыть от них в сторону. Ну и конечно же сразу влупился ногой об коралл. Я вылез на пирс, мне обработали ногу. Через 2 дня она была размером с голову, но об этом в другой раз.

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

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

В общем, море — лучшее воспоминание, которое у меня осталось.

🚶 Выходим из отеля — такси и продавцы

Вызвали Такси. Цена в приложении — 105 фунтов. По совету интернетных экспертов уточняю цену до поездки, на что таксист говорит, что это копейки и поедет только за 150. Ок, сторговались на 120.

Едем минут 10, и таксист говорит:
— Слушай, Мухамед (он) - хороший, машина - хороший, ставь мне 5 звёзд
— Да, конечно, обязательно поставлю (нет)
— Ставь, сейчас!

Я немного офигел от наглости, InDrive похоже тоже офигел, заглючил и отрубился.

Доезжаем до Наама Бей. К нам подходит мужчина и говорит, что ещё очень рано и всё закрыто. Мы спросили, где находится аптека и он предложил нас проводить. Слово за слово, и он заводит нас в лавку с маслами. Это — его лавка, он начинает нам показывать сколько у него отзывов, мол купите что-нибудь и идите в аптеку, или хотя бы отзыв оставьте.

Я офигел от наглости 2 раз за 10 минут и игнорил торговцев весь отпуск 😄.

🛬 Вылет в Каир

Мы отлично отдохнули в Шарме и поехали в Аэропорт.

Здесь меня удивило, что на входе была огромная очередь на досмотр, а рядом ещё одна небольшая очередь для тех, кто дал на лапу, чтобы пройти без очереди.

Дать на лапу тебя не навязчиво попросят прямо сотрудники аэропорта, которые очень хотят, чтобы ты сэкономил 10 минут фунтов за 300. В остальном — всё как в обычном аэропорте.

----

На сегодня всё. Шукран, что дочитали 👋.
А где вы провели последний отпуск

@cherkalexander

cherkashin.dev

02 Dec, 08:01


В прошлом месяце я писал, что постепенно пытаюсь оживить свой блог и переписываю его на Astro.

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

В этот раз я подумал, что "Лучшее — враг хорошего." и решил, что для блога будет достаточно MVP:
- Перенёс все статьи
- Добавил секцию с проектами
- Поправил стили

Далее в планах:
- Прикрутить комментарии
- Опубликовать CV
- Реализовать кнопку Share
- Добавить какую-нибудь пасхалку в консоль, куда ж без этого. Есть идеи? 😄

Кстати, если вы переписываете блог, не забудьте убедиться, что ссылки на ваши старые статьи работают. Например, у Jekyll и Astro — разные форматы URL, поэтому чтобы старые ссылки не сломались нужно использовать редиректы:

//astro.config.mjs

export default defineConfig({
redirects: {
'/old-page': '/new-page'
}
});


P.S. Если знаете, как прикрутить комментарии и реакции для блога — расскажите в комментариях 👇.

Ссылка на блог

@cherkashindev

#блог #astro

cherkashin.dev

21 Nov, 08:39


Сейчас темп жизни такой, что на всё не хватает времени. И чтобы сэкономить время на уборке, в прошлом году я раскошелился и решил заменить свой старый робот-пылесос Xiaomi (который штурмовал каждую неровность) на новый, более современный.

После просмотра кучи обзоров остановился на DreamBot L10s Ultra. Если кратко о его использовании:
- чистой воды налил
- грязную вылил
- мешок для мусора вставил (раз в пол года)
а дальше он все сам:
- воды наберет
- мусор выгрузит
- даже тряпки сам помоет и высушит.

В общем, чая навели, пылесос включили и пошли на стендап.

---

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

О продукте:
- Продукт для мониторинга упоминания компаний в соц сетях. 
- Задача продукта – с помощью AI помочь бизнесу упростить процесс маркетинговых исследований для понимания и управления репутацией своих продуктов.

О позиции:
- требуется Senior Frontend разработчик 
- стек — React, TypeScript, Next.js
- опыт разработки интерактивных дашбордов
- зарплата ~$5000
- удаленка, гибкий график
- разные варианты трудоустройства
- хороший английский

Полное описание вакансии и как откликнуться — в комментарии к посту, если что-то непонятно пишите в личку @cherkalexander.

#about_me #вакансия

cherkashin.dev

18 Nov, 07:55


return Promise 🆚 return await Promise

Что будет выведено в консоль?


async function test1() {
console.log('start-1');
return Promise.resolve();
}

async function test2() {
console.log('start-2');
return await Promise.resolve();
}

test1().then(() => console.log('done-1'));
test2().then(() => console.log('done-2'));

console.log('end');


@cherkashindev

#typescript

cherkashin.dev

15 Nov, 08:23


// @ts-nocheck

Помню, когда я только начал изучать TypeScript, мне часто попадалась фраза: "TypeScript — это надмножество JavaScript, и любой корректный JavaScript-код является также корректным TypeScript-кодом". В общем, если надоел JavaScript — меняешь расширение файла с .js на .ts и радуешься жизни (или нет).

Вчера поздним вечером я копался в нашем легаси, некоторому коду лет 10, а то и больше. И я вспомнил, как лет 6 назад менял расширение этих файлов на .ts.

У нас на проекте тогда уже использовался TypeScript, но был и пласт легаси на чистом JavaScript. Я попробовал переименовать их в .ts, и тут весь файл стал огненно красным. Не всё так просто, как говорили эксперты.

Но в версии 3.7 TypeScript появилась директива // @ts-nocheck. Просто добавляешь её в начале файла, и проверка типов отключается, и можно постепенно мигрировать на TS.

Потом переписывать их на TS, конечно же, никто не собирался 😄

#typescript

cherkashin.dev

07 Nov, 10:03


Я уже года 4 плачу за свой домен cherkashin.dev, где хостится мой мертвый и убогий блог, который я сделал во время ковида, и с тех пор ни разу не трогал. В то время я не слышал про 11ty, а Astro ещё не появился. ChatGPT тоже ещё не было, поэтому — я погуглил, поспрашивал знакомых и взял Jekyll.

GitHub Pages, насколько я помню, неплохо дружат с Jekyll, я взял какой-то простенький шаблон для быстрого старта и опубликовал блог. Но Jekyll написан на Ruby, а это значит, что придётся постоянно сталкиваться с ним для настройки и билда блога, поэтому я быстро забил. 

Этим летом я сходил на конфу подлодки и узнал про Astro. Нашёл темплейт и потихоньку мигрирую. На скрине текущее состояние блога.

Кстати, если вы используете Astro и вам нужна аналитика, то @xufostation есть Astro плагин для Яндекс Метрики. У плагина пока мало звезд — поэтому давайте исправим это. Нам не сложно, а автору будет приятно.

https://github.com/ufocoder/astro-yandex-metrika

#блог #astro

@cherkashindev

cherkashin.dev

31 Oct, 09:01


✉️ Реализация инбокса в Obsidian с помощью Apple Shortcuts

Те, кто давно на меня подписан могут помнить, что я рассказывал как настроить Inbox для Notion с помощью Apple Shortcuts (тут и тут).

Если кратко — Apple Shortcuts позволяет делать автоматизации, которые, например, можно запускать нажатием на ярлык. Для Notion автоматизация была простая:
- Показывается текстовое поле
- Мы вводим свою заметку
- Вызывается API Notion и заметка добавляется в базу данных Inbox

Когда я начал мигрировать на Obsidian, всё это конечно перестало работать. Казалось, что придётся делать заметки в Apple Notes а затем ручками переносить всё в Obsidian.

Но после того, как настроил интеграцию Obsidian с GitHub понял, что можно добавлять заметки напрямую в GitHub репозиторий через GitHub API.

И это сработало, пришлось лишь сильно поменять реализацию шортката. Теперь это работает так:
- Показывается текстовое поле
- Мы вводим текст заметки
- Он кодируется в base64, так требует GitHub API
- Получаем текущую дату, она будет являться именем заметки
- Формируем URL для создания файла в репозитории — https://api.github.com/repos/{owner}/{repo}/contents/{path}
- Отправляем запрос, предварительно нужно сгенерировать GitHub Access Token.
- При открытии Obsidian сделает pull из репозитория и заметка отобразится в папке Inbox, или можно сделать pull вручную
- Готово 🚀

Позже поделюсь ссылкой на готовый шорткат, если кому-то нужно.

#obsidian #nocode #planning

@cherkashindev

cherkashin.dev

28 Oct, 08:03


Этот самурай незаметно пробрался в квартиру прошлой ночью. К счастью, мы с женой не пострадали, чего нельзя сказать о старом кресле ...

#workingplace

@cherkashindev

cherkashin.dev

18 Oct, 16:47


Выходной в Пятницу

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

В итоге:
- пересмотрел пару серий Игры престолов. Одичалые штурмуют стену, а Тириона Ланнистера хотят казнить.
- разобрал (почти) рабочий стол на ноуте
- удалил всякого мусора на 40 Гб
- съездил на теннис, зная, что мне не нужно мчаться на работу
- разобрал чеки и справки, которые лежали пару месяцев в ящике
- записался в больницу
- выставил ненужный хлам на авито
- а ещё нашел #obsidian плагин 🚀, который умеет в мультикурсор, прям как VS Code (CMD/CTRL + D), нужно только настроить горячие клавиши
- а теперь пойду забью кальян, пятница же

Жаль, что каждую пятницу так делать не прокатит 😅.

P.S. Ходят слухи, что некоторые компании практикуют 4-х дневную рабочую неделю, вы работали в таких? Или может хотя бы слышали? Куда слать резюме? 😄

UPD: ссылку на плагин добавил

#about_me

@cherkashindev

cherkashin.dev

16 Oct, 08:00


Отдельная страница для задач в Обсидиан

В 🇯🇵 Notion мне всегда очень нравилось, что каждая запись в базе - это отдельная страница, которая может содержать что угодно - от простых заметок, до вложенных баз или таблиц.

Я использовал Notion, как менеджер задач, и эта возможность была критически важной для меня - работая над сложными задачами, я всегда делаю заметки:

- разбиваю на подзадачи
- записываю нюансы, на которые я наткнулся
- помечаю, какие тесты необходимо написать

Хотя в обсидиан это не поддерживается из коробки, но всё же достаточно легко реализуется:

- Для задач использую obsidian-tasks плагин, по сути это просто ToDo лист
- Если нужно сделать много записей по задаче или приложить скриншоты - то просто превращаем задачу в ссылку на заметку
- Оборачиваем задачу в Wikilink [[]] и нажимаем на неё, заметка с именем задачи создастся автоматически
- Заметка создастся в стандартной папке для заметок, папку можно задать в Settings => Files and links => Folder to create new notes in.

#obsidian #notion

@cherkashindev

cherkashin.dev

02 Oct, 06:55


Пока я Индии поедаю сабудану и досу, мне в Курск пришла книга "Мама, Я тимлид!" от Жени Черкасова. Я конечно не тимлид, но книжку обязательно прочитаю.

Женя ведёт ламповый и очень уютный канал о личной и командной эффективности. Вот некоторые из моих любимых постов:
- Готовься к увольнению с первого дня
- Как всё успеть
- Сколько я заработал с блога
- Как на самом деле строятся процессы

А ещё Женя летает на параплане 😱, обязательно посмотрите.

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

#рекомендую_канал

@cherkashindev

cherkashin.dev

26 Sep, 19:08


Пока я сижу в Шереметьево и жду свой задерживающийся рейс в Мумбаи, расскажу вам кринжовую историю, которая произошла со мной сегодня утром в аэропорте Каира.

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

Обычное утро, заказываем убер и едем в аэропорт, мы жили в районе Гелиополис, поэтому доехали минут за 20. Рассчитываюсь с водителем и идём в аэропорт. Перед металлоискателями говорю жене: "Надеюсь, что мы пройдём всё очень быстро", и тут ощущаю тревожную лёгкость - рюкзак с ноутом и российским паспортом остался на заднем сидении такси.

Мысленно попрощавшись с ноутом и параллельно убеждая жену, что таксист ещё не успел его кому-то втюхать, пишу в поддержку убера. Чтобы связаться с водителем, я прошу номер телефона сотрудника аэропорта - российский номер не подходит. Спустя 10 минут попыток - связаться с таксистом так и не получилось. А Убер просит сообщить ему, если нам не получится вернуть рюкзак в течение 24 часов. Пока сотрудник аэропорта зовёт полицию - я понимаю, что придётся лететь домой без ноута и прикидываю, где купить новый макбук в Москве перед командировкой.

Спустя 5 минут приходит худощавый египетский полицейский со стволом, который повторяет каждые 10 секунд, чтобы меня успокоить: "Don't worry, I will help you. It is my job.". Он мне напомнил брутального копа из американских фильмов. Изучив профиль таксиста, он уходит смотреть по камерам куда скрылся злоумышленник.

Ещё минут через 5 жене приходит в голову шикарная идея - возможно на ноуте работает геолокация. Открываю на айфоне локатор и вижу, что мои наушники и ноут неподалёку от аэропорта, появляется небольшая надежда. Через пару минут, наушники снова оказываются на территории аэропорта - таксист вернулся. Я хочу выбежать на улицу, расцеловать таксиста вручить ему вознаграждение и наконец-то отправиться на регистрацию, но полицейский останавливает меня - нужно соблюсти бюрократические процедуры.

Когда со всем разобрались, завязывается диалог с полицейским (П):

Я: Как вы его нашли?
П: Это просто моя работа! "Как твои дела?" - спрашивает он на русском
Я: Очень хорошо! "Я бы сказал иначе, но не хочу материться." - переходим обратно на английский.
П: Ты куришь? Может хочешь, что-нибудь выпить?
Я: Нет, ещё раз большое спасибо.
П: Египтяне хорошие люди, приезжайте к нам снова.
Я: Непременно.

Подходим к металлоискателям, где другие "хорошие" египтяне разводят нас на 200 фунтов (400 рублей), но это уже совсем другая история.

P.S. Таксист не говорил по-английски, но он несколько раз повторил "Uber, SMS". Думаю, убер просто связался с таксистом и тот вернулся назад, а полицейский брутально присвоил всю славу себе. Но мы конечно всё равно ему благодарны.

Расскажите, какие подобные истории происходили с вами? 😅

#about_me #vacation

cherkashin.dev

17 Sep, 12:13


Кажется, кто-то узнал, что программист приехал на отдых.

Сначала аэропорт SSH, теперь номер 11101, а дальше что?

Бустани канал, чтобы оставаться в курсе, а то мало ли что ...

#vacation

cherkashin.dev

11 Sep, 08:13


⏭️ Соседние селекторы в CSS

Сегодня утром прилетает баг - у элемента не виден горизонтальный скрол. Случилось это из-за новой фичи - появился новый компонент, из-за чего соседний немного съехал и скрол ушёл за пределы экрана.

Тут я подумал, что в первый раз в жизни смогу использовать "Родственные селекторы" ~, чтобы пофиксить стили если оба элемента отображаются на странице:


.new-feature-element ~ .element-with-scroll {
// тут фиксим стили, они применяются к .element-with-scroll
}


Посмотрел на разметку, понял что .element-with-scroll всегда идёт непосредственно после .new-feature-element поэтому можно поменять на +:


.new-feature-element + .element-with-scroll {
// тут фиксим стили, они применяются к .element-with-scroll
}


Основные различия + и ~:

- + выбирает только один элемент, который непосредственно следует за первым элементом.
- ~ выбирает все элементы, которые следуют за первым элементом, но не обязательно сразу за ним.

Посмотрел на разметку ещё раз и понял, что элементы видны всегда, а не по условию, поэтому просто пофиксил стили для .element-with-scroll без всяких соседних селекторов, но хоть потренировался.

#css

cherkashin.dev

06 Sep, 10:03


Notion 👋

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


У меня пока план миграции такой:

1. Экспортировал все данные из Notion
2. Импортировал в российские аналоги - Yonote и Teamly, на случай если понадобятся старые заметки в удобно читаемом формате (ну не совсем он удобный)
3. Обмазываюсь плагинами в Obsidian и пытаюсь разобраться, что лучше “папки или связи”


Теперь кратко про Obsidian:

- Настроил интеграцию с гитом, чтобы бэкапить всё на гитхаб
- Шаблоны Notion заменил на плагин Templates
- Настроил некоторые горячие клавиши, как в VS Code.
- Вместо баз данных Notion, установил плагин Projects. Он позволяет отображать данные в виде таблицы или канбан доски, как это было в Notion.
- Аналога инлайн баз данных в Obsidian нет, но есть dataview. С помощью SQL подобного языка запросов Dataview Query Language, можно писать запросы ко всем заметкам в базе знаний.
- Для миграции заметок из Notion можно использовать плагин Obsidian Importer. Я пока импортировал только, базу с постами для телеграмм. Импортировалось отлично. Нужно делать экспорт в HTML формате, не в Markdown. После импорта, настроил отображение с помощью плагина Projects и получилось примерно как было в Notion. И ощущение, что после этого Obsidian стал иногда подвисать, посмотрим как будет работать дальше.
- Создал папку для zero-links - по сути теги в виде страниц имена, которых начинаются с двух нулей, для оптимизации поиска.
- Так как инлайн баз данных нет, для ведения задач собираюсь попробовать плагин Obsidian Tasks.


Если вам интересна тема Notion и как с него съехать, то вам на канал Марии. Она активно освещает текущую ситуацию, и альтернативные продукты.

P.S. Расскажите, как вы ведёте базу знаний или список задач. На что мигрируете, если пользовались Notion? Тупит ли Obsidian у вас? 😅

#notion #obsidian

cherkashin.dev

23 Aug, 10:00


У нас на проекте есть 2 основных правила для написания стилей:

- У всех CSS-классов должен быть префикс dp-, выбранный по названию продукта
- Мы используем БЭМ — <block>__<element>--<modifier>

Однако есть большой пласт легаси стилей, где эти правила не используются.

И вот, при добавлении monaco-editor’а (текстовый редактор на котором построен VS Code) в новую фичу, прилетело ишью — у горизонтального и вертикального скролл-баров разная толщина.

А вся проблема в том, что наши глобальные стили для класса slider применяются к элементу с таким же классом в monaco-editor.

Именно эту проблему и решают префиксы — позволяют избежать коллизии имён с библиотечными классами.

#css #bem

cherkashin.dev

19 Aug, 10:00


size-limit

Вот здесь я писал про source-map-explorer и о том, как с его помощью анализировать размер бандла. Но, чтобы не приходилось анализировать бандл, лучше предотвратить его раздувание.

Это можно сделать на этапе CI с помощью size-limit.


Как использовать

1. Устанавливаем size-limit и плагин @size-limit/file, необходимый для анализа web-приложений.

npm install --save-dev size-limit @size-limit/file


2. Добавляем когфиг size-limit в package.json

  "size-limit": [
{
"limit": "35 kB",
"path": "dist/app-*.js",
"gzip": true
}
],


3. Добавляем запуск size-limit в скрипт, который вы запускаете на CI

  "scripts": {
"size": "npm run build && size-limit",
"test": "vitest && eslint . && npm run size"
}


Если вы пользуетесь гитхабом, то можете использовать GitHub action, который добавляет в качестве комментария изменение размера бандла.

Также size-limit поддерживает задание временных лимитов на исполнение вашего кода и использует для этого “безголовый хром”.

#frontend #performance #tools #ci

cherkashin.dev

16 Aug, 09:05


Первый шок от последних событий начал проходить, поэтому вчера я немного разобрал инбокс и нашёл в нём статью, которой решил с вами поделиться “4 тысячи заметок?! Как я веду личную базу знаний в Obsidian”.

Автор рассказывает, как ему надоело забывать важную информацию и он решил завести личную базу знаний в Obsidian, вдохновившись Zettelkasten.

Zettelkasten – это такая система ведения личных заметок, в которой каждая заметка:

- Атомарна. То есть независима и содержит одну мысль.
- Имеет контекст. Например, размечена по тегам, темам.
- Связана с другими знаниями в системе.

Obsidian — это приложение для заметок на максималках. Главное преимущество перед тем же Notion — очень просто добавить новую связь между заметками и легко масштабировать базу (ну и данные все хранятся локально, насколько я помню). Автор использовал видео Виктора Теплова для настройки Obsidian.

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

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

Вчера я тоже решил записать, чего полезного я сделал за прошедший день и понял, что кроме работы там ничего нет. Поэтому я соглашусь с автором, порой стоит остановиться и подумать, “туда ли я иду”.

В общем, рекомендую прочитать статью целиком, тем более, что она совсем небольшая.

---

А расскажите,

- чем пользуетесь вы для ведения заметок?
- какие подходы и практики используете?

Я пользуюсь Notion. Но вот на днях пришло письмо от Miro, о том, что они “не могут обслуживать клиентов, зарегистрированных в запрещённом регионе” с 12 сентября. И кто сказал, что скоро Notion не пришлёт такое же письмо, возможно стоит начинать искать альтернативы …

#obsidian #fridayreading

cherkashin.dev

10 Aug, 09:09


Со стороны может показаться, что у нас, у программистов, очень лёгкая работа. Как любит говорить мой тренер по теннису: “мол успешные айтишники сидят где-нибудь в эмиратах, птягивают кофе в кафешках и в ус не дуют”. В чем-то он может и прав, но почему-то не у всех получается “войти в айти”. А те, кто вошел, только и говорят о выгорании.


Года 3 назад я писал, что я делаю, чтобы не перегореть. С тех пор добавилось ещё несколько привычек.

🎾 Я начал играть в большой теннис. Пока бегаешь по корту и чуть ли не выплёвываешь свои лёгкие, совсем забываешь о работе.


🏃‍♂️ С нового года я начал делать зарядку, увидел пост у Евгения Шушкова и тоже решил попробовать. Не уверен, что я чувствую себя намного лучше, но зарядка определённо помогает проснуться. Но что гораздо лучше, она помогает на какие-то 15 минут немного избавиться от тревожности.

- Обычно я делаю вот этот комплекс на 15 минут
- Или этот на 5 минут, когда лень, но чтобы не потерять привычку


💪 В дополнение к зарядке стараюсь пару раз в неделю подтягиваться или отжиматься. Или же делаю вот этот комплекс на пресс, первые 4 минуты, потом пресс умирает.


📱В мае я отписался от новостных каналов.

---

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

P.S.

В такие моменты важно иметь чувство контроля над ситуацией. И оно хоть немного появляется, когда получается помочь тем, кому сейчас тяжело.

Если у вас есть желание помочь людям, кто вынуждено покинул свои дома из-за всей ситуации в Курской области, это можно сделать здесь. Или напишите мне в личку.

Я вообще считаю, программирование это не про “писать код”, это про людей. И мы можем сделать жизнь людей лучше не только написав очередные 1000 строчек кода.

cherkashin.dev

06 Aug, 10:00


source-map-explorer

На прошлой неделе анализировал размер главного бандла мобильной версии нашего приложения.

В спешке мы накосячили с импортами и бандл раздулся.

🤔 Как анализировать?

Для анализа использовал утилиту source-map-explorer.

При запуске, утилита генирирует древовидную карту, с помощью которой можно увидеть, какие именно файлы попадают в бандл.

К сожалению, почему именно это что-то попало в бандл утилита не говорит.

👉 В чём была проблема?

Иногда мы ленимся и в файле компонента кладём какую-нибудь утилитную функцию, enum или константу, а потом где-то в другом месте импортируем их.

Так вот, когда мы их импортируем, то в бандл “засасывает” не только импортируемую функцию, но и весь компонент, из-за чего размер бандла и увеличивается.

P.S. А какими инструментами пользуетесь вы?

#frontend #performance #tools

cherkashin.dev

30 Jul, 10:00


Как инспектировать разметку попапов

Если у вас возникают проблемы с дебагом попапов, которые открываются только по ховеру, то вот несколько простых советов:

Способ 1: Открываете DevTools ⇒ Вкладка Sources ⇒ Далее наводите мышкой на свой элемент ⇒ Нажимаете F8, чтобы приостановить выполнение скрипта

Способ 2: Открываете DevTools ⇒ Находите тег body или тот тег, внутри которого появляется попап и нажимаете на нём правой кнопкой ⇒ Выбираете “Break on ⇒ subtree modification” и дебажите до тех пор пока не появится попап.

Способ 3: Мой любимый. Вставляете скрипт в консоль и у вас есть 3 секунды чтобы показать попап. Именно этим способом пользовался пока не узнал про первый 😄

setTimeout(() => { debugger }, 3000)


#frontend #devtools

cherkashin.dev

26 Jul, 10:00


Если бы вас спросили, что самое сложное в вашей работе, чтобы вы ответили?
Я думаю одна из самых сложных вещей - читать чужой код, или свой собственный, написанный пару лет назад.

👉 Сегодня статья о том, Как избежать когнитивной перегрузки: способы оптимизации кода для разработчиков.

Вот основные моменты из статьи, если вам лень читать всю статью в пятницу да ещё и летом 😅

- Когнитивная нагрузка – это объем умственной работы, необходимый разработчику для выполнения задачи. Нашим приоритетом должно быть максимальное снижение такой нагрузки в проектах.
- Типы когнитивной нагрузки:
- Внутренняя — изначальная сложность задачи, её нельзя уменьшить.
- Внешняя — создается способом представления информации. То есть то, как написан код, решающий задачу.
- Знакомая и простая вещь — не одно и то же. Они ощущаются одинаково — та же легкость перемещения по пространству без особых умственных усилий, но по совершенно разным причинам. Каждый «умный» и нестандартный прием приведет к трате времени на обучение для остальных разработчиков. После того, как они его освоят, им будет легче работать с кодом. Именно поэтому не так легко понять, как можно упростить уже знакомый код.
- Нет никакой «упрощающей силы», влияющей на базу кода, кроме вашего сознательного выбора. Упрощение требует усилий, а люди часто спешат.
- Отладка в два раза сложнее написания кода. Следовательно, если вы пишете код максимально хитроумно, вы по определению недостаточно умны, чтобы его отладить.

- Лучшие компоненты — это те, которые обеспечивают мощную функциональность при простом интерфейсе.
- Лучше большой модуль с простым API, чем много маленьких модулей с раздутым API, которые связаны между собой.
- Хорошо продуманный монолит с действительно изолированными модулями часто намного удобнее и гибче, чем набор микросервисов.

- DRY (Don’t repeat yourself) — хотя в целом это хорошее и фундаментальное правило, его чрезмерное использование приводит к непосильной когнитивной нагрузке. У DRY есть альтернатива AHA Programming
- Вы можете слишком рано извлечь общую функциональность, основываясь на предполагаемом сходстве, которого на самом деле в долгосрочной перспективе может не быть. Это может привести к ненужным абстракциям, которые будет непросто модифицировать или расширять.
- «Небольшое копирование лучше, чем небольшая зависимость».

https://habr.com/ru/companies/ncloudtech/articles/818643/

#fridayreading #essential

cherkashin.dev

17 Jul, 10:03


Как я обычно узнаю о новых фичах в C#

О новых фичах в C# я обычно узнаю с помощью подсказок Райдера — IDE для C# от JetBrains.

В общем, обновился, пишу код, и Райдер предлагает что-то исправить там, где раньше все было окей. Думаю — ну ок, давай исправим. Но ощущение, что он перепутал C# c JavaScript.

- string[] array = new [] { “a”, “b”, } предлагает заменить на string[] array = ["a", "b"]
- Array.Empty<string>() на []
- List<string> list = new (vowels) на List<string> list = [.. vowels]

Особенно интересен последний пример, очень уж напоминающий spread оператор из JS. И действительно, в C# его тоже завезли, правда по пути потеряли одну точку и назвали spread element.


int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];

int[] example1 = [..row0, ..row1, ..row2];
List<int> example2 = [..row0, row1[0]];


В общем, в C# 12 поднасыпали синтаксического сахара для работы с коллекциями. А ещё прихватили Primary конструктор из Scala. Это когда конструктор объявляется сразу после имени класса.


public class BankAccount(string accountID, string owner)
{
public string AccountID { get; } = accountID;
public string Owner { get; } = owner;

public override string ToString() => $"Account ID: {AccountID}, Owner: {Owner}";
}


Подробнее о релизе C# 12 здесь.

А о том, как добавить поддержку спред оператора для кастомных коллекций описывается тут.

#csharp

cherkashin.dev

08 Jul, 10:00


function(): Promise 🆚 async function(): Promise

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

Пример

function fn(obj) {
const someProp = obj.someProp
return Promise.resolve(someProp)
}

async function asyncFn(obj) {
const someProp = obj.someProp
return Promise.resolve(someProp)
}

asyncFn().catch(err => console.error('Catched')) // => 'Catched'
fn().catch(err => console.error('Catched')) // => TypeError: Cannot read property 'someProp' of undefined


- при объявлении функции с ключевым словом async JavaScript гарантирует, что функция вернёт Promise, даже если в ней произошла ошибка
- если функция возвращает Promise, но объявлена без async то catch не поймает ошибку, если в функции произошла ошибка
- дело в том, что ошибки произошедшие внутри конструктора new Promise((resolve, reject) => { throw new ... }) промиса ловятся. Когда мы добавляем async, то по сути заворачиваем тело функции в new Promise((resolve, reject) ⇒ { })

То есть, чтобы сделать функции из примера идентичными, нужно завернуть первую функцию в промис.

function fn(obj) {
return new Promise((resolve, reject) => {
const someProp = obj.someProp;
resolve(someProp);
});
}


https://habr.com/ru/articles/475260/


#javascript #frontend