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

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

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

По всем вопросам: @denisputnov
Download Telegram
Что такое 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
Что такое декларативность и императивность?

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

// Императивный способ создания списка из элементов массива
const items = [1, 2, 3, 4, 5];
const ul = document.createElement('ul');

for (let i = 0; i < items.length; i++) {
const li = document.createElement('li');
li.textContent = items[i];
ul.appendChild(li);
}

document.body.appendChild(ul);


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

Декларативный же подход фокусируется на том, ЧТО нужно сделать. В декларативном стиле вы описываете результат, который хотите получить, а не процесс его достижения, например:

import React from 'react';
import ReactDOM from 'react-dom';

const items = [1, 2, 3, 4, 5];

const App = () => (
<ul>
{items.map(item => (
<li key={item}>{item}</li>
))}
</ul>
);

ReactDOM.render(<App />, document.getElementById('root'));


В этом примере с использованием React мы описываем, что хотим увидеть: список элементов. Мы не указываем, как именно React должен создать и добавить эти элементы, мы просто описываем структуру, которую хотим получить

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

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

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

@prog_way_blogчат#theory #code #javascript #principles
25👍13🔥6🐳2
Остановка распространения событий: event.stopPropogation и event.stopImmediatePropagation()

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

🟢event.stopPropagation()

Этот метод предотвращает дальнейшее распространение события в фазе захвата или всплытия. Это значит, что событие сработает только на event.target, то есть на самом элементе, но не на всех его родителях, как это сделано по умолчанию. Рассмотрим код:
document.getElementById('child').addEventListener('click', event => {
event.stopPropagation();
console.log('Ребёнок');
});

document.getElementById('parent').addEventListener('click', () => {
console.log('Родитель');
});


Так как мы используем event.stopPropogation(), в консоли мы увидим только Ребёнок. Без использования этого метода, мы увидим вывод: Ребёнок, Родитель

🟢event.stopImmediatePropagation()

Этот метод не только предотвращает дальнейшее распространение события к родителям, но и останавливает выполнение других обработчиков событий на том же элементе. Рассмотрим пример:
const element = document.getElementById('child')

element.addEventListener('click', event => {
event.stopImmediatePropagation();
console.log('Первый обработчик нажатия');
});

element.addEventListener('click', () => {
console.log('Второй обработчик нажатия');
});


При клике на элемент, в консоли мы увидим только лишь Первый обработчик нажатия. Второй обработчик не выполнится, потому что event.stopImmediatePropagation() остановил выполнение других обработчиков на этом элементе

Коротко о главном:

- event.stopPropagation() используется для остановки распространения события на родительские элементы
- event.stopImmediatePropagation() используется для полной остановки события, включая другие обработчики на текущем элементе


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

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

@prog_way_blogчат#theory #code #javascript
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥42👍112🐳2
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
Виды операторов в JavaScript

Операторы в языке (почти во всех языках, кстати), можно строго разделить на три категории:

1. Унарные операторы
Работают с одним операндом — то есть применяются только к одной переменной. Это, например, такие операторы, как i++ или --i, смены знака -i или отрицания !isTrue
let a = 5;
a++; // теперь a равно 6
let b = -a; // теперь b равно -6


Операнд — это элемент данных, над которым выполняется операция. В выражении i++ переменная i будет операндом, а ++ — оператором


2. Бинарные операторы
Бинарные операторы работают с двумя операндами. Это самые распространенные операторы, включающие арифметические, логические, сравнительные и присваивающие операции
const x = 10;
const y = 20;
const sum = x + y; // (+) - арифметический оператор
const isEqual = x == y; // (==) - сравнительный оператор


3. Тернарный оператор
Тернарный оператор — единственный оператор, который работает с тремя операндами и является сокращенной формой конструкции if-else. Он часто используется для кратких условий
const age = 31
const canKupitPivo = age >= 18 ? true : false


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

Операторы бывают трёх видов — унарные, бинарные и тернарные. Работают они с одним, двумя и тремя операндами соответственно

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

@prog_way_blogчат#theory #code #javascript
👍259🔥5🐳1
Как определить с какого устройства открыт сайт

Самым простым способом является анализ строки User-Agent’a — это специальный заголовок, который передаётся браузером устройства вместе с любым запросом.

Сразу рассмотрим на примере:
Запрос с айфона из Safari:
Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1

Запрос с комьютера из Google Chrome:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36


Из этой строки можно достать информацию об устройстве пользователя, его операционной системе и браузере.

Чтобы проанализировать строку, можно воспользоваться либо готовыми библиотеками, либо написать примерно такой код:
const isMobile = () => /Mobi|Android/i.test(navigator.userAgent)

if (isMobile()) {
console.log("Мобильное устройство");
} else {
console.log("Десктопное устройство");
}


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

Пригодиться это может в нескольких кейсах:

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


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

@prog_way_blogчат#theory #code #javascript
👍25🔥65🐳2
Что такое Callback Hell и как с ним бороться?

Частый вопрос с собеса, особенно если идти куда-то повыше стажёра.

Callback Hell — это ситуация в асинхронном программировании, когда вложенные друг в друга функции обратного вызова (он же callback) образуют "лесенку", что делает код трудным для чтения и сопровождения.

doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doAnotherThing(newResult, function(finalResult) {
doSomethingMore(finalResult, function(lastResult) {
console.log(lastResult);
});
});
});
});


Как с этим можно бороться?

Конечно же промисы и async/await синтаксис:

Промисы позволяют писать асинхронный код более линейно и читаемо благодаря цепочке вызовов (chaining):

doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doAnotherThing(newResult))
.then(finalResult => console.log(finalResult))
.catch(error => console.error(error));


А async/await — это более современный синтаксис над промисами, который так же позволяет развернуть вложенные колбеки в плоский код:

async function process() {
try {
const result = await doSomething();
const newResult = await doSomethingElse(result);
const finalResult = await doAnotherThing(newResult);
console.log(finalResult);
} catch (error) {
console.error(error);
}
}

process();


И о Promise, и о async/await у меня уже есть более подробные посты

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

@prog_way_blogчат#theory #code #javascript #patterns #data
🔥189👍9🐳3
Как открыть ссылку в новом окне или вкладке

Чтобы ссылка открывалась в новом окне или вкладке, достаточно добавить к тегу <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
Как отменить уже отправленный HTTP запрос?

Для отмены уже отправленного запроса нам пригодится встроенный в JavsScript объект — AbortController
Этот объект позволяет отменять уже запущенные асинхронные операции, fetch в том числе

const controller = new AbortController()

// отправляем запрос
fetch('https://.../', { signal: controller.signal })

// отменяем его
controller.abort()


Нужно это много где, я приведу самый очевидный пример с реактом:
Представим, что пользователь открывает страницу. На странице в useEffect идёт запрос к API, но пользователь, не дожидаясь ответа от сервера, переходит на другую страницу. Запрос есть, трафик занят, есть риск нарушения жизненного цикла компонента, а результаты этого запроса уже и вовсе не нужны. Вот так это решается:

useEffect(() => {
const controller = new AbortController()

// делаем запрос на маунт компонента
fetch('https://.../', { signal: controller.signal })

// отменяем запрос на анмаунт компонента
return () => controller.abort()
}, [])


Использование AbortController'a помогает избежать потенциальных утечек памяти и гарантирует, что запросы не будут выполняться после того, как компонент был размонтирован. Полезно это при любых запросах, так что можно смело сделать свой хук обёртку. Или просто использовать @tanstack/react-query 🌚

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

@prog_way_blogчат#theory #javascript #code #data
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3211🔥3🐳2🤯1🤩1
Разница между CommonJS и ES Modules

Если по простому, то CommonJS и ES (ECMAScript) Modules — это два способа импорта и экспорта чего либо из файлов в JavaScript

CommonJS — относительно старый API, который был разработан для NodeJS. Выглядит он следующим образом:
// Экспорт
module.exports = function() {
console.log(...);
};

// Импорт
const module = require('./module');
module();


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

Для браузера, синхронная загрузка — крайне неудачный подход из-за блокировки интерфейса в момент загрузки. Поэтому в браузере использовать CommonJS — моветон, лучше использовать ES Modules


ES Modules — это подход, который в язык принес ECMAScript 2015 (ES6). Он задумывался как замена устаревшему CommonJS и выглядит так:
// Экспорт
export function foo() {
console.log(...)
}

// Импорт
import { foo } from './module.js';
foo();


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

Также ES Modules могут использоваться не только в браузере, а и в NodeJS, начиная аж с 12 версии. Как же давно это было🥲


ИМХО, в современной разработке от CommonJS можно отказаться как от рудимента. Я стараюсь использовать модули по максимуму

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

@prog_way_blogчат#theory #javascript #code
👍3011🐳6🔥5
Как убрать стили на под-дереве — мини-задача с реального проекта

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

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


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

Обнулить все стили на под-дереве можно с помощью CSS свойства all. Выглядеть это может так:
.tailwind-reset-styles * {
all: revert;
}


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

Далее полученный класс .tailwind-reset-styles вешаем на родительский тег, все под-дерево которого уже будет со сброшенными ненаследуемыми стилями. Это, наверное, самое элегантное и быстрое решение, что можно придумать в этой ситуации

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

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

@prog_way_blogчат#theory #web #code
👍296🔥5🐳5
Что такое SWC и немного о Rust

SWC — это аббревиатура, которая всё чаще появляется в мире фронтенда. Расшифровывается это как Speedy Web Compiler и полностью оправдывает своё название, ведь SWC — это ультрабыстрый компилятор и пакетный обработчик, написанный на Rust. Он предназначен для преобразования современного JavaScript и TypeScript кода в код, который будет поддерживаться большинством браузеров. Возможно это во многом из-за полифилов, о которых я писал в этом посте

Если ещё проще, то SWC выполняет все функции Babel, только делает это в более чем 20 раз быстрее на одном ядре, и более чем в 70 раз быстрее на 4 ядрах.

Снова Rust всех победил 🤷‍♂️🤷‍♂️🤷‍♂️


Уже сейчас SWC используется в продуктах Vercel (в Next.js и Turbopack в том числе), Tencent, Shopify и других компаний, а также ложится в основу Vite начиная ещё с 4 версии (сейчас 5), так что с нами он плюс минус на долго

Да и больше про SWC сказать обзорно особо нечего. Мне во всём этом очень занимательно наблюдать за тем, какой огромный фокус на скорость появляется в фронтенде. Rust постепенно захватывает тулинг фронтенда: сборщики, компиляторы, линтеры и так далее — уже почти в каждой части тулинга есть решение на Rust и это, очевидно, не просто так

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

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

@prog_way_blogчат#theory #web #code
Please open Telegram to view this post
VIEW IN TELEGRAM
🐳397👍3🔥2
Про платные курсы и менторинг

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

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


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

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

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

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

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


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

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

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

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

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


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

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

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

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

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

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

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


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

@prog_way_blogчат#blog #useful
🐳4811👍10😐1
Что такое виртуализация?

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

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


Если объяснять на пальцах как это работает, то я бы сказал так:
Мы можем представить, что хотим послушать музыку. Открываем что-то типа Тындыкс.Музыки и видим 10.000 разных треков — это 10.000 строк огромного списка

Так вот, зачем отображать все 10.000 сразу, если на экране в лучшем случае поместиться треков 20-30? Давайте рисовать только первые, например, 50 треков, а дальше следить за тем что видит пользователь — за его скроллом. Если пользователь прокрутит ещё на 20 строк вниз, то мы нарисуем следующие 20 строк, а первые 20 удалим из вёрстки

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

Чаще всего это реализуют через события scroll на контейнере или через IntersectionObserver, подробности реализации для особо любопытных всегда доступны в сорсах библиотек (в TanStack Virtual можете начать с функции observeElementRect)

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

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

@prog_way_blogчат#theory #javascript #code #react
🐳26👍95🔥4