deepdigital | Unsorted

Telegram-канал deepdigital - Deep Digital

-

Разработка цифровых продуктов на современных технологиях и фреймворках с фокусом на финтех. Обсудить проект @YuraAndreev

Subscribe to a channel

Deep Digital

Восстановление состояния после применения git push --force

📌 Применение git push --force может быть необходимым в ряде ситуаций, например, для коррекции ошибок в истории коммитов. Однако ее использование может привести к потере данных в репозитории. Как вернуть состояние до применения команды? Решение есть!

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

+ deadbeef...f00f00ba master -> master (forced update)


Значение deadbeef является коммитом в ветке master до применения команды git push --force.

💡Для восстановления нам необходимо выполнить

git push --force origin deadbeef:master


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

Читать полностью…

Deep Digital

Объединение интерфейсов в TypeScript

🔥 Сегодня рассмотрим одну замечательную возможность TypeScript — объединение интерфейсов, или merging interfaces. Этот механизм позволяет создавать более гибкие и масштабируемые типы.

🛠 Как работает объединение интерфейсов?
TypeScript уникален тем, что позволяет сливать несколько объявлений интерфейса в одно. Если вы объявляете два интерфейса с одинаковым именем, TypeScript автоматически объединит их.

interface User {
name: string;
age: number;
}
interface User {
email: string;
}


Результирующий интерфейс User будет иметь свойства name, age и email
const user: User = {
name: 'Алексей',
age: 30,
email: 'alexey@example.com',
}

Читать полностью…

Deep Digital

Изучаем Array.prototype.flat()

Сегодняшняя тема посвящена одной из полезных функций, введенной в ECMAScript 2019, — методу Array.prototype.flat().

📚 Что такое Array.prototype.flat()?
Метод flat() позволяет «выровнять» многомерные массивы ранее заданной глубине. Это особенно полезно, когда вы работаете с массивами, структура которых может быть сложной или неизвестной.

🌐 Как работает Array.prototype.flat()?
flat() принимает один необязательный аргумент — глубину, которая указывает, насколько глубоко метод должен «выравнивать» массив. По умолчанию глубина равна 1.

Пример использования:

let multiDimensionalArray = [1, [2, 3], [4, [5, 6]]];

// Выравниваем на один уровень
let flatArray = multiDimensionalArray.flat();
console.log(flatArray); // Выведет: [1, 2, 3, 4, [5, 6]]

// Выравниваем на два уровня
let flatArrayDeep = multiDimensionalArray.flat(2);
console.log(flatArrayDeep); // Выведет: [1, 2, 3, 4, 5, 6]


@chulakov_dev

Читать полностью…

Deep Digital

CSS Logical Properties

CSS Logical Properties предоставляют альтернативу традиционным физическим свойствам, таким как width, height, margin, border, padding и подобным, для более адаптивного оформления веб-страниц. Они учитывают направление текста и другие языковые особенности.
CSS Logical Properties позволяют нам быть более гибкими в работе с мультиязычными интерфейсами и значительно сокращают количество кода, который нужно написать для адаптирования страниц под разные языки.
Вот несколько примеров использования.

Логические отступы:

.container {
margin-inline-start: 20px; /* Логический внутренний отступ слева (или справа) */
margin-block-end: 30px; /* Логический внутренний отступ вниз (в зависимости от направления текста) */
}


Логическая ширина и высота:
.elent {
inline-size: 200px; /* Логическая ширина */
block-size: 100px; /* Логическая высота */
}


Логические границы:
.box {
border-inline: 2px solid #333; /* Логическая граница в горизонтальном направлении */
border-block: 1px dashed #555; /* Логическая граница в вертикальном направлении */
}


Логические паддинги:
.content {
padding-inline: 15px; /* Логический внутренний отступ в горизонтальном направлении*/
padding-block: 10px; /* Логический внутренний отступ в вертикальном направлении */
}


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

@chulakov_dev

Читать полностью…

Deep Digital

Привет, друзья!

Предлагаем сегодня решить такую задачку. Нужно вывести в консоль числа от 0 до 10. Как вы думаете, будет ли код на картинке работать? Напишите в комментариях: да/нет и почему?

@chulakov_dev

Читать полностью…

Deep Digital

Всем привет!

Сегодня затронем важную тему — поверхностное и глубокое копирование в JavaScript.

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

chulakov_dev/5nHdVVKilSY">Читать пост

@chulakov_dev

Читать полностью…

Deep Digital

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

