На прошлой неделе проверял почту и наткнулся на рассылку от Я.Практикума “Что нельзя делать хорошему менеджеру”. Одна из упоминаемых проблем – “Срезание углов” или экономия времени на продумывании ТЗ. Чтобы избежать проблемы понимания требований исполнителем – нужно научиться смотреть на ТЗ глазами новичка. Такое же правило я применяю при написании кода:
Нужно смотреть на код глазами новичка.
Представьте, что вы новый сотрудник и ничего не знаете кроме того, что написано в коде.
- Поймёт ли он, что именно происходит в коде?
- Почему это реализовано именно так?
Нужно смотреть на код глазами новичка.
Представьте, что вы новый сотрудник и ничего не знаете кроме того, что написано в коде.
- Поймёт ли он, что именно происходит в коде?
- Почему это реализовано именно так?
👍12❤3👏1
Мемоизация селекторов в Zustand
Если вы используете Zustand, то знаете, что computed значения реализуются с помощью селекторов.
В примере выше:
- при каждом обновлении стейта значение селектора будет вычисляться заново
- это приведёт к ре-рендеру компонента, так как каждый раз мы постоянно возвращает новый массив по ссылке, а по-умолчанию используется строгое сравнение (old === new).
Чтобы решить эту проблему в Zustand есть хук
Но при этом селектор всё равно выполнится, и в большинстве случаев нам не нужно об этом заботиться. Проблема появляется если выполнение селектора занимает много времени или же он вызывается много раз в различных компонентах или других селекторах.
Автор Zustand упоминает, что можно нарушить согласованность данных и просто положить вычисляемые данные в стейт (но в этом случае нужно вручную следить за их актуальностью).
Также он отмечает, что для этих целей можно использовать метод
Аналогично immer’у proxy-memoize работает на основе
Конечно, нужно помнить, что мемоизировать можно только “чистую” функцию — если она возвращает одни и те же значения в ответ на одни и те же аргументы
Так, обернув пару селекторов в
#react #zustand #statemanagement #frontend
Если вы используете Zustand, то знаете, что computed значения реализуются с помощью селекторов.
const userPrs = useChartsStore((state) => {
return state.pullRequests.filter(pr => pr.author.id === state.user.id);
});
В примере выше:
- при каждом обновлении стейта значение селектора будет вычисляться заново
- это приведёт к ре-рендеру компонента, так как каждый раз мы постоянно возвращает новый массив по ссылке, а по-умолчанию используется строгое сравнение (old === new).
Чтобы решить эту проблему в Zustand есть хук
useShallow , который сделает “поверхностное” сравнение предыдущего и нового значения. Если они равны — ре-рендер не произойдёт.
const userPrs = useChartsStore(useShallow((state) => {
return state.pullRequests.filter(pr => pr.author.id === state.user.id);
}));
Но при этом селектор всё равно выполнится, и в большинстве случаев нам не нужно об этом заботиться. Проблема появляется если выполнение селектора занимает много времени или же он вызывается много раз в различных компонентах или других селекторах.
Автор Zustand упоминает, что можно нарушить согласованность данных и просто положить вычисляемые данные в стейт (но в этом случае нужно вручную следить за их актуальностью).
Также он отмечает, что для этих целей можно использовать метод
memoize из его библиотеки proxy-memoize (для redux есть reselect). Аналогично immer’у proxy-memoize работает на основе
Proxy. memoize запоминает предыдущий параметр функции и свойства к которым обращались в селекторе (для этого и нужен Proxy). При следующем выполнении функции, он проверит изменились ли используемые свойства, если нет — вернёт значение, вычисленное в прошлый раз.
const authorSelector = memoize((state) => state.pullRequests.filter(pr => pr.author.id === state.user.id));
const userPrs = useChartsStore(authorSelector);
Конечно, нужно помнить, что мемоизировать можно только “чистую” функцию — если она возвращает одни и те же значения в ответ на одни и те же аргументы
Так, обернув пару селекторов в
memoize, я ускорил фильтрацию пул-реквестов в более чем 20 раз (900мс ⇒ 40мс).#react #zustand #statemanagement #frontend
👍14🔥3🥴2🥱1
Generic React-компоненты
Помню года так 4 назад я писал базовый компонент поиска — стандартное текстовое поле, а когда начинаешь печатать, появляется список найденных элементов.
И тогда я впервые задумался, поддерживает ли React дженерики в связке с TypeScript (а почему бы ему их не поддерживать?).
Каркас компонента выглядит так
А использование так
TypeScript отлично выводит типы, но недавно я узнал, что их можно указать и в JSX. Раньше думал, что будут проблемы из-за угловых скобок
💡 Когда использовать дженерики для реакт-компонентов?
Когда компонент может принимать:
- данные разных типов
- и рендер-пропсы/слоты, чтобы преобразовать эти данные в UI
Ещё один пример можете посмотреть вот в этом видео
#react #frontend #typescript
Помню года так 4 назад я писал базовый компонент поиска — стандартное текстовое поле, а когда начинаешь печатать, появляется список найденных элементов.
И тогда я впервые задумался, поддерживает ли React дженерики в связке с TypeScript (а почему бы ему их не поддерживать?).
Каркас компонента выглядит так
export interface SearchBoxProps<T> {
search: (text: string) => T[] | Promise<T[]>;
renderItem: (item: T) => React.ReactNode;
// ...
}
export function SearchBox<T>(props: SearchBoxProps<T>) {
// ...
}
А использование так
<SearchBox
search={() => [1, 2, 3]}
renderItem={(item) => <div>{item}</div>}
/>
TypeScript отлично выводит типы, но недавно я узнал, что их можно указать и в JSX. Раньше думал, что будут проблемы из-за угловых скобок
< > в дженериках<SearchBox<number>
search={() => [1, 2, 3]}
renderItem={(item) => <div>{item}</div>}
/>
💡 Когда использовать дженерики для реакт-компонентов?
Когда компонент может принимать:
- данные разных типов
- и рендер-пропсы/слоты, чтобы преобразовать эти данные в UI
Ещё один пример можете посмотреть вот в этом видео
#react #frontend #typescript
👍11🔥4❤2
Сегодня принёс вам одну из лучших статей по код ревью.
В конце статьи автор упоминает фразу, которая уже давно вертелась у меня на языке, и вот здесь она отлично сформулирована.
💡 “Как это ни парадоксально, наличие постоянно полезных и ценных ревью — это признак того, что вы можете добиться большего на других этапах процесса.”
- Исправлять архитектурные проблемы на фазе код ревью — слишком дорого
- Люди не должны вручную искать проблемы, которые можно найти автоматически
- Одна из целей код ревью — постоянно сужать его рамки, позволяя разработчикам постоянно обнаруживать, что может быть улучшено в других частях процесса разработки
- Документация
- Онбординг
- Линтеры
- Статические анализаторы
- и т.д.
Также ещё одна мысль, которую доносит автор — “код ревью не должно быть одинаковым для всех изменений”.
🐌 Проблемы медленных ревью
- Они медленные 🤷♂️ — замедляют релиз на несколько часов или дней
- Поверхностные — не улучшают качество кода, не происходит обмен знаниями.
- Если ревью происходит медленно — разработчики начинают создавать большие пул реквесты, что увеличивает нагрузку на ревьюера и делает код ревью ещё медленнее.
Подходы, которые описываются в статье
Автор долго придерживался принципа Ship / Show / Ask
- 🚢 Ship. Изменения простые, нет знаний, которыми стоит поделиться — льём в прод без ревью.
- 🔍 Show. Если изменения простые, но в них есть что-то полезное и ими стоит поделиться (например вы написали новую функцию или компонент), то — сливайте изменения, а потом просите о код ревью. Код ревью — не блокирующий. Я обычно называю это постревью.
- ❓Ask. Если вы вносите сложные изменения — дождитесь код ревью и только потом сливайте изменения. Тут код ревью блокирующий.
Со временем он его немного перефразировал в Automate / Defer / Pair
- 🤖 Automate. Если в изменениях нет знаний, которыми стоило бы поделиться, а в коде особо нечего улучшить — пропускаем ревью и полагаемся на линтеры, статические анализаторы и тесты.
- ↪️ Defer (отложить). В зрелом и проверенном процессе разработки большинство изменений нужно ревьюить, но ревью не должно быть блокирующим. Это особенно хорошо работает, когда новая фича деплоится за фича флагом и можно спокойно получить фидбек после деплоя.
- 👯 Pair. Если корректность изменений очень важна: их сложно откатить или изменения связаны с оплатой, или же изменения достаточно сложные — то вам нужно работать в паре с ревьюером, созвониться и объяснить ему изменения, чтобы он был в контексте и смог сделать ревью быстрее и качественнее.
#codereview #fridayreading #weekphrase
В конце статьи автор упоминает фразу, которая уже давно вертелась у меня на языке, и вот здесь она отлично сформулирована.
💡 “Как это ни парадоксально, наличие постоянно полезных и ценных ревью — это признак того, что вы можете добиться большего на других этапах процесса.”
- Исправлять архитектурные проблемы на фазе код ревью — слишком дорого
- Люди не должны вручную искать проблемы, которые можно найти автоматически
- Одна из целей код ревью — постоянно сужать его рамки, позволяя разработчикам постоянно обнаруживать, что может быть улучшено в других частях процесса разработки
- Документация
- Онбординг
- Линтеры
- Статические анализаторы
- и т.д.
Также ещё одна мысль, которую доносит автор — “код ревью не должно быть одинаковым для всех изменений”.
🐌 Проблемы медленных ревью
- Они медленные 🤷♂️ — замедляют релиз на несколько часов или дней
- Поверхностные — не улучшают качество кода, не происходит обмен знаниями.
- Если ревью происходит медленно — разработчики начинают создавать большие пул реквесты, что увеличивает нагрузку на ревьюера и делает код ревью ещё медленнее.
Подходы, которые описываются в статье
Автор долго придерживался принципа Ship / Show / Ask
- 🚢 Ship. Изменения простые, нет знаний, которыми стоит поделиться — льём в прод без ревью.
- 🔍 Show. Если изменения простые, но в них есть что-то полезное и ими стоит поделиться (например вы написали новую функцию или компонент), то — сливайте изменения, а потом просите о код ревью. Код ревью — не блокирующий. Я обычно называю это постревью.
- ❓Ask. Если вы вносите сложные изменения — дождитесь код ревью и только потом сливайте изменения. Тут код ревью блокирующий.
Со временем он его немного перефразировал в Automate / Defer / Pair
- 🤖 Automate. Если в изменениях нет знаний, которыми стоило бы поделиться, а в коде особо нечего улучшить — пропускаем ревью и полагаемся на линтеры, статические анализаторы и тесты.
- ↪️ Defer (отложить). В зрелом и проверенном процессе разработки большинство изменений нужно ревьюить, но ревью не должно быть блокирующим. Это особенно хорошо работает, когда новая фича деплоится за фича флагом и можно спокойно получить фидбек после деплоя.
- 👯 Pair. Если корректность изменений очень важна: их сложно откатить или изменения связаны с оплатой, или же изменения достаточно сложные — то вам нужно работать в паре с ревьюером, созвониться и объяснить ему изменения, чтобы он был в контексте и смог сделать ревью быстрее и качественнее.
#codereview #fridayreading #weekphrase
refactoring.fm
Thoughts on Code Reviews 🔍
Why so many teams mess them up, and a modest proposal to do them better.
🔥11👍6❤2
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
Хабр
Разница между асинхронной функцией и функцией, возвращающей промис
Существует небольшая, но довольно важная разница между функцией, которая просто возвращает промис, и функцией, которая была объявлена с помощью ключевого слова async . Взгляните на следующий фрагмент...
👍23🔥5❤4
Как я обычно узнаю о новых фичах в C# ❓
О новых фичах в C# я обычно узнаю с помощью подсказок Райдера — IDE для C# от JetBrains.
В общем, обновился, пишу код, и Райдер предлагает что-то исправить там, где раньше все было окей. Думаю — ну ок, давай исправим. Но ощущение, что он перепутал C# c JavaScript.
-
-
-
Особенно интересен последний пример, очень уж напоминающий spread оператор из JS. И действительно, в C# его тоже завезли, правда по пути потеряли одну точку и назвали spread element.
В общем, в C# 12 поднасыпали синтаксического сахара для работы с коллекциями. А ещё прихватили Primary конструктор из Scala. Это когда конструктор объявляется сразу после имени класса.
Подробнее о релизе C# 12 здесь.
А о том, как добавить поддержку спред оператора для кастомных коллекций описывается тут.
#csharp
О новых фичах в 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
Docs
Declare C# primary constructors – classes, structs
Learn how and when to declare primary constructors in your class and struct types. Primary constructors provide concise syntax to declare constructor parameters available anywhere in the body of your type.
👍4😁2👎1
Если бы вас спросили, что самое сложное в вашей работе, чтобы вы ответили?
Я думаю одна из самых сложных вещей - читать чужой код, или свой собственный, написанный пару лет назад.
👉 Сегодня статья о том, Как избежать когнитивной перегрузки: способы оптимизации кода для разработчиков.
Вот основные моменты из статьи, если вам лень читать всю статью в пятницу да ещё и летом 😅
- Когнитивная нагрузка – это объем умственной работы, необходимый разработчику для выполнения задачи. Нашим приоритетом должно быть максимальное снижение такой нагрузки в проектах.
- Типы когнитивной нагрузки:
- Внутренняя — изначальная сложность задачи, её нельзя уменьшить.
- Внешняя — создается способом представления информации. То есть то, как написан код, решающий задачу.
- Знакомая и простая вещь — не одно и то же. Они ощущаются одинаково — та же легкость перемещения по пространству без особых умственных усилий, но по совершенно разным причинам. Каждый «умный» и нестандартный прием приведет к трате времени на обучение для остальных разработчиков. После того, как они его освоят, им будет легче работать с кодом. Именно поэтому не так легко понять, как можно упростить уже знакомый код.
- Нет никакой «упрощающей силы», влияющей на базу кода, кроме вашего сознательного выбора. Упрощение требует усилий, а люди часто спешат.
- Отладка в два раза сложнее написания кода. Следовательно, если вы пишете код максимально хитроумно, вы по определению недостаточно умны, чтобы его отладить.
- Лучшие компоненты — это те, которые обеспечивают мощную функциональность при простом интерфейсе.
- Лучше большой модуль с простым API, чем много маленьких модулей с раздутым API, которые связаны между собой.
- Хорошо продуманный монолит с действительно изолированными модулями часто намного удобнее и гибче, чем набор микросервисов.
- DRY (Don’t repeat yourself) — хотя в целом это хорошее и фундаментальное правило, его чрезмерное использование приводит к непосильной когнитивной нагрузке. У DRY есть альтернатива — AHA Programming
- Вы можете слишком рано извлечь общую функциональность, основываясь на предполагаемом сходстве, которого на самом деле в долгосрочной перспективе может не быть. Это может привести к ненужным абстракциям, которые будет непросто модифицировать или расширять.
- «Небольшое копирование лучше, чем небольшая зависимость».
https://habr.com/ru/companies/ncloudtech/articles/818643/
#fridayreading #essential
Я думаю одна из самых сложных вещей - читать чужой код, или свой собственный, написанный пару лет назад.
👉 Сегодня статья о том, Как избежать когнитивной перегрузки: способы оптимизации кода для разработчиков.
Вот основные моменты из статьи, если вам лень читать всю статью в пятницу да ещё и летом 😅
- Когнитивная нагрузка – это объем умственной работы, необходимый разработчику для выполнения задачи. Нашим приоритетом должно быть максимальное снижение такой нагрузки в проектах.
- Типы когнитивной нагрузки:
- Внутренняя — изначальная сложность задачи, её нельзя уменьшить.
- Внешняя — создается способом представления информации. То есть то, как написан код, решающий задачу.
- Знакомая и простая вещь — не одно и то же. Они ощущаются одинаково — та же легкость перемещения по пространству без особых умственных усилий, но по совершенно разным причинам. Каждый «умный» и нестандартный прием приведет к трате времени на обучение для остальных разработчиков. После того, как они его освоят, им будет легче работать с кодом. Именно поэтому не так легко понять, как можно упростить уже знакомый код.
- Нет никакой «упрощающей силы», влияющей на базу кода, кроме вашего сознательного выбора. Упрощение требует усилий, а люди часто спешат.
- Отладка в два раза сложнее написания кода. Следовательно, если вы пишете код максимально хитроумно, вы по определению недостаточно умны, чтобы его отладить.
- Лучшие компоненты — это те, которые обеспечивают мощную функциональность при простом интерфейсе.
- Лучше большой модуль с простым API, чем много маленьких модулей с раздутым API, которые связаны между собой.
- Хорошо продуманный монолит с действительно изолированными модулями часто намного удобнее и гибче, чем набор микросервисов.
- DRY (Don’t repeat yourself) — хотя в целом это хорошее и фундаментальное правило, его чрезмерное использование приводит к непосильной когнитивной нагрузке. У DRY есть альтернатива — AHA Programming
- Вы можете слишком рано извлечь общую функциональность, основываясь на предполагаемом сходстве, которого на самом деле в долгосрочной перспективе может не быть. Это может привести к ненужным абстракциям, которые будет непросто модифицировать или расширять.
- «Небольшое копирование лучше, чем небольшая зависимость».
https://habr.com/ru/companies/ncloudtech/articles/818643/
#fridayreading #essential
Хабр
Как избежать когнитивной перегрузки: способы оптимизации кода для разработчиков
По мнению Артема Закируллина*, одна из фундаментальных проблем, с которой сталкиваются разработчики при анализе кода – высокая когнитивная нагрузка. Это не абстрактное, а реальное ограничение...
👍11💯4
Как инспектировать разметку попапов
Если у вас возникают проблемы с дебагом попапов, которые открываются только по ховеру, то вот несколько простых советов:
Способ 1: Открываете DevTools ⇒ Вкладка Sources ⇒ Далее наводите мышкой на свой элемент ⇒ Нажимаете F8, чтобы приостановить выполнение скрипта
Способ 2: Открываете DevTools ⇒ Находите тег body или тот тег, внутри которого появляется попап и нажимаете на нём правой кнопкой ⇒ Выбираете “Break on ⇒ subtree modification” и дебажите до тех пор пока не появится попап.
Способ 3: Мой любимый. Вставляете скрипт в консоль и у вас есть 3 секунды чтобы показать попап. Именно этим способом пользовался пока не узнал про первый 😄
#frontend #devtools
Если у вас возникают проблемы с дебагом попапов, которые открываются только по ховеру, то вот несколько простых советов:
Способ 1: Открываете DevTools ⇒ Вкладка Sources ⇒ Далее наводите мышкой на свой элемент ⇒ Нажимаете F8, чтобы приостановить выполнение скрипта
Способ 2: Открываете DevTools ⇒ Находите тег body или тот тег, внутри которого появляется попап и нажимаете на нём правой кнопкой ⇒ Выбираете “Break on ⇒ subtree modification” и дебажите до тех пор пока не появится попап.
Способ 3: Мой любимый. Вставляете скрипт в консоль и у вас есть 3 секунды чтобы показать попап. Именно этим способом пользовался пока не узнал про первый 😄
setTimeout(() => { debugger }, 3000)
#frontend #devtools
🔥22👍3❤2😁2
source-map-explorer
На прошлой неделе анализировал размер главного бандла мобильной версии нашего приложения.
В спешке мы накосячили с импортами и бандл раздулся.
🤔 Как анализировать?
Для анализа использовал утилиту source-map-explorer.
При запуске, утилита генирирует древовидную карту, с помощью которой можно увидеть, какие именно файлы попадают в бандл.
К сожалению, почему именно это что-то попало в бандл утилита не говорит.
👉 В чём была проблема?
Иногда мы ленимся и в файле компонента кладём какую-нибудь утилитную функцию, enum или константу, а потом где-то в другом месте импортируем их.
Так вот, когда мы их импортируем, то в бандл “засасывает” не только импортируемую функцию, но и весь компонент, из-за чего размер бандла и увеличивается.
P.S. А какими инструментами пользуетесь вы?
#frontend #performance #tools
На прошлой неделе анализировал размер главного бандла мобильной версии нашего приложения.
В спешке мы накосячили с импортами и бандл раздулся.
🤔 Как анализировать?
Для анализа использовал утилиту source-map-explorer.
При запуске, утилита генирирует древовидную карту, с помощью которой можно увидеть, какие именно файлы попадают в бандл.
К сожалению, почему именно это что-то попало в бандл утилита не говорит.
👉 В чём была проблема?
Иногда мы ленимся и в файле компонента кладём какую-нибудь утилитную функцию, enum или константу, а потом где-то в другом месте импортируем их.
Так вот, когда мы их импортируем, то в бандл “засасывает” не только импортируемую функцию, но и весь компонент, из-за чего размер бандла и увеличивается.
P.S. А какими инструментами пользуетесь вы?
#frontend #performance #tools
👍7🤡1
Со стороны может показаться, что у нас, у программистов, очень лёгкая работа. Как любит говорить мой тренер по теннису: “мол успешные айтишники сидят где-нибудь в эмиратах, птягивают кофе в кафешках и в ус не дуют”. В чем-то он может и прав, но почему-то не у всех получается “войти в айти”. А те, кто вошел, только и говорят о выгорании.
Года 3 назад я писал, что я делаю, чтобы не перегореть. С тех пор добавилось ещё несколько привычек.
🎾 Я начал играть в большой теннис. Пока бегаешь по корту и чуть ли не выплёвываешь свои лёгкие, совсем забываешь о работе.
🏃♂️ С нового года я начал делать зарядку, увидел пост у Евгения Шушкова и тоже решил попробовать. Не уверен, что я чувствую себя намного лучше, но зарядка определённо помогает проснуться. Но что гораздо лучше, она помогает на какие-то 15 минут немного избавиться от тревожности.
- Обычно я делаю вот этот комплекс на 15 минут
- Или этот на 5 минут, когда лень, но чтобы не потерять привычку
💪 В дополнение к зарядке стараюсь пару раз в неделю подтягиваться или отжиматься. Или же делаю вот этот комплекс на пресс, первые 4 минуты, потом пресс умирает.
📱В мае я отписался от новостных каналов.
---
К сожалению, очередная попытка перестать читать новости на этой неделе провалилась. Сложно не следить за ними, когда ты живешь в Курске. В теннис тоже не поиграешь из-за постоянной сирены за окном. Поэтому именно сейчас я в полной мере почувствовал пользу зарядки.
P.S.
В такие моменты важно иметь чувство контроля над ситуацией. И оно хоть немного появляется, когда получается помочь тем, кому сейчас тяжело.
Если у вас есть желание помочь людям, кто вынуждено покинул свои дома из-за всей ситуации в Курской области, это можно сделать здесь. Или напишите мне в личку.
Я вообще считаю, программирование это не про “писать код”, это про людей. И мы можем сделать жизнь людей лучше не только написав очередные 1000 строчек кода.
Года 3 назад я писал, что я делаю, чтобы не перегореть. С тех пор добавилось ещё несколько привычек.
🎾 Я начал играть в большой теннис. Пока бегаешь по корту и чуть ли не выплёвываешь свои лёгкие, совсем забываешь о работе.
🏃♂️ С нового года я начал делать зарядку, увидел пост у Евгения Шушкова и тоже решил попробовать. Не уверен, что я чувствую себя намного лучше, но зарядка определённо помогает проснуться. Но что гораздо лучше, она помогает на какие-то 15 минут немного избавиться от тревожности.
- Обычно я делаю вот этот комплекс на 15 минут
- Или этот на 5 минут, когда лень, но чтобы не потерять привычку
💪 В дополнение к зарядке стараюсь пару раз в неделю подтягиваться или отжиматься. Или же делаю вот этот комплекс на пресс, первые 4 минуты, потом пресс умирает.
📱В мае я отписался от новостных каналов.
---
К сожалению, очередная попытка перестать читать новости на этой неделе провалилась. Сложно не следить за ними, когда ты живешь в Курске. В теннис тоже не поиграешь из-за постоянной сирены за окном. Поэтому именно сейчас я в полной мере почувствовал пользу зарядки.
P.S.
В такие моменты важно иметь чувство контроля над ситуацией. И оно хоть немного появляется, когда получается помочь тем, кому сейчас тяжело.
Если у вас есть желание помочь людям, кто вынуждено покинул свои дома из-за всей ситуации в Курской области, это можно сделать здесь. Или напишите мне в личку.
Я вообще считаю, программирование это не про “писать код”, это про людей. И мы можем сделать жизнь людей лучше не только написав очередные 1000 строчек кода.
Хабр
Очередная история о борьбе с выгоранием
Я думаю, не стоит никому объяснять, что такое выгорание, большинство периодически ходят по краю, рискуя упасть и окунуться в это состояние с головой. В двух словах выгорание — это поломка...
❤26
Первый шок от последних событий начал проходить, поэтому вчера я немного разобрал инбокс и нашёл в нём статью, которой решил с вами поделиться “4 тысячи заметок?! Как я веду личную базу знаний в Obsidian”.
Автор рассказывает, как ему надоело забывать важную информацию и он решил завести личную базу знаний в Obsidian, вдохновившись Zettelkasten.
Zettelkasten – это такая система ведения личных заметок, в которой каждая заметка:
- Атомарна. То есть независима и содержит одну мысль.
- Имеет контекст. Например, размечена по тегам, темам.
- Связана с другими знаниями в системе.
Obsidian — это приложение для заметок на максималках. Главное преимущество перед тем же Notion — очень просто добавить новую связь между заметками и легко масштабировать базу (ну и данные все хранятся локально, насколько я помню). Автор использовал видео Виктора Теплова для настройки Obsidian.
Используя подобную систему, достаточно просто писать статьи/тексты, ведь у тебя нет проблемы чистого листа. Ты можешь найти уже сохранённую информацию по одному из тегов, и остаётся лишь сформировать линию повествования.
Также автор описывает, что ведёт дневник в своей базе знаний, это помогает поразмышлять о том, что действительно важно. В жизни человека не происходит то, о чем он не мыслит, поэтому такое ретро очень помогает двигаться в нужном направлении.
Вчера я тоже решил записать, чего полезного я сделал за прошедший день и понял, что кроме работы там ничего нет. Поэтому я соглашусь с автором, порой стоит остановиться и подумать, “туда ли я иду”.
В общем, рекомендую прочитать статью целиком, тем более, что она совсем небольшая.
---
А расскажите,
- чем пользуетесь вы для ведения заметок?
- какие подходы и практики используете?
Я пользуюсь Notion. Но вот на днях пришло письмо от Miro, о том, что они “не могут обслуживать клиентов, зарегистрированных в запрещённом регионе” с 12 сентября. И кто сказал, что скоро Notion не пришлёт такое же письмо, возможно стоит начинать искать альтернативы …
#obsidian #fridayreading
Автор рассказывает, как ему надоело забывать важную информацию и он решил завести личную базу знаний в Obsidian, вдохновившись Zettelkasten.
Zettelkasten – это такая система ведения личных заметок, в которой каждая заметка:
- Атомарна. То есть независима и содержит одну мысль.
- Имеет контекст. Например, размечена по тегам, темам.
- Связана с другими знаниями в системе.
Obsidian — это приложение для заметок на максималках. Главное преимущество перед тем же Notion — очень просто добавить новую связь между заметками и легко масштабировать базу (ну и данные все хранятся локально, насколько я помню). Автор использовал видео Виктора Теплова для настройки Obsidian.
Используя подобную систему, достаточно просто писать статьи/тексты, ведь у тебя нет проблемы чистого листа. Ты можешь найти уже сохранённую информацию по одному из тегов, и остаётся лишь сформировать линию повествования.
Также автор описывает, что ведёт дневник в своей базе знаний, это помогает поразмышлять о том, что действительно важно. В жизни человека не происходит то, о чем он не мыслит, поэтому такое ретро очень помогает двигаться в нужном направлении.
Вчера я тоже решил записать, чего полезного я сделал за прошедший день и понял, что кроме работы там ничего нет. Поэтому я соглашусь с автором, порой стоит остановиться и подумать, “туда ли я иду”.
В общем, рекомендую прочитать статью целиком, тем более, что она совсем небольшая.
---
А расскажите,
- чем пользуетесь вы для ведения заметок?
- какие подходы и практики используете?
Я пользуюсь Notion. Но вот на днях пришло письмо от Miro, о том, что они “не могут обслуживать клиентов, зарегистрированных в запрещённом регионе” с 12 сентября. И кто сказал, что скоро Notion не пришлёт такое же письмо, возможно стоит начинать искать альтернативы …
#obsidian #fridayreading
Хабр
4 тысячи заметок?! Как я веду личную базу знаний в Obsidian
В моей базе знаний 4 000 заметок. Да, у меня немного съехала крыша на этой теме. Но решение создать систему для ведения заметок три года назад — пока что лучшая из моих интеллектуальных...
1👍6
size-limit
Вот здесь я писал про source-map-explorer и о том, как с его помощью анализировать размер бандла. Но, чтобы не приходилось анализировать бандл, лучше предотвратить его раздувание.
Это можно сделать на этапе CI с помощью size-limit.
Как использовать❓
1. Устанавливаем
2. Добавляем когфиг size-limit в
3. Добавляем запуск size-limit в скрипт, который вы запускаете на CI
Если вы пользуетесь гитхабом, то можете использовать GitHub action, который добавляет в качестве комментария изменение размера бандла.
Также size-limit поддерживает задание временных лимитов на исполнение вашего кода и использует для этого “безголовый хром”.
#frontend #performance #tools #ci
Вот здесь я писал про 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
GitHub
GitHub - ai/size-limit: Calculate the real cost to run your JS app or lib to keep good performance. Show error in pull request…
Calculate the real cost to run your JS app or lib to keep good performance. Show error in pull request if the cost exceeds the limit. - ai/size-limit
10👍10
У нас на проекте есть 2 основных правила для написания стилей:
- У всех CSS-классов должен быть префикс
- Мы используем БЭМ —
Однако есть большой пласт легаси стилей, где эти правила не используются.
И вот, при добавлении monaco-editor’а (текстовый редактор на котором построен VS Code) в новую фичу, прилетело ишью — у горизонтального и вертикального скролл-баров разная толщина.
А вся проблема в том, что наши глобальные стили для класса
Именно эту проблему и решают префиксы — позволяют избежать коллизии имён с библиотечными классами.
#css #bem
- У всех CSS-классов должен быть префикс
dp-, выбранный по названию продукта- Мы используем БЭМ —
<block>__<element>--<modifier>Однако есть большой пласт легаси стилей, где эти правила не используются.
И вот, при добавлении monaco-editor’а (текстовый редактор на котором построен VS Code) в новую фичу, прилетело ишью — у горизонтального и вертикального скролл-баров разная толщина.
А вся проблема в том, что наши глобальные стили для класса
slider применяются к элементу с таким же классом в monaco-editor. Именно эту проблему и решают префиксы — позволяют избежать коллизии имён с библиотечными классами.
#css #bem
1👍6❤🔥3
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
Только ленивый не написал, что 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
1👍12❤2
⏭️ Соседние селекторы в CSS
Сегодня утром прилетает баг - у элемента не виден горизонтальный скрол. Случилось это из-за новой фичи - появился новый компонент, из-за чего соседний немного съехал и скрол ушёл за пределы экрана.
Тут я подумал, что в первый раз в жизни смогу использовать "Родственные селекторы"
Посмотрел на разметку, понял что
Основные различия
-
-
Посмотрел на разметку ещё раз и понял, что элементы видны всегда, а не по условию, поэтому просто пофиксил стили для
#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
Журнал «Код» программирование без снобизма
Что такое соседние и родственные селекторы в CSS: объясняем на спринтерах — Журнал «Код» программирование без снобизма
Когда мы делали Шар судьбы на CSS, то встретили там родственные селекторы. Тогда мы про это поговорили вскользь, теперь разберём поглубже.
1👍14
Кажется, кто-то узнал, что программист приехал на отдых.
Сначала аэропорт SSH, теперь номер 11101, а дальше что?
Бустани канал, чтобы оставаться в курсе, а то мало ли что ...
#vacation
Сначала аэропорт SSH, теперь номер 11101, а дальше что?
Бустани канал, чтобы оставаться в курсе, а то мало ли что ...
#vacation
😁22❤3🍌2
Пока я сижу в Шереметьево и жду свой задерживающийся рейс в Мумбаи, расскажу вам кринжовую историю, которая произошла со мной сегодня утром в аэропорте Каира.
Я всегда стараюсь приезжать заранее, будь то поезд, автобус или самолёт. На всякий случай, мало ли что может случиться. Всегда всё проходит нормально, а я тупо жду на пол часа-час дольше, чем остальные, но не сегодня ...
Обычное утро, заказываем убер и едем в аэропорт, мы жили в районе Гелиополис, поэтому доехали минут за 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
Я всегда стараюсь приезжать заранее, будь то поезд, автобус или самолёт. На всякий случай, мало ли что может случиться. Всегда всё проходит нормально, а я тупо жду на пол часа-час дольше, чем остальные, но не сегодня ...
Обычное утро, заказываем убер и едем в аэропорт, мы жили в районе Гелиополис, поэтому доехали минут за 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
4👍19🔥7😁7
Пока я Индии поедаю сабудану и досу, мне в Курск пришла книга "Мама, Я тимлид!" от Жени Черкасова. Я конечно не тимлид, но книжку обязательно прочитаю.
Женя ведёт ламповый и очень уютный канал о личной и командной эффективности. Вот некоторые из моих любимых постов:
- Готовься к увольнению с первого дня
- Как всё успеть
- Сколько я заработал с блога
- Как на самом деле строятся процессы
А ещё Женя летает на параплане 😱, обязательно посмотрите.
А мне расскажите, читали ли вы книгу и как она вам.
#рекомендую_канал
@cherkashindev
Женя ведёт ламповый и очень уютный канал о личной и командной эффективности. Вот некоторые из моих любимых постов:
- Готовься к увольнению с первого дня
- Как всё успеть
- Сколько я заработал с блога
- Как на самом деле строятся процессы
А ещё Женя летает на параплане 😱, обязательно посмотрите.
А мне расскажите, читали ли вы книгу и как она вам.
#рекомендую_канал
@cherkashindev
❤4👍4
Отдельная страница для задач в Обсидиан
В🇯🇵 Notion мне всегда очень нравилось, что каждая запись в базе - это отдельная страница, которая может содержать что угодно - от простых заметок, до вложенных баз или таблиц.
Я использовал Notion, как менеджер задач, и эта возможность была критически важной для меня - работая над сложными задачами, я всегда делаю заметки:
- разбиваю на подзадачи
- записываю нюансы, на которые я наткнулся
- помечаю, какие тесты необходимо написать
Хотя в обсидиан это не поддерживается из коробки, но всё же достаточно легко реализуется:
- Для задач использую obsidian-tasks плагин, по сути это просто ToDo лист
- Если нужно сделать много записей по задаче или приложить скриншоты - то просто превращаем задачу в ссылку на заметку
- Оборачиваем задачу в Wikilink
- Заметка создастся в стандартной папке для заметок, папку можно задать в
#obsidian #notion
@cherkashindev
В
Я использовал Notion, как менеджер задач, и эта возможность была критически важной для меня - работая над сложными задачами, я всегда делаю заметки:
- разбиваю на подзадачи
- записываю нюансы, на которые я наткнулся
- помечаю, какие тесты необходимо написать
Хотя в обсидиан это не поддерживается из коробки, но всё же достаточно легко реализуется:
- Для задач использую obsidian-tasks плагин, по сути это просто ToDo лист
- Если нужно сделать много записей по задаче или приложить скриншоты - то просто превращаем задачу в ссылку на заметку
- Оборачиваем задачу в Wikilink
[[]] и нажимаем на неё, заметка с именем задачи создастся автоматически- Заметка создастся в стандартной папке для заметок, папку можно задать в
Settings => Files and links => Folder to create new notes in.#obsidian #notion
@cherkashindev
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤2