alexgriss.tech
1.23K subscribers
31 photos
6 videos
67 links
Я — Александр Григоренко, фронтенд-архитектор и продуктовый инженер.

Пишу о зрелом инженерном мышлении, лидерстве, архитектуре и продуктовой разработке, создаю https://webaudio.studio

Сайт: https://alexgriss.tech
ТГ: @astroscientist
Download Telegram
В процессе работы над статическим сайтом пришлось поменять стратегию работы с API. Я решил сменить WordPress на другую CMS, в которой смогу задать необходимые структуры данных с нуля. Мой выбор остановился на Strapi — опенсорсной «безголовой» CMS, написанной на Node.js и TypeScript.

Сайт-лендинг, над которым я работаю, состоит из нескольких блоков, структура которых более-менее строго задана в вёрстке, а вот контент в них будет со временем меняться. Для удобного контент-менеджмента мне нужен инструмент, в который будет легко перенести логику блоков и работать с содержимым соответствующих полей. Поначалу я хотел как-то хитро использовать заложенную в WordPress архитектуру страниц, записей и категорий, чтобы построить на ней апишку для блоков лендинга. На практике оказалось не всё так просто: если этого монстра и можно приручить для такой задачи, то только с определённым шаманством, использованием плагинов для создания дополнительных таксономий и пользовательских полей. Я понял, что лучше уж сразу использовать что-то более гибкое — по-настоящему «безголовую» CMS, — а не отрезать бэкенд от монолитного WordPress.

Strapi устанавливается и настраивается буквально за пять минут, особенно, если использовать встроенную СУБД по умолчанию — SQLite. В npm-пакет Strapi встроены интеграции с MySQL, Postgres и MariaDB, но сами оболочки для работы с соответствующими базами данных нужно устанавливать отдельно. После установки будет доступна админка, в которой создаются и настраиваются поля для API. Там же эти поля заполняются необходимым контентом. В админке встроены все необходимые типы полей: от текста и картинок до произвольного JSON, а богатая экосистема плагинов позволяет серьёзно расширить этот список. Плагины для Strapi живут как отдельные npm-пакеты. Например, @strapi/plugin-graphql добавляет функциональность GraphQL и создаёт эндпоинт для запросов и мутаций. Его-то я и собираюсь использовать для общения с фронтендом, написанным на Astro+Svelte.

Кроме работы с API в Strapi предусмотрена система авторизации на токенах, работа с поисковой оптимизацией (SEO), интернационализация, а также заложен практически безграничный потенциал для масштабирования функционала сайта вплоть до полноценного блога и каталога товаров/услуг.

Пока что выбор в пользу Strapi выглядит хорошим решением:

— лёгкая в управлении и работе с данными админка;
— работает быстрее, чем WordPress;
— куда лучше кастомизируется, чем WordPress;
— существует как набор npm-пакетов, в целом сильно продвинутее DX (developer experience);
— не привязывает к архитектуре страниц, записей и категорий, даёт полную свободу в выборе структуры API.

Буду продолжать сериал про сеньора, который решил заморочиться и разработать лендинг на самом современном стеке 🤵
Please open Telegram to view this post
VIEW IN TELEGRAM
👍43
Но мне только спросить...
😁4
Сегодня хочу поделиться подборкой фишек языка TypeScript, которые могут быть полезны в повседневной работе.

🔤«Ленивая» типизация параметров функции через запрос типов typeof

В TypeScript существует очень удобный способ типизации функций через механизм запроса типов. Он будет полезен для указания типов при написании юнит-тестов, особенно при использовании параметров функции, написанных через объект.


const testPerson = {
name: "Aleksandr",
age: 31,
occupation: "developing frontend"
};

const generateGreeting = (person: typeof testPerson) => {
return `Hello! My name is ${person.name}. I am ${person.age} years old. My occupation is ${person.occupation}.`;
}


Таким образом, используя typeof, не придётся писать дополнительную декларацию типов для тестируемой функции, а при обращении к свойствам объекта person сработает автодополнение.

🔤Шаблонные строковые типы

Скорее всего в JavaSсript вам приходилось сталкиваться с таким инструментом как шаблонные строки. Как раз выше в примере с typeof я использую их для формирования строки из комбинации обычных строковых литералов и переменных, которые содержат строки или могут быть к ним преобразованы. В TypeScript этот же синтаксис можно использовать для генерации комбинаций строковых типов:


type Sides = "top" | "right" | "bottom" | "left";
type Styles = "none" | "dotted" | "dashed" | "solid";

/**
* type BorderStyle = "border-top: none;" | "border-top: dotted;" | "border-top: dashed;" | ... | "border-left: solid";
*/
type BorderStyle = `border-${Sides}-style: ${Styles};`;


🔤Утверждение типа

Часто в коде на TypeScript может встретиться оператор as — он необходим для так называемого утверждения типа (type assertion). Утверждение типа — это способ заставить компилятор работать с тем типом, который мы явно определяем для значения, хотя автоматически TypeScript вычисляет для этого значения другой тип.

Классический пример использования утверждения типа — это работа с DOM API:


const input = document.querySelector('.input'); // Компилятор TS по умолчанию считает типом DOM-элемента тип Element

const inputValue = input.value; // Ошибка: Свойство "value" не существует в типе "Element"


С использованием as:


const input = document.querySelector('.input') as HTMLButtonElement;

const inputValue = input.value; // Мы явно утвердили тип HTMLButtonElement для элемента, теперь можно обратиться к свойству value


Другой довольно распространённый пример использования as — это перебор свойств объекта и утверждение типов для его ключей. Продемонстрирую это на примере react-компонента формы:


const INPUTS = {
name: "Имя",
email: "Электронная почта",
password: "Пароль",
};

// Внутренности React-компонента
{Object.keys(INPUTS).map((name) => (
<input
key={name}
type={name === "name" ? "text" : name}
placeholder={INPUTS[name as keyof typeof INPUTS]}
/>
))}


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

🔤Как получить тип всех параметров функции

Для получения типа параметров функции в TypeScript существует расширенный тип Parameters<T>. В качестве аргумента он требует запрос типа функции через оператор typeof, на основе которого будет получен кортеж (строго заданный по количеству и типам элементов массив) со всеми параметрами функции. Рассмотрим на примере:


const functionWithManyParams = (a: number, b: string, c: boolean, d: object = {}) => {};

/**
* type FunctionParams = [a: number, b: string, c: boolean, d?: object]
*/
type FunctionParams = Parameters<typeof functionWithManyParams>;


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

———

На сегодня это все фишки TypeScript, о которых я хотел бы рассказать. Если хотите узнать больше про язык TypeScript и его особенности, рекомендую почитать отличный учебник на русском языке: https://github.com/nauchikus/typescript-definitive-guide/tree/master/book/ru/chapters
Please open Telegram to view this post
VIEW IN TELEGRAM
👍52🔥2👏1
Кроме шуток, лет 10 назад такие технологии как jQuery, Bootstrap и модули на RequireJS составляли полноценный фреймворк с исключительной кроссбраузерностью (поддерживался даже IE 6), зоопарком возможностей для управления DOM-деревом и пользовательскими событиями, встроенными хелперами для AJAX-запросов, технологичными эффектами и анимациями, бесконечной библиотекой плагинов от очень активного коммьюнити — эти технологии были фактически фундаментом фронтенда тех лет.

Ландшафт начал очень сильно меняться с приходом следующих инструментов:

👩‍💻 React с его Virtual DOM — сложные обновления интерфейса стали на порядок проще в разработке и быстрее в исполнении, а концепция переиспользуемых компонентов определила основной способ организации кода;

👩‍💻 ES6 — мощный DOM API полностью заменил селекторы jQuery, для управления сложной асинхронной логикой появились промисы, ну и чего только стоит встроенная система модулей, импортов и экспортов. Применять новые возможности на практике помог 👩‍💻 Babel, который транспилирует новейший код в поддерживаемый старыми браузерами;

👩‍💻 Webpack взял на себя задачу сборки модульного ES6-кода, тем самым полностью заменив неуклюжий RequireJS;

👩‍💻 А у коммьюнити появился мощный инструмент для хранения и распространения библиотек — менеджер пакетов npm в составе 👩‍💻 Node.js.

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

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

Я вижу свою задачу в том, чтобы доступно рассказывать об этой сложности, о том, как отслеживать, куда всё движется дальше и как можно не только удержаться в профессиональном «седле», но и делать крутой качественный современный веб на высоком уровне.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥3
Пока я готовлю свою первую статью на Хабр, хочу напомнить о редко используемых или относительно новых операторах в JavaScript.

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

??Nullish coalescing operator (оператор нулевого слияния)

Что означает

Оператор нулевого слияния — это логический оператор, возвращающий значение правого операнда, если значение левого содержит null или undefined.

Как пишется

const nullValue = null;
const someValue = "Какое-то значение";
const zeroValue = 0;

const valueA = nullValue ?? "Вот уж не надо нам null'ов!";
const valueB = someValue ?? "А здесь значение есть";
const valueC = zeroValue ?? "Сюда не дойдём, так как в левой части выражения число 0";

console.log(valueA) // "Вот уж не надо нам null'ов!"
console.log(valueB) // "Какое-то значение"
console.log(valueС) // 0;


Если мы составим цепочку из операторов ??, то операция остановится на первом значении, которое определено:

const valueA = null;
const valueB = "Остановитесь на мне!";

console.log(valueA ?? valueB ?? "А как же я?"); // "Остановитесь на мне!"


В чём особенности

Этот оператор является частным случаем логического оператора ИЛИ ||. Но если в случае с ИЛИ правый операнд возвращается при любом ложноподобном значении левого операнда, то при использовании ?? значениями левого операнда могут быть только null или undefined. Оператор нулевого слияния удобно использовать, если такие значения как 0, "", false или NaN считаются валидными и не могут быть отброшены.

Очень часто оператор ?? используется для проверки наличия определённого свойства в объекте или наличия у этого свойства значения:

const object = {
someProperty: "У меня всё в порядке со значением",
nullProperty: null
};

console.log(object.someProperty ?? "До сюда не дойдём"); // "У меня всё в порядке со значением"
console.log(object.nullProperty ?? "А вот тут уже нас ждут"); // "А вот тут уже нас ждут"
console.log(object.undefinedProperty ?? "Что-то такого свойства не найдено :("); // "Что-то такого свойства не найдено :("


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

??=Nullish coalescing assignment (оператор нулевого присваивания)

Что означает

Оператор нулевого присваивания позволяет присвоить значение правого операнда переменной, указанной в левом операнде, если значение этой переменной содержит null или undefined.

Как пишется

let name;
let age = 31;

name ??= "Aleksandr";
age ??= 100;

console.log(name); // "Aleksandr"
console.log(age); // 31


В чём особенности

Оператор нулевого присваивания позволяет элегантно решить такую часто встречающуюся задачу, как переопределение переменной, у которой значение не определено или задано как отсутствующее. Ранее для этого использовалась громоздкая конструкция:

let name;

if (name === null || name === undefined) {
name = "Aleksandr";
}
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍3🔥2
||=Logical OR assignment (логическое присваивание ИЛИ)

Что означает

Оператор логического присваивания ИЛИ позволяет присвоить значение правого операнда переменной, указанной в левом операнде, если значение этой переменной при приведении его к false будет ложноподобным. Иными словами — если значение переменной, указанной слева от оператора ||= не приводится к true, то этой переменной присваивается значение, указанное справа от оператора.

Как пишется


let name = "";

name ||= "Aleksandr";

console.log(name); // "Aleksandr"


В чём особенности

Оператор логического присваивания ИЛИ призван упростить задачу проверки значения на истинность и последующего переопределения переменной через условную конструкцию if:


let name = "";

if (!name) {
name = "Aleksandr";
}


&&=Logical AND assignment (логическое присваивание И)

Что означает

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

Как пишется


let name = "Aleksandr";

name &&= name + " Grigorenko";

console.log(name); // "Aleksandr Grigorenko"


В чём особенности

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


const getData = () => data || null; // Сервис, который получает данные откуда-то извне и может вернуть null

let localData = getData();

localData &&= { ...localData, ...otherLocalData }; // Если данные, полученные из сервиса определены, обогатим их дополнительными данными


?.Optional chaining (Опциональная цепочка)

Что означает

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

Как пишется

Довольно частая проблема обращений к объектам в JavaScript — отсутствующие свойства или их значения и, как следствие, нарушающие взаимодействие с программой рантайм-ошибки:


const user = {};

console.log(user.name.toUpperCase()); // Ошибка: Uncaught TypeError: user.name is undefined


Данных ошибок можно избежать, если использовать опциональные цепочки:


const user = {};

console.log(user?.name?.toUpperCase()); // В консоль выведется undefined


В чём особенности

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

Как пример, это может быть полезно при работе с DOM API:


const element = document.querySelector('.element')?.innerHTML; // Не будет ошибки, если DOM-элемент не найден


Или в случае с попыткой обратиться к свойствам несуществующего элемента массива:


const users = [{ name: "Pavel", age: 28 }];

const userAge = users.find(user => user.name === "Aleksandr")?.age; // С использованием опциональной цепочки вернёт undefined, иначе бы завершилось ошибкой: Uncaught TypeError: users.find(...) is undefined


Как я уже упоминал выше, оператор опциональной цепочки удобно использовать совместно с оператором нулевого слияния ??, чтобы отработать случай, если обращение к свойству или методу объекта вернёт undefined:


const user = {};

console.log(user?.name?.toUpperCase() ?? "ALEKSANDR"); // В консоль выведется "ALEKSANDR"


———

На сегодня это все операторы JavaScript, о которых я хотел рассказать. Если хотите узнать больше об этих или напомнить себе про другие операторы в JS, рекомендую почитать соответствующий раздел на mdn web docs:
🇬🇧 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators
🇷🇺 https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍2
Внезапная рубрика «Дневники разработчика»

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

Мораль тут такая: не нужно бояться попросить нанять больше тестировщиков в команду иногда залезть в чужой код, так как это может помочь эффективнее решить задачу в условиях, когда другие варианты замедлят её решение, а также позволит глубже разобраться в том, как устроена командная разработка.
👍4221😎11
Сегодня я разместил свою первую статью на Хабре, где рассмотрел особенности работы HTML-элемента <dialog>: https://habr.com/ru/articles/778542/

Идея этой статьи родилась в процессе реализации личного проекта, в котором мне удалось попробовать разные не совсем привычные, но очень интересные и перспективные технологии. На проекте требовалась модалка, и передо мной встал вопрос: какое решение для неё выбрать и стоит ли дать шанс нативному элементу <dialog>?

Оказалось, что ещё как стоит, ведь он:

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

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

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

Приглашаю подписываться и участвовать в обсуждениях, будет много интересного!
5🔥3👀2
Комментарий к статье про элемент <dialog> на Хабре подтолкнул меня к размышлению и развёрнутому ответу на тему того, почему хорошая нативная реализация подобных компонентов будет лучше, чем альтернативное решение на JS, даже если оно учитывает все требования к работе компонента. Хочу процитировать вопрос пользователя:

Вам не кажется, что с полифилом получается сложновато, а JS реализации универсальны и не требуют ни переписывания, ни полифила?


А также частично мой ответ:

Я считаю, что JS-реализации по умолчанию хуже полноценного нативного стандарта, потому что разработаны и поддерживаются не производителями конечных технологий — браузеров, а такими же разработчиками, как и мы с вами. Как следствие, эти реализации могут перестать поддерживаться в будущем. Кроме того, они могут использовать различные хаки и нестандартизированные приёмы для того, чтобы эмулировать поведение, которое работает в нативных реализациях. К примеру, в них может эмулироваться функциональность глобального атрибута inert, блокирующего действия над остальной страницей под модальным окном или же поведение фокуса, которое давно стандартизированно в нативной реализации. В конце концов, такие реализации могут быть слишком тяжеловесными в рамках конкретного проекта, да и в целом это лишняя внешняя зависимость [в node_modules].


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

А ещё они не захламляют папку с npm-модулями.
👍62
Решил не забывать и о своём сайте, опубликовал свежую запись про генераторы статических сайтов (SSG-фреймворки) и, в частности, про полюбившийся мне Astro.

Статья доступна по ссылке: https://alexgriss.tech/blog/ssg-astro/

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

Ставьте реакции к этому посту, особенно если тема показалась интересной и хотелось бы узнать больше о технических подробностях работы с Astro.
👍72
Почему-то не существовало подобного мемаса, решил исправить ситуацию 🤵
Please open Telegram to view this post
VIEW IN TELEGRAM
5😁3🤔1
This media is not supported in your browser
VIEW IN TELEGRAM
Сегодня мне одобрили участие в приватном бета-тестировании генеративного инструмента v0.dev от Vercel, и это прям огонь! Эта штука генерирует несколько рабочих прототипов интерфейса на основе текстового промпта, выдаёт готовый код HTML-разметки и даже разбивает его на React-компоненты с Tailwind-классами 😳

Выглядит как потенциально крутой инструмент для прототипирования UI и как очень интересное применение возможностей генеративного искусственного интеллекта. А вы что думаете, стали бы использовать такое в работе?
🔥6
Совсем недавно вышла новая мажорная версия 👩‍💻 Astro 4.0, и я хотел рассказать об основных изменениях, которые появились с обновлением. Может показаться, что существенных нововведений не так много, и в целом покажется правильно. Но для меня это лишний показатель того, что Astro — уже достаточный зрелый, хоть и относительно свежий инструмент для генерации статических сайтов, который продолжает развиваться в сторону улучшения тулинга, скорости сборки и удобства использования основных API, тем самым создавая лучший developer experience.

🚀 Давайте пройдемся по основным нововведениям Astro 4.0:

Тулбар для разработчика. В режиме разработки появился компонент, который появляется внизу страницы и позволяет получить быстрый доступ к инструментам разработчика. В тулбар встроены такие возможности как инспектор интерактивных элементов, написанных на сторонних UI-библиотеках типа React, Vue или Svelte («островов»), а также помощник для решения проблем с доступностью (accessibility). Но главная особенность — это возможность добавлять свои собственные инструменты или устанавливать готовые из каталога Astro. Для разработки своих инструментов есть отдельное API, но в каталоге с интеграциями пока что нет чего-то действительно полезного — впрочем, времени с выхода новой версии прошло совсем ничего.

Увеличение скорости билда больших коллекций с контентом. Эта фича порадует владельцев блогов и статических каталогов, которые построены на основе большого количества записей, описанных как коллекции с контентом в виде markdown или json/yaml файлов. Благодаря отслеживанию и кэшированию тех файлов, которые не изменились между билдами, скорость сборок повышается практически в два раза. Стоит упомянуть, что эта фича пока экспериментальная, так что требует специального флага experimental.contentCollectionCache в настройках проекта.

Новые возможности View Transitions API. <ViewTransitions /> — это встроенный в Astro компонент, который перехватывает переходы между страницами и позволяет внедрить собственную функциональность в процесс этих переходов. При помощи минимального количества JS-кода этот компонент позволяет добавить новый слой интерактивности для статических страниц — например, активировать анимации при переходе между страницами или сохранить и передать состояния страниц между переходами. Это позволяет программировать опыт, который можно получить только в Single Page Applications, но для статических HTML-страниц. В последней версии Astro были добавлены новые возможности при переходах между страницами, правда они будут интересны только опытным разработчикам Astro. Для первого знакомства с View Transitions API лучше начать с туториала на официальном сайте: https://docs.astro.build/en/tutorials/add-view-transitions/.

Мультиязычность, основанная на роутинге, теперь в стабильной версии. Теперь вы можете смело указывать локали для вашего сайта в конфигурации проекта и генерировать многоязычные страницы в зависимости от структуры файлов в директории src/pages. Подробнее можно почитать тут: https://docs.astro.build/en/guides/internationalization/.

***

Это все основные изменения, которые появились в новой версии Astro. Не могу сказать, что это достаточное количество и качество новшеств для мажорной версии, но я в любом случае планирую использовать всю мощь и удобство этого фреймворка для будущего переезда своего блога https://alexgriss.tech с WordPress на Jamstack, в который входит и Astro (чуть позже я расскажу, что такое этот Jamstack и с чем его едят). Я хочу попробовать использовать коллекции контента для постов и формат MDX, который позволяет встраивать динамический JSX прямо в markdown. Так что ускорение скорости сборки коллекций уж точно не помешает.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Приглашаю почитать мою свежую статью на Хабре про эмуляцию бэкенда и мокинга API с помощью такого инструмента как Mock Service Worker: https://habr.com/ru/articles/780200/

Я работаю в одном из крупнейших банков РФ, и на моём проекте возникла ситуация, в которой у меня нет прямого доступа к бэкенду при разработке. Это сделано из соображений безопасности в работе с персональными данными клиентов банка. Бэкенд функционирует только в боевом контуре и доступен через виртуальную машину, поэтому мне пришлось искать способ полноценной эмуляции бэкенда на клиентской стороне. Я потратил много времени на изучение и сравнение существующих решений, но остановился именно на Mock Service Worker, так как для его использования не нужен отдельный сервер, который генерирует фейковые данные. Эта технология реализована в библиотеке msw, которая предоставляет широкий набор возможностей для очень точной эмуляции сетевого поведения и тестирования различных пользовательских сценариев.
👍6🔥3
Сегодня хочу поделиться ссылкой на глубокий и подробный обзор механик и внутренних особенностей работы браузеров, таких как: механизм рендеринга, синтаксический анализ HTML и CSS, оптимизации в вычислениях и перерисовках и много чего ещё интересного: https://web.dev/articles/howbrowserswork?hl=ru

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

В конце статьи заботливо приведены ссылки на дополнительные материалы по браузерной архитектуре и устройству конкретных движков для тех, кто хочет погрузиться в тему с головой.
👍10
Ранее у меня на сайте выходила статья про Static Site Generators и Astro: https://alexgriss.tech/blog/ssg-astro/

Эти технологии прочно связаны с так называемым Jamstack — подходом разработки контент-ориентированных сайтов, призванном заменить стандартные подходы с использованием тяжеловесных CMS и написанием неповоротливых одностраничных JavaScript-приложений.

По моему мнению, Jamstack — это новый виток эволюции разработки самых простых веб-сайтов. Ранее мы испытывали проблемы инструментального характера — мощности и гибкости сборщиков сайтов типа Gulp было недостаточно, все основные силы сообщества перетекли в продвинутый JavaScript-тулинг и поддержку экосистемы популярных фреймворков. Мы пытались строить самые простые сайты как SPA на React и Vue, пробовали оседлать SSR-монстров типа Next.js, продолжали разворачивать LAMP для установки WordPress, и совсем забыли, что веб-сайты — это просто HTML, CSS и JavaScript. Архитектурный подход Jamstack позволяет использовать всю мощь современных фронтенд-инструментов, и получать на выходе очень лёгкие и быстро работающие HTML-страницы с минимальным размером JavaScript-кода.

Статью-обзор можно почитать на моём сайте по ссылке: https://alexgriss.tech/blog/jamstack/
👍3
Тема про бессмысленность алгоритмических собеседований наболевшая, особенно у фронтенд-разработчиков. Лично я считаю самыми лучшими собеседованиями те, в которых умение грамотно рассуждать проверяется на реальных, приближенных к боевому опыту задачах, а не на абстрактных тренажёрах с leetcode.

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

Ставьте 🤵, если согласны.
Please open Telegram to view this post
VIEW IN TELEGRAM
13🤷‍♂1
😁33👍2
Я не понимаю, почему 👩‍💻 Tailwind внезапно стал модной заменой обычного CSS. Неужели миллион однозадачных классов на однотипных элементах лучше, чем один, но самописный и продуманный?

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

▶️ Лёгкость использования. C Tailwind вам нужно знать не только все CSS-свойства и их значения, но и встроенные во фреймворк алиасы для их использования. Вы думали, что утилитарный класс .p-10 означает CSS-правило padding: 10px;? Вот и нет, Tailwind так зашифровал внутренние отступы размером в 2.5rem. Будьте добры выучить это и ещё несколько сотен специфических классов.

▶️ Скорость и удобство написания стилей. Если в вашей вёрстке десять одинаковых пунктов меню, то копировать нагромождение классов придётся для всех десяти. Знаю, что объединять одинаковые наборы классов в один общий класс можно с помощью директивы @apply, но для этого нужно отойти от чисто инлайнового подхода написания стилей прямо в HTML и создать отдельный файл со стилями для утилитарных классов поверх наборов утилитарных классов. При этом использование @apply возвращает проблему инкапсуляции стилей и нейминга, о которой речь пойдёт в следующем пункте.

▶️ Не нужно задумываться о нейминге. Считаю это скорее минусом, чем плюсом, так как необходимость контроля над неймингом позволяет принимать более осмысленные решения при написании разметки и стилей. Я до сих пор готов рекомендовать подходы БЭМ и CSS Modules для работы с нативным CSS и решения проблем инкапсуляции стилей. Возможно, через несколько лет с распространением @scope решатся все боли верстальщиков, но сейчас я точно не вижу, чем набор лапши типа bg-white shadow-md rounded-md p-4 hover:shadow-lg transition duration-300 ease-in-out hover:bg-gray-200 лучше адекватно именованного БЭМ-класса или CSS модуля.

▶️ Небольшой размер файлов стилей. Да, в экосистему Tailwind встроена утилита, которая при сборке проекта может порезать лишние неиспользуемые классы. Однако, обычно требуется произвести нетривиальную настройку, чтобы добиться действительно существенного уменьшения размеров выходного файла со стилями Tailwind. Без этого шага размер стилевого файла может достигать более 10MB — со всеми лишними удобствами, компонентами и утилитами. При этом даже для урезанного файла нельзя будет настроить code splitting, чего ожидаешь от современного инструмента для работы с CSS.

Я понимаю, почему был популярен Bootstrap, ведь он давал не просто набор псевдонимов к всевозможного вида отступам и фоновым цветам разной яркости. Его классы были привязаны к парадигме 12-ти колоночной сетки и очень упрощали работу с проектированием и вёрсткой адаптивных интерфейсов, когда flexbox был чем-то экзотическим, а про CSS Grids никто ещё даже не говорил. Но я откровенно не понимаю, какую проблему решает Tailwind. Пожалуй, для меня всё это демонстрирует, что в попытках снизить принципиальную сложность стилизации, популярным может стать любой велосипед, который может упростить одни стороны этой сложности (вопрос — какие?), но привнесёт ещё больший хаос в другие. Особенно если для этого велосипеда написать побольше модных инструментов и хорошо разрекламировать.

Поделитесь, какое у вас мнение по поводу Tailwind?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍64
This media is not supported in your browser
VIEW IN TELEGRAM
Демонстрация работы канбан-доски
🔥5👍33
👋 Всем привет!

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

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

При создании этого проекта мы поставили себе несколько амбициозных целей:

▶️ Продумать идеальный пользовательский путь, который будет интуитивно понятен. Для этого мы используем подход Customer Journey Map (CJM), с помощью которого можно наглядно проанализировать все пользовательские сценарии: от регистрации пользователя и создания проекта до переноса конкретной задачи из одного статуса в другой. Пользовательский путь выглядит как граф, узлами которого являются точки соприкосновения (touchpoints) с продуктом, а связи между узлами формируют различные сценарии взаимодействия. Создание такой наглядной схемы позволяет оптимизировать пользовательский опыт.

▶️ Разработать максимально удобный интерфейс, который будет интуитивно понятен и приятен в работе. Основой такого интерфейса будет механизм drag-n-drop, и в нашем проекте я использую современную React-библиотеку dnd-kit. Dnd-kit не использует HTML Drag and Drop API, так как он имеет несколько критических ограничений — это отсутствие поддержки touch-девайсов и довольно сложная кастомизация и настройка типовых интерфейсных решений.

▶️ Инструмент должен работать очень быстро: как на сервере, так и на клиенте. Для этого мы используем gRPC, который позволяет использовать бинарный формат для коммуникации между бэковскими сервисами и между бэком и клиентом (что даёт прирост примерно в х5 по сравнению с JSON REST API), умеет работать на любой платформе и в любой среде благодаря развитым инструментам кодогенерации, и особенно важно, что такая генерация существует и для веба. Protobuff-модели с описанием типов данных могут быть преобразованы в TypeScript-интерфейсы, с которыми можно удобно взаимодействовать на фронте, используя gRPC-web как основу для работы с gRPC-методами.

▶️ Инструментом можно будет пользоваться совместно в коллаборативном режиме. По умолчанию мы решили добавить стримы как основу работы с gRPC-методами, чтобы отслеживать действия разных пользователей, которые они совершают над задачами на одном экране. Со стримами, которые приходят от сервера на клиент, можно работать напрямую, всё также благодаря gRPC-web. В данный момент я нахожусь в процессе анализа и подбора технологий для работы с данными, полученными со стримов на фронте, пока что смотрю в сторону RxJS. Буду рад, если вы вдруг предложите какие-то свои идеи.

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

👇 Голосуйте за наиболее интересную вам тему. Так я смогу понять, о чём можно написать в первую очередь.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥63👍21