Инвариантность
Инвариантность означает, что тип является неизменным относительно других типов. В контексте обобщений, если у вас есть обобщенный тип например MyType<T>, MyType<A> и MyType<B> не считаются связанными друг с другом, даже если типы A и B связаны отношением наследования.

Ковариантность
Ковариантность позволяет использовать подтипы вместо основного типа. Это означает, что если у вас есть обобщенный тип MyType<out T>, то MyType<A> является подтипом MyType<B>, если A является подтипом B. Ковариантные типы могут использоваться только в «выходных» позициях.

fun main() {
val producerA: Producer<A> = ProducerImplA()
val producerB: Producer<B> = producerA
}
interface Producer<out T> {
fun produce(): T
}
class A : B()
open class B

В этом примере Producer<A> является подтипом Producer<B>, поэтому мы можем присвоить producerA (тип Producer<A>) переменной producerB (тип Producer<B>).

Контравариантность
Контравариантность позволяет использовать супертипы вместо основного типа. Это означает, что если у вас есть обобщенный тип MyType<in T>, то MyType<A> является супертипом MyType<B>, если A является супертипом B. Контравариантные типы могут использоваться только во «входных» позициях.

fun main() {
val consumerB: Consumer<B> = ConsumerImplB()
val consumerA: Consumer<A> = consumerB
}
interface Consumer<in T> {
fun consume(item: T)
}
open class B
class A : B()

В этом примере Consumer<B> является супертипом Consumer<A>, поэтому мы можем присвоить consumerB (тип Consumer<B>) переменной consumerA (тип Consumer<A>).

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

@chulakov_dev

Читать полностью…

Deep Digital

box-shadow VS drop-shadow

⚡️Привет! Сегодня разбираемся с разницей свойства box-shadow и фильтра drop-shadow.

Свойство box-shadow добавляет к блоку одну или несколько теней. Оно принимает либо значение none, что означает отсутствие теней, либо список теней, разделенных запятыми в порядке от переднего к заднему.

drop-shadow применяет эффект падающей тени к входному изображению. Тень представляет собой размытую смещенную версию альфа-маски входного изображения, нарисованную определенным цветом и расположенную под изображением. Значения интерпретируются как для box-shadow, но с опциональным третьим вариантом, который является стандартным отклонением, а не радиусом размытия.

📎 В чём же разница?
box-shadow дает нам тень, охватывающую весь элемент, даже если элемент не имеет фона.
drop-shadow применяется не к самому элементу, а к его визуальному представлению, включая прозрачные части и создает тень только от непрозрачных частей элемента. Помимо этого, drop-shadow не поддерживает ключевое слово inset, которое превращает тень из внешней во внутреннюю.

Радиус размытия в свойстве box-shadow в CSS определяет, насколько сильно тень будет размыта и растянута относительно элемента: чем больше значение радиуса, тем больше тень и тем меньше её чёткость.

С другой стороны, стандартное отклонение в drop-shadow аналогично радиусу размытия в box-shadow. Но, поскольку drop-shadow применяется к визуальному изображению элемента, эффект может выглядеть иначе, особенно если элемент имеет прозрачные области.

Пример использования:

.drop_shadow {
filter: drop-shadow(0 0 16px #000);
}


.box_shadow {
box-shadow: 0px 0px 16px #000;
}

Читать полностью…

Deep Digital

Этапы рендеринга в браузере

Давайте вспомним, как это происходит 🤓

1. Загрузка ресурсов (Loading): браузер загружает HTML-документ и связанные ресурсы, такие как стили CSS, скрипты JavaScript, изображения и медиафайлы.

2. DOM: из полученного HTML-документа формируется Document Object Model (DOM).

3. CSSOM: параллельно с DOM браузер обрабатывает стили CSS и формирует CSS Object Model (CSSOM).

4. Accessibility Tree: параллельно с DOM и CSSOM формируется Accessibility Tree, которое содержит информацию о структуре веб-страницы и ее элементах для вспомогательных технологий.

5. Render Tree: на основе DOM и CSSOM формируется дерево рендеринга (Render Tree), содержащее только видимые элементы и их стили.

6. Scripting: выполнение JavaScript, который может изменять DOM и CSSOM, что приведет к повторным процессам рендеринга.

7. Layout: браузер вычисляет положение и размеры каждого элемента в Render Tree (Layout или Reflow).

8. Painting: отрисовка элементов на странице на основе информации из Render Tree.

9. Composite: разбиение отрисованных элементов на слои и их объединение для формирования окончательного изображения страницы.

10. Оптимизация производительности и кеширование: применение методов оптимизации и кеширование для улучшения производительности загрузки и рендеринга.

11. Обработка событий: взаимодействие пользователя с веб-страницей может вызывать обновления DOM и запускать новые циклы рендеринга.

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

@chulakov_dev

Читать полностью…

Deep Digital

Разбираемся в разнице: target="_blank" и target="blank" в HTML

🌐 Привет! Сегодня мы разберем интересный вопрос: в чем разница между target="_blank" и target="blank" при использовании в HTML? Детали могут показаться незначительными, но на практике они оказывают большое влияние на поведение ссылок в ваших веб-приложениях.

🎯 target="_blank"
Это стандартный способ открытия ссылки в новой вкладке браузера.

Каждый раз при клике на ссылку создается новая вкладка или новое окно браузера.
Пример использования:

<a href="https://example.com" target="_blank">
Открыть example.com в новой вкладке
</a>


🆚 target="blank"
При использовании target="blank" (без нижнего подчеркивания) браузер ведет себя по-другому.
"blank" здесь рассматривается как название фрейма, а не как ключевое слово. Если браузер не находит фрейм с таким именем, он создает новую вкладку с этим именем.
Повторные клики на разных ссылках с target="blank" будут перезаписывать содержимое одной и той же вкладки, вместо того чтобы открывать новую вкладку каждый раз.

Пример использования:

<a href="https://example.com" target="blank">
Открыть example.com в именованном фрейме/вкладке "blank"
</a>


💡 Это знание особенно ценно, когда вы сталкиваетесь с ситуацией, в которой ссылка, предположительно с target="_blank", не открывается в новой вкладке или открывается только один раз.

Осознание того, что target="blank" без нижнего подчеркивания ведет к созданию одной постоянной вкладки для всех ссылок, может сэкономить вам много времени при отладке и поиске проблем в вашем коде.

@chulakov_dev

Читать полностью…

Deep Digital

infer в примерах

Ключевое слово infer используется в контексте условных типов TypeScript для их автоматического вывода в определенных ситуациях и не может применяться вне расширения.

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

Другими словами, когда вы сталкиваетесь со сложными типами в TypeScript, infer помогает вытащить или определить неизвестные части этих типов, делая ваш код более гибким и легким для понимания.

Вы можете представить его как способ сказать TypeScript: «Выясни сам, какой здесь тип, и дай мне его использовать». Это особенно полезно, когда вы работаете с функциями или классами, где точные типы не всегда ясны из контекста.

Примеры применения ключевого слова infer.

1. Вывод типов из аргументов функции:

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function add(a: number, b: number): number {
return a + b;
}

type Result = ReturnType<typeof add>; // Result будет иметь тип number


2. Примеры с рекурсивными типами.
Реализация типа Reverse:
type actually = "123123123"

type Reverse<T extends string, R extends string = ""> = T extends `${infer Head}${infer Rest}`
? Reverse<`${Rest}`, `${Head}${R}`>
: R;

type result = Reverse<actually>; // "321321321"

Реализация типа Replace:
type actually = "912342181";
type Replace<T extends string, U extends string, R extends string = ""> = T extends ${infer Head}${infer Rest}
  ? Head extends U ? Replace<`${Rest}`, U, R> : Replace<`${Rest}`, U, `${R}${Head}`>
  : R;
 
type result = Replace<actually, "1">; // "923428"


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

Читать полностью…

Deep Digital

Продолжаем серию заметок про запуск проекта с использованием Strapi. В первом посте мы рассказали, как собрать свой образ Strapi, а во втором — как запускать его в docker-окружении. Сегодня мы настроим подключение Strapi к базе данных Postgres.

chulakov_dev/podkluchenie_Strapi_k_Postgres">👉🏻 Читать инструкцию

@chulakov_dev

Читать полностью…

Deep Digital

Привет, друзья!

15-16 сентября в Ульяновске пройдет международная IT-конференция «Стачка», на которой выступит наш Frontend Team Lead Альберт Рыбалко с докладом «Таймеры в HTML5».

Спикер расскажет, что такое Host и почему он важен при работе с Web Api, подробно разберет работу таймеров и методы их очистки, а также объяснит, как микрозадачи выполняются в окружении JavaScript и какую роль они играют в асинхронном программировании.

Альберт выступит в секции «FrontEnd» 16 сентября.

@chulakov_dev

Читать полностью…
Subscribe to a channel