#статья дня
Мой товарищ, а по совместительству автор библиотеки extended-fetch, принёс довольно интересную тему для обсуждения.
Fetch API давно стал стандартным способом работы с HTTP-запросами в JavaScript, но его реализация в разных рантаймах может отличаться.
Особенно это заметно, когда речь заходит о поддержке HTTP/2: этот протокол позволяет улучшить производительность за счет мультиплексирования запросов.
Когда пишешь код в браузере, fetch воспринимается как что-то само собой разумеющееся. Он просто работает, поддерживает полный спектр HTTP, и никаких проблем не возникает.
Рассмотрим, как обстоят дела с HTTP/2 в популярных JavaScript-рантаймах: Node.js, Deno и Bun.
Спойлер: речь о поддержке HTTP/2 и экзотическом случае, при котором доступно общение с сервером без фоллбэка на HTTP/1.1.
🦕 Победитель — Deno. Этот рантайм обеспечивает полноценную поддержку HTTP/2 в fetch без дополнительных манипуляций.
🩼 Костыльный победитель — Node.js. Здесь fetch основан на библиотеке undici, которая изначально не поддерживает HTTP/2. Однако, можно воспользоваться самим undici, минуя стандартный fetch, и получить желаемый результат.
🌚 Проигравший — Bun. В этом рантайме более года открыто issue о поддержке HTTP/2, но пока что полноценной реализации нет.
Подытожим
Если вам нужна полноценная поддержка HTTP/2 в fetch, лучший выбор — Deno. В Node.js придется использовать обходные пути, а в Bun — просто подождать, пока разработчики добавят эту функциональность.
В общем, даже стандартные API могут работать по-разному в разных окружениях, поэтому всегда стоит проверять их поддержку перед использованием в продакшене.
Собственно, вот и статья: https://blog.disintegrator.dev/posts/http2-support-in-js-runtimes/
Там есть все примеры кода и клиента, и сервера.
Мнения?
#fetch #node #deno #bun
Мой товарищ, а по совместительству автор библиотеки extended-fetch, принёс довольно интересную тему для обсуждения.
Fetch API давно стал стандартным способом работы с HTTP-запросами в JavaScript, но его реализация в разных рантаймах может отличаться.
Особенно это заметно, когда речь заходит о поддержке HTTP/2: этот протокол позволяет улучшить производительность за счет мультиплексирования запросов.
Когда пишешь код в браузере, fetch воспринимается как что-то само собой разумеющееся. Он просто работает, поддерживает полный спектр HTTP, и никаких проблем не возникает.
Рассмотрим, как обстоят дела с HTTP/2 в популярных JavaScript-рантаймах: Node.js, Deno и Bun.
Спойлер: речь о поддержке HTTP/2 и экзотическом случае, при котором доступно общение с сервером без фоллбэка на HTTP/1.1.
🩼 Костыльный победитель — Node.js. Здесь fetch основан на библиотеке undici, которая изначально не поддерживает HTTP/2. Однако, можно воспользоваться самим undici, минуя стандартный fetch, и получить желаемый результат.
Подытожим
Если вам нужна полноценная поддержка HTTP/2 в fetch, лучший выбор — Deno. В Node.js придется использовать обходные пути, а в Bun — просто подождать, пока разработчики добавят эту функциональность.
В общем, даже стандартные API могут работать по-разному в разных окружениях, поэтому всегда стоит проверять их поддержку перед использованием в продакшене.
Собственно, вот и статья: https://blog.disintegrator.dev/posts/http2-support-in-js-runtimes/
Там есть все примеры кода и клиента, и сервера.
Мнения?
#fetch #node #deno #bun
Please open Telegram to view this post
VIEW IN TELEGRAM
#немогумолчать дня
Котаны, такое дело. Сегодня у моего самого старого подписчика @dimovski день рождения.
Человек прошел путь от моего вопроса лет семь назад: «Накой тебе сдался битрикс? Не ломай себе жизнь!» до тимлида. И стоял у истоков канала и всячески поддерживает до сих пор.
Накидайте ему сердечек там штоле ☺️ Будет мой ему такой подарок 💝
Котаны, такое дело. Сегодня у моего самого старого подписчика @dimovski день рождения.
Человек прошел путь от моего вопроса лет семь назад: «Накой тебе сдался битрикс? Не ломай себе жизнь!» до тимлида. И стоял у истоков канала и всячески поддерживает до сих пор.
Накидайте ему сердечек там штоле ☺️ Будет мой ему такой подарок 💝
Media is too big
VIEW IN TELEGRAM
#codepen дня
Тут нужно краткое предисловие.
Где-то с неделю назад, Google опубликовали исходный код операционной системы умных часов Pebble.
Вы, наверное, вряд ли помните о них, но это, собственно, были первые умные часы. Они и проложили дорогу всем остальным, начавшись просто как проект на Kickstarter.
Судьба компании довольно трагична, но мы не о ней.
Дело в том, что их основатель и уговорил Google открыть исходный код, чтобы возродить те самые часы. Мотивация проста: писать софт — долго и сложно, дайте хоть что-то.
И он сделал забавный сайт — https://repebble.com/ — на котором изложил свою философию.
А меня, в свою очередь, чуток порвало с анимации выключения телевизора, которая происходит при нажатии на No. Порвало настолько, что я решил для вас её повторить📺
Она простая и при этом очень крутая, никаких шейдеров и прочего: https://codepen.io/alinaki/pen/vEBoZOz?editors=0110
Заодно, пусть будет дежурным напоминанием: вам не нужны таймауты, чтобы управлять событиями по завершению анимаций. Для этого есть прекрасное событие animationend.
Хорошей пятницы, котаны!
#css #animation #animationend
Тут нужно краткое предисловие.
Где-то с неделю назад, Google опубликовали исходный код операционной системы умных часов Pebble.
Вы, наверное, вряд ли помните о них, но это, собственно, были первые умные часы. Они и проложили дорогу всем остальным, начавшись просто как проект на Kickstarter.
Судьба компании довольно трагична, но мы не о ней.
Дело в том, что их основатель и уговорил Google открыть исходный код, чтобы возродить те самые часы. Мотивация проста: писать софт — долго и сложно, дайте хоть что-то.
И он сделал забавный сайт — https://repebble.com/ — на котором изложил свою философию.
А меня, в свою очередь, чуток порвало с анимации выключения телевизора, которая происходит при нажатии на No. Порвало настолько, что я решил для вас её повторить
Она простая и при этом очень крутая, никаких шейдеров и прочего: https://codepen.io/alinaki/pen/vEBoZOz?editors=0110
Заодно, пусть будет дежурным напоминанием: вам не нужны таймауты, чтобы управлять событиями по завершению анимаций. Для этого есть прекрасное событие animationend.
Хорошей пятницы, котаны!
#css #animation #animationend
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
#инструмент дня
Не устану повторять, что лучшая вёрстка — это та, которую делать не надо.
Поэтому я очень люблю конструкторы. Но мы тут не тильду делать собрались, потому речь о конструкторах раскладок.
И сегодня мне принесло очередной! FlexBox Labs: https://flexboxlabs.netlify.app/
Из названия понятно, что речь о флексбоксе, не о гридах. Но — повторю — одно другого не отменяет ни разу. Флекс и грид решают разные задачи, потому — стоит внимания.
Особенно учитывая, что на рынке не так много конструкторов под флекс, гриды казались более крутой технологией и натурально получили больше конструкторов.
Да и короткое объяснение, что и когда применять, на канале уже было: https://www.tg-me.com/htmlshit/607
А что ещё круто, проект — открытый, можно держать у себя локально: https://github.com/prazzon/flexbox-labs
Генерирует как CSS, так и классы Tailwind.
Впрочем, гриды конструктор тоже может, в экспериментальном режиме: https://flexboxlabs.netlify.app/grid
#css #flex #layout
Не устану повторять, что лучшая вёрстка — это та, которую делать не надо.
Поэтому я очень люблю конструкторы. Но мы тут не тильду делать собрались, потому речь о конструкторах раскладок.
И сегодня мне принесло очередной! FlexBox Labs: https://flexboxlabs.netlify.app/
Из названия понятно, что речь о флексбоксе, не о гридах. Но — повторю — одно другого не отменяет ни разу. Флекс и грид решают разные задачи, потому — стоит внимания.
Особенно учитывая, что на рынке не так много конструкторов под флекс, гриды казались более крутой технологией и натурально получили больше конструкторов.
Да и короткое объяснение, что и когда применять, на канале уже было: https://www.tg-me.com/htmlshit/607
А что ещё круто, проект — открытый, можно держать у себя локально: https://github.com/prazzon/flexbox-labs
Генерирует как CSS, так и классы Tailwind.
Впрочем, гриды конструктор тоже может, в экспериментальном режиме: https://flexboxlabs.netlify.app/grid
#css #flex #layout
#статья дня
Посмотрите на иллюстрацию. Я не буду говорить: "Ничего интересного не замечаете?", — ну просто потому что в самом коде ничего интересного нет. Секрет кроется в подсветке кода.
И суть в том, что подсветка кода сделана... шрифтом.
Кроме шуток, я когда это увидел, я подумал "ну точно какой-то финн упоролся". Есть у финнов такое направление в дизайне, извращение над шрифтами называется. Вот, например, шрифт, который становится тоньше из-за изменения климата: https://kampanjat.hs.fi/climatefont/
И да!
Автор шрифта — Хейкки Лотвонен. И он буквально выжал всё возможное из фишки COLR (это чуть больше чем лигатуры на стероидах) стандарта шрифтов OpenType: https://blog.glyphdrawing.club/font-with-built-in-syntax-highlighting/
Статья не только рассказывает о возможностях шрифта, но и погружает в понятие COLR: палитра, правила совмещения, лигатуры.
Поддерживаются HTML, CSS и даже JavaScript. Более того, можно перегружать цвета, получая свою собственую тему!
В общем, прекрасная взрывающая мозг статья. И применение самое что ни на есть реальное.
Есть обсуждение на HackerNews, вдруг кому интересно.
И CodePen с демо: https://codepen.io/argyleink/pen/GRbyNNv
Подробное описание технологии COLR от разработчиков Google Chrome: https://developer.chrome.com/blog/colrv1-fonts
В общем, Финляндия это не только озёра и Linux, но и шрифты. Теперь и вы знаете.
#opentype #fonts #colr #бородач
Посмотрите на иллюстрацию. Я не буду говорить: "Ничего интересного не замечаете?", — ну просто потому что в самом коде ничего интересного нет. Секрет кроется в подсветке кода.
И суть в том, что подсветка кода сделана... шрифтом.
Кроме шуток, я когда это увидел, я подумал "ну точно какой-то финн упоролся". Есть у финнов такое направление в дизайне, извращение над шрифтами называется. Вот, например, шрифт, который становится тоньше из-за изменения климата: https://kampanjat.hs.fi/climatefont/
И да!
Автор шрифта — Хейкки Лотвонен. И он буквально выжал всё возможное из фишки COLR (это чуть больше чем лигатуры на стероидах) стандарта шрифтов OpenType: https://blog.glyphdrawing.club/font-with-built-in-syntax-highlighting/
Статья не только рассказывает о возможностях шрифта, но и погружает в понятие COLR: палитра, правила совмещения, лигатуры.
Поддерживаются HTML, CSS и даже JavaScript. Более того, можно перегружать цвета, получая свою собственую тему!
В общем, прекрасная взрывающая мозг статья. И применение самое что ни на есть реальное.
Есть обсуждение на HackerNews, вдруг кому интересно.
И CodePen с демо: https://codepen.io/argyleink/pen/GRbyNNv
Подробное описание технологии COLR от разработчиков Google Chrome: https://developer.chrome.com/blog/colrv1-fonts
В общем, Финляндия это не только озёра и Linux, но и шрифты. Теперь и вы знаете.
#opentype #fonts #colr #бородач
#инструмент дня
Зачем писать
Ответ на эти и другие вопросы прост: «Потому что не подумал».
Но думать — сложно. И не всегда нужно. Поэтому в IDE от JetBrains встроен преобразователь логических вырадений по законам де Моргана.
А тем, кто предпочитает быть свободным, приходится искать иные решения.
Иногда — даже думать.
И тут есть вариант, откуда не ждали: правило для ESLint!
ESLint Plugin De Morgan: https://github.com/azat-io/eslint-plugin-de-morgan
Запросто преобразует ваши const value = !(a || b !== c) в const value = !a && b === c.
В плагине два правила:
- no-negated-conjunction
- no-negated-disjunction
Все правила имеют автофикс. У плагина нет зависимостей. Поддерживает как современный, так и легаси формат ESLint конфигов.
Твиттер автора с анонсом: https://x.com/azat_io/status/1888874193007132762
Пользуемся, котаны!
#boolean #eslint #logic
Зачем писать
!(a && !b && c >= 10 && d !== e)
, если можно !a || b || c < 10 || d === e
?Ответ на эти и другие вопросы прост: «Потому что не подумал».
Но думать — сложно. И не всегда нужно. Поэтому в IDE от JetBrains встроен преобразователь логических вырадений по законам де Моргана.
А тем, кто предпочитает быть свободным, приходится искать иные решения.
Иногда — даже думать.
И тут есть вариант, откуда не ждали: правило для ESLint!
ESLint Plugin De Morgan: https://github.com/azat-io/eslint-plugin-de-morgan
Запросто преобразует ваши const value = !(a || b !== c) в const value = !a && b === c.
В плагине два правила:
- no-negated-conjunction
- no-negated-disjunction
Все правила имеют автофикс. У плагина нет зависимостей. Поддерживает как современный, так и легаси формат ESLint конфигов.
Твиттер автора с анонсом: https://x.com/azat_io/status/1888874193007132762
Пользуемся, котаны!
#boolean #eslint #logic
#статья дня
Эффект frosted glass — матового стекла, а не замороженного, как вы могли бы подумать — последнее время довольно популярен.
Вот только проблема в том, что он насколько популярен, настолько же и убог. Разработчики и дизайнеры просто размывают фон за полупрозрачным элементом, делая вид, что оптические эффекты их не касаются.
Джош Комо решил подойти к этой проблеме серьезно: https://www.joshwcomeau.com/css/backdrop-filter/
Что он заметил?
Когда смотришь сквозь настоящее матовое стекло, размытие неравномерное:
Чем дальше объект за стеклом, тем сильнее он размывается.
Блики и яркие детали распространяются по стеклу, создавая эффект светящегося ореола.
В итоге он решил применить фильтр для гораздо большей части изображения, а остальное — скрыть
Звучит страшно, но на самом деле всё достаточно просто. В статье объясняются как базовые принципы использования фильтров и масок в CSS, так и неожиданные их комбинации.
#css #filter #glass
Эффект frosted glass — матового стекла, а не замороженного, как вы могли бы подумать — последнее время довольно популярен.
Вот только проблема в том, что он насколько популярен, настолько же и убог. Разработчики и дизайнеры просто размывают фон за полупрозрачным элементом, делая вид, что оптические эффекты их не касаются.
Джош Комо решил подойти к этой проблеме серьезно: https://www.joshwcomeau.com/css/backdrop-filter/
Что он заметил?
Когда смотришь сквозь настоящее матовое стекло, размытие неравномерное:
Чем дальше объект за стеклом, тем сильнее он размывается.
Блики и яркие детали распространяются по стеклу, создавая эффект светящегося ореола.
В итоге он решил применить фильтр для гораздо большей части изображения, а остальное — скрыть
маской:
.backdrop {
position: absolute;
inset: 0;
height: 200%;
backdrop-filter: blur(16px);
mask-image: linear-gradient(
to bottom,
black 0% 50%,
transparent 50% 100%
);
}
Звучит страшно, но на самом деле всё достаточно просто. В статье объясняются как базовые принципы использования фильтров и масок в CSS, так и неожиданные их комбинации.
#css #filter #glass
This media is not supported in your browser
VIEW IN TELEGRAM
#ссылка дня
Адам Аргайл (Adam Argyle) — деврел в команде Google Chrome — уже давно в своём блоге https://nerdy.dev/ ведёт раздел Nerdy Notebook. Собирает разные техники создания компонентов и эффектов.
И одно из последних обновлений там — это большой сборник эффектов появления по скроллу! ScrollAnimation API в CSS: https://nerdy.dev/notebook/scroll-driven-animations.html
z-stack вариант шикарный вообще.
Ну и, естественно, есть описание техники.
Нелишним будет напомнить, что работает ScrollAnimation API пока только в Chrome и Safari TP. Но работа идёт!
#css #scroll
Адам Аргайл (Adam Argyle) — деврел в команде Google Chrome — уже давно в своём блоге https://nerdy.dev/ ведёт раздел Nerdy Notebook. Собирает разные техники создания компонентов и эффектов.
И одно из последних обновлений там — это большой сборник эффектов появления по скроллу! ScrollAnimation API в CSS: https://nerdy.dev/notebook/scroll-driven-animations.html
z-stack вариант шикарный вообще.
Ну и, естественно, есть описание техники.
Нелишним будет напомнить, что работает ScrollAnimation API пока только в Chrome и Safari TP. Но работа идёт!
#css #scroll
Ищем web3 разработчика
Мы криптообменник❤️ CoinCross.one
Мы изменим правила игры в ФинТехе🔥 , благодаряя нашей философии: деньги клиента это деньги клиента!
В обычных же банках и биржах как только вы положили деньги, то ваши сбережения становятся их.
Мы ищем web3 разработчика для осуществления решения создания web агрегатора крипто процессинга:
–на создание быстрой работающей MVP крипто-кошелька (сайта) для принятия платежей от покупателей с криптообменника.
–отдельные кошельки для трейдеров(п2пшников) входящие в состав общего банка криптообменника.
Цель: проверить гипотезу
На что стоит держать фокус:
Скорость, дешевизна, работоспособность.
Берём в работу только А-игроков
Для раскрытия более подробной информации пиши сюда: www.tg-me.com/alexeyuser
Мы криптообменник
Мы изменим правила игры в ФинТехе
В обычных же банках и биржах как только вы положили деньги, то ваши сбережения становятся их.
Мы ищем web3 разработчика для осуществления решения создания web агрегатора крипто процессинга:
–на создание быстрой работающей MVP крипто-кошелька (сайта) для принятия платежей от покупателей с криптообменника.
–отдельные кошельки для трейдеров(п2пшников) входящие в состав общего банка криптообменника.
Цель: проверить гипотезу
На что стоит держать фокус:
Скорость, дешевизна, работоспособность.
Берём в работу только А-игроков
Для раскрытия более подробной информации пиши сюда: www.tg-me.com/alexeyuser
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
#заметка дня
Джордж Моллер (George Moller) — техлид в Shopify — предлагает интересное решение одной наболевшей в React проблемы. И проблема эта — ререндер всех компонентов, зависящих от некоего контекста.
Ну просто потому что useContext сработает на любое изменение данных в контексте, очевидно.
И решение это — кастомный хук useContextSelector: https://github.com/dai-shi/use-context-selector
И вроде всё бы ничего, вот только если вам пришлось это делать — вы используете контекст не очень верно. И лучше бы перейти на Jotai, Zustand, Effector, Reatom и так далее. На любой современный стейт-менеджер, короче говоря.
Контекст — он для чего-то глобального. Тема, данные пользователя, информация о лицензии. Плюс, совсем не обязательно хранить огромный контекст на всё приложение. Можно иметь много контекстов на разные зоны ответственности — в этом же вся его прелесть.
Но если уж вы попали в подобную ситуацию — да, useContextSelector спасёт.
Хотя я бы не стал.
#react #context #hook
Джордж Моллер (George Moller) — техлид в Shopify — предлагает интересное решение одной наболевшей в React проблемы. И проблема эта — ререндер всех компонентов, зависящих от некоего контекста.
Ну просто потому что useContext сработает на любое изменение данных в контексте, очевидно.
И решение это — кастомный хук useContextSelector: https://github.com/dai-shi/use-context-selector
И вроде всё бы ничего, вот только если вам пришлось это делать — вы используете контекст не очень верно. И лучше бы перейти на Jotai, Zustand, Effector, Reatom и так далее. На любой современный стейт-менеджер, короче говоря.
Контекст — он для чего-то глобального. Тема, данные пользователя, информация о лицензии. Плюс, совсем не обязательно хранить огромный контекст на всё приложение. Можно иметь много контекстов на разные зоны ответственности — в этом же вся его прелесть.
Но если уж вы попали в подобную ситуацию — да, useContextSelector спасёт.
Хотя я бы не стал.
#react #context #hook
This media is not supported in your browser
VIEW IN TELEGRAM
#библиотека дня
На правах пятницы!
Если надо выбрать любимый бесполезный эффект — то мой определённо будет глитч.
И вот есть библиотечка как раз для этого!
https://github.com/7PH/powerglitch
Она это делает совершенно потрясающим способом: объявляется набор полигонов для выделения маски, элемент будто нарезается на куски, а потом к ним применяются CSS-преобразования. Просто шикарно.
Я давно хотел сделать плеер. где обложка будет глючить в так музыке :) Настало время!
#css #glitch #effect
На правах пятницы!
Если надо выбрать любимый бесполезный эффект — то мой определённо будет глитч.
И вот есть библиотечка как раз для этого!
https://github.com/7PH/powerglitch
Она это делает совершенно потрясающим способом: объявляется набор полигонов для выделения маски, элемент будто нарезается на куски, а потом к ним применяются CSS-преобразования. Просто шикарно.
Я давно хотел сделать плеер. где обложка будет глючить в так музыке :) Настало время!
#css #glitch #effect
#статья дня
Если среди моих подписчиков есть те, кому за 30, то они могут вспомнить, что 8 и 16-битные игры на ЭЛТ-телевизорах выглядели совсем не так, как их нынче имитируют. Ни о каком пиксель-арте речи не шло, всё было достаточно смазано, чтобы казаться гладким и настоящим. А пиксель-арт, собственно, распространился с ЖК-экранами и модой на ретро.
А всё потому что из особенностей и недостатков технологии делали преимущество! Нативное сглаживание, бесплатно!
К чему это я?
К тому, что набор квадратиков на иллюстрации это самый настоящий шрифт, использующий особенности технологии построения ЖК-экранов. В 1 пиксель шириной. Он так и называется: Millitext. Вот: http://www.msarnoff.org/millitext/
Но статья дня всё равно о другом.
Как происходит процесс рендеринга шрифтов вообще, что за этим стоит и почему это так сложно. И да, особенности ЖК играют в этом не последнюю роль, потому и вступление такое: https://faultlore.com/blah/text-hates-you/
Text hates you, котаны!
#font #rendering #бородач
Если среди моих подписчиков есть те, кому за 30, то они могут вспомнить, что 8 и 16-битные игры на ЭЛТ-телевизорах выглядели совсем не так, как их нынче имитируют. Ни о каком пиксель-арте речи не шло, всё было достаточно смазано, чтобы казаться гладким и настоящим. А пиксель-арт, собственно, распространился с ЖК-экранами и модой на ретро.
А всё потому что из особенностей и недостатков технологии делали преимущество! Нативное сглаживание, бесплатно!
К чему это я?
К тому, что набор квадратиков на иллюстрации это самый настоящий шрифт, использующий особенности технологии построения ЖК-экранов. В 1 пиксель шириной. Он так и называется: Millitext. Вот: http://www.msarnoff.org/millitext/
Но статья дня всё равно о другом.
Как происходит процесс рендеринга шрифтов вообще, что за этим стоит и почему это так сложно. И да, особенности ЖК играют в этом не последнюю роль, потому и вступление такое: https://faultlore.com/blah/text-hates-you/
Text hates you, котаны!
#font #rendering #бородач
#devtools дня
Одна из моих любимых фишек современного CSS — это функция clamp.
В переводе — зажим. И это буквально то, что она делает: зажимает некое значение в пределах двух других.
Ну, например, выражение:
...задаст по-умолчанию ширину блока в половину ширины экрана, но не меньше 250 пикселей и не больше шестиста.
Удобно? Ну, не то слово. Со шрифтами вообще великолепно выходит! Вот инструмент, например: https://www.tg-me.com/htmlshit/902
Ну и пример с шириной: https://codepen.io/Ekaterina_Vu/pen/QWjxJvm
Но собрал я вас не совсем за этим. К сожалению, в средствах разработчика Chrome никак не возможно понять, какое же значение используется в данный момент.
Но уже в Chrome Canary и скоро и в стабильных DevTools 134 нас ждёт адекватная нотация! С зачёркнутыми неиспользуемыми значениями:
width: clamp(250px, 50vw, 600px);
Счастье есть, котаны!
#css #clamp #chrome
Одна из моих любимых фишек современного CSS — это функция clamp.
В переводе — зажим. И это буквально то, что она делает: зажимает некое значение в пределах двух других.
Ну, например, выражение:
width: clamp(250px, 50vw, 600px);
...задаст по-умолчанию ширину блока в половину ширины экрана, но не меньше 250 пикселей и не больше шестиста.
Удобно? Ну, не то слово. Со шрифтами вообще великолепно выходит! Вот инструмент, например: https://www.tg-me.com/htmlshit/902
Ну и пример с шириной: https://codepen.io/Ekaterina_Vu/pen/QWjxJvm
Но собрал я вас не совсем за этим. К сожалению, в средствах разработчика Chrome никак не возможно понять, какое же значение используется в данный момент.
Но уже в Chrome Canary и скоро и в стабильных DevTools 134 нас ждёт адекватная нотация! С зачёркнутыми неиспользуемыми значениями:
width: clamp(
Счастье есть, котаны!
#css #clamp #chrome
#видео и #статья дня
Отгадайте за секунду, что это такое зелёное подсвечено на скриншоте Танков?
Да, это буквально игровой UI. А что если я скажу вам, что он написан на TypeScript и React?
А вы что думали, Реакт ограничивается только вебом и мобилками? Нет :) И Prabashwara Seneviratne (я не уверен, как его имя транслитерировать правильно) несколько лет назад как раз работал в отделении Wargaming в Праге над UI для World of Tanks.
И даже написал об этом статью: https://www.frontendundefined.com/posts/essays/pc-game-ui-react/
В статье вы найдёте не только некоторые технические подробности, но и узнаете, в чём фундаментальное отличие Web от игровых UI.
И таки да, вы не поверите, но там буквально свой кастомный браузер, поддерживающий лишь некоторые возможности HTML/CSS и JS.
Если лениво читать, автор не поленился выложить видео с конференции Web Expo 2022, где он рассказывает, в общем, о том же: https://www.frontendundefined.com/posts/talks/web-tech-game-ui/
#game #wot #react #ui
Отгадайте за секунду, что это такое зелёное подсвечено на скриншоте Танков?
Да, это буквально игровой UI. А что если я скажу вам, что он написан на TypeScript и React?
А вы что думали, Реакт ограничивается только вебом и мобилками? Нет :) И Prabashwara Seneviratne (я не уверен, как его имя транслитерировать правильно) несколько лет назад как раз работал в отделении Wargaming в Праге над UI для World of Tanks.
И даже написал об этом статью: https://www.frontendundefined.com/posts/essays/pc-game-ui-react/
В статье вы найдёте не только некоторые технические подробности, но и узнаете, в чём фундаментальное отличие Web от игровых UI.
И таки да, вы не поверите, но там буквально свой кастомный браузер, поддерживающий лишь некоторые возможности HTML/CSS и JS.
Если лениво читать, автор не поленился выложить видео с конференции Web Expo 2022, где он рассказывает, в общем, о том же: https://www.frontendundefined.com/posts/talks/web-tech-game-ui/
#game #wot #react #ui
#инструмент дня
Я уже один раз потерял ссылку на этот сервис, потому на правах закладки.
Встречайте, Cobalt: https://cobalt.tools/
Это сервис с открытым исходным кодом (GitHub), предназначенный для скачивания видео с большой кучи разнообразных сервисов: вк, ютуб, рутуб, тикток, твиттер, инстаграм и так далее и тому подобное. Полный список тут.
Никакой рекламы и занудства. Разве только UI на мобиле подглючивает — у меня не всегда правильно определяется безопасная зона "чёлки".
В общем, рекомендация.
#video #download
Я уже один раз потерял ссылку на этот сервис, потому на правах закладки.
Встречайте, Cobalt: https://cobalt.tools/
Это сервис с открытым исходным кодом (GitHub), предназначенный для скачивания видео с большой кучи разнообразных сервисов: вк, ютуб, рутуб, тикток, твиттер, инстаграм и так далее и тому подобное. Полный список тут.
Никакой рекламы и занудства. Разве только UI на мобиле подглючивает — у меня не всегда правильно определяется безопасная зона "чёлки".
В общем, рекомендация.
#video #download
This media is not supported in your browser
VIEW IN TELEGRAM
#проект дня
Помните, когда я описывал библиотеку powerglitch, я сказал, что хотел бы сделать свой маленький плеер, где обложка глючила бы в такт?
Ну что же, я сделал!
Идея показалась интересной, особенно с перспективой в будущем генерировать глитч-видео на основе ритма. Но реализация оказалась не такой простой, как я думал.
Основные этапы разработки:
1. Загрузка аудиофайлов — обработка mp3-файлов и их воспроизведение в браузере.
2. Извлечение обложки — получаем картинку из метаданных трека.
3. Анализ аудиопотока — детектируем ритм и биты разными методами.
4. Генерация глитч-эффектов — синхронизируем глитчи с музыкой.
Для реализации я использовал:
- powerglitch — библиотека для создания глитч-эффектов.
- WebAudio API — анализ аудиопотока в браузере.
- music-metadata — для извлечения метаданных, в том числе обложек, из mp3.
Проблема с обложкой
На этапе парсинга метаданных и отображения обложки неожиданно возникла проблема: maximum stack size exceeded.
Всё оказалось просто: обложки были тупо слишком большими, поэтому я выходил за пределы максимального размера блока. А он всего 64 килобайта, которых хватит всем.
Нужно было обрабатывать данные поблочно.
Решилось всё использованием библиотеки uint8array-extras, хотя, если честно, решение лежало на поверхности. С другой стороны, есть нюанс с Юникодом.
И, к сожалению, библиотека powerglitch просто не позволяет менять настройки глитча на лету. Но она оказалась достаточно производительной, чтобы просто пересоздавать.
Методы детектирования ритма
Я добавил несколько способов анализа:
- Spectral Flux — анализ изменений спектральной энергии.
- Zero Crossing Rate — количество пересечений нуля в сигнале.
- Beat Tracking — поиск ударов в аудиопотоке.
- Energy Detection — резкие скачки громкости.
- Peak Detection — анализ пиков сигнала.
Сейчас плеер работает, но хочется добавить больше визуальных эффектов и попробовать другие алгоритмы анализа. Впрочем, на драмэндбассе любой сравнительно хорошо работает. Хотя надо бы ещё ручки покрутить.
Жаль, браузеры не могут записывать видео с самих себя... Но это мы решим :)
Ах, да. Посмотреть можно вот тут: https://bekharsky.github.io/GlitchBeat/
И репка: https://github.com/bekharsky/glitchbeat
Пощёлкайте разные виды определения ритма. Там очень далеко от идеала, но иногда получается прям хорошо.
#js #audio #glitch #effect #music
Помните, когда я описывал библиотеку powerglitch, я сказал, что хотел бы сделать свой маленький плеер, где обложка глючила бы в такт?
Ну что же, я сделал!
Идея показалась интересной, особенно с перспективой в будущем генерировать глитч-видео на основе ритма. Но реализация оказалась не такой простой, как я думал.
Основные этапы разработки:
1. Загрузка аудиофайлов — обработка mp3-файлов и их воспроизведение в браузере.
2. Извлечение обложки — получаем картинку из метаданных трека.
3. Анализ аудиопотока — детектируем ритм и биты разными методами.
4. Генерация глитч-эффектов — синхронизируем глитчи с музыкой.
Для реализации я использовал:
- powerglitch — библиотека для создания глитч-эффектов.
- WebAudio API — анализ аудиопотока в браузере.
- music-metadata — для извлечения метаданных, в том числе обложек, из mp3.
Проблема с обложкой
На этапе парсинга метаданных и отображения обложки неожиданно возникла проблема: maximum stack size exceeded.
Всё оказалось просто: обложки были тупо слишком большими, поэтому я выходил за пределы максимального размера блока. А он всего 64 килобайта, которых хватит всем.
Нужно было обрабатывать данные поблочно.
Решилось всё использованием библиотеки uint8array-extras, хотя, если честно, решение лежало на поверхности. С другой стороны, есть нюанс с Юникодом.
И, к сожалению, библиотека powerglitch просто не позволяет менять настройки глитча на лету. Но она оказалась достаточно производительной, чтобы просто пересоздавать.
Методы детектирования ритма
Я добавил несколько способов анализа:
- Spectral Flux — анализ изменений спектральной энергии.
- Zero Crossing Rate — количество пересечений нуля в сигнале.
- Beat Tracking — поиск ударов в аудиопотоке.
- Energy Detection — резкие скачки громкости.
- Peak Detection — анализ пиков сигнала.
Сейчас плеер работает, но хочется добавить больше визуальных эффектов и попробовать другие алгоритмы анализа. Впрочем, на драмэндбассе любой сравнительно хорошо работает. Хотя надо бы ещё ручки покрутить.
Жаль, браузеры не могут записывать видео с самих себя... Но это мы решим :)
Ах, да. Посмотреть можно вот тут: https://bekharsky.github.io/GlitchBeat/
И репка: https://github.com/bekharsky/glitchbeat
Пощёлкайте разные виды определения ритма. Там очень далеко от идеала, но иногда получается прям хорошо.
#js #audio #glitch #effect #music
#инструмент дня
Вчерашний проект я изначально хотел просто оставить в песочнице, на Codesandbox, но решил, что это не имеет никакого смысла. Потому, GitHub Pages — наш путь.
Так вот, никто же не хочет ограничиваться одним репозиторием, как на главной странице документации, верно?
И для этого GitHub может просто деплоить в подкаталог из ветки, которая настраивается в разделе Pages конфигурации репозитория. Выходит, всё, что нужно сделать, это положить в эту ветку ваш собранный проект.
И тут, опять же, возникает нюанс. Как правило, дистрибутив (сборку) проекта не принято хранить в основной ветке.Каталог
Поэтому надо:
- переключиться в ветку
- удалить из-под гита файлы
- собрать проект
- добавить каталог со сборкий...
выходит, мягко говоря, муторно.
Но, как всегда, есть решение! Пакет gh-pages.
Он проделает все эти операции за вас, ему нужно лишь немного помочь. И тут есть два нюанса.
Во-первых, документация даёт неожиданно много информации и сначала можно даже смутиться. Но на самом деле, всё, что надо сделать — это прописать следующий скрипт в package.json (я исхожу из соображения, что в git вы пушить уже научились):
И второй нюанс: сборку надо совсем чуть-чуть настроить.
Видите ли, все сборщики проектов (будь то vite, rsbuild, esbuild, rollup или даже Next.js) по-умолчанию полагают, что ваш проект лежит в корне сайта. И от этого и строят все пути, загружают картинки, стили и скрипты.
К счастью, в большинстве из них это очень легко решается: установкой параметра
В vite для этого даже не нужно городить новую конфигурацию, просто передаёте в строке сборки:
Обратили внимание, что я делаю кастомную команду, которая отличается от
А теперь, объединяем всё вместе! У
И всё, вы великолепны! Хотите собрать и задеплоить проект куда-то в иное место — никто обычный
Вчерашний проект я изначально хотел просто оставить в песочнице, на Codesandbox, но решил, что это не имеет никакого смысла. Потому, GitHub Pages — наш путь.
Так вот, никто же не хочет ограничиваться одним репозиторием, как на главной странице документации, верно?
username.github.io
, конечно, хорошо, но репозиториев-то хочется много!И для этого GitHub может просто деплоить в подкаталог из ветки, которая настраивается в разделе Pages конфигурации репозитория. Выходит, всё, что нужно сделать, это положить в эту ветку ваш собранный проект.
И тут, опять же, возникает нюанс. Как правило, дистрибутив (сборку) проекта не принято хранить в основной ветке.Каталог
dist
или build
почти всегда включён в любой рекомендованный файл .gitignore
.Поэтому надо:
- переключиться в ветку
- удалить из-под гита файлы
- собрать проект
- добавить каталог со сборкий...
выходит, мягко говоря, муторно.
Но, как всегда, есть решение! Пакет gh-pages.
Он проделает все эти операции за вас, ему нужно лишь немного помочь. И тут есть два нюанса.
Во-первых, документация даёт неожиданно много информации и сначала можно даже смутиться. Но на самом деле, всё, что надо сделать — это прописать следующий скрипт в package.json (я исхожу из соображения, что в git вы пушить уже научились):
"scripts": {
"deploy": "gh-pages -d build"
}
И второй нюанс: сборку надо совсем чуть-чуть настроить.
Видите ли, все сборщики проектов (будь то vite, rsbuild, esbuild, rollup или даже Next.js) по-умолчанию полагают, что ваш проект лежит в корне сайта. И от этого и строят все пути, загружают картинки, стили и скрипты.
К счастью, в большинстве из них это очень легко решается: установкой параметра
basePath
(или просто base
).В vite для этого даже не нужно городить новую конфигурацию, просто передаёте в строке сборки:
"scripts": {
"build-ghp": "vite build --base=/GlitchBeat",
}
Обратили внимание, что я делаю кастомную команду, которая отличается от
build
? В скрипте build
я оставляю настройки сборщика по-умолчанию. Это простая гигиена.А теперь, объединяем всё вместе! У
gh-pages
есть прекрасная и очень полезная нам особенность: он автоматически вызовет скрипт predeploy
. Как можно догадаться, это что-то, что можно сделать перед выкладыванием проекта. И в нашем случае — это, собственно, сборка:
"scripts": {
"build-ghp": "vite build --base=/GlitchBeat",
"predeploy": "npm run build-ghp",
"deploy": "gh-pages -d dist"
}
И всё, вы великолепны! Хотите собрать и задеплоить проект куда-то в иное место — никто обычный
build
у вас не отбирал, собирайте и запускайте как угодно. А в predeploy
и build-ghp
можно понапихать ещё чего-то нужного, от подключения ключей до кастомной аналитики.#статья дня
А ну, сходу ответьте, чем отличается
На самом деле, если тупо воспользоваться логикой английского языка — легко ошибиться.
Разработчики браузера для, простите, разработчиков —Polypane — ведут свой блог с разными мелкими фишками, и сегодня — вот такая, как раз об этом.
📌 :has(:not())
Выбирает элементы, которые содержат определённые дочерние элементы, но не содержащие другие.
🔹 Выберет
📌 :not(:has())
Выбирает элементы, не содержащие определённый дочерний элемент.
🔹 Выберет
🏁 Итого:
Ну а в статье всё то же самое, только чуть подробнее.
Не ошибайтесь, котаны.
#css #has #not
А ну, сходу ответьте, чем отличается
:has(:not())
от :not(:has())
?На самом деле, если тупо воспользоваться логикой английского языка — легко ошибиться.
Разработчики браузера для, простите, разработчиков —Polypane — ведут свой блог с разными мелкими фишками, и сегодня — вот такая, как раз об этом.
📌 :has(:not())
Выбирает элементы, которые содержат определённые дочерние элементы, но не содержащие другие.
.card:has(:not(img)) {
background: lightblue;
}
🔹 Выберет
.card
, если внутри есть любой элемент, кроме <img>
.📌 :not(:has())
Выбирает элементы, не содержащие определённый дочерний элемент.
.card:not(:has(img)) {
background: lightcoral;
}
🔹 Выберет
.card
, если внутри вообще нет <img>
.🏁 Итого:
:has(:not(img))
проверяет, есть ли что-то, кроме <img>
.:not(:has(img))
проверяет, что <img>
вообще нет.Ну а в статье всё то же самое, только чуть подробнее.
Не ошибайтесь, котаны.
#css #has #not
😈 Челлендж по запуску 12 простых IT-проектов за 12 месяцев
Летом 2023 г. появилось комьюнити инди-хакеров, в котором ребята решили запускать 1 простой продукт в онлайне каждый месяц.
И в реальном времени показывать: как разрабатывают, продвигают и сколько получилось заработать на запусках таких микро-проектов.
Например, вот 👉 пост про то, почему американцы платят $40 за простой конвертер картинок, который сделали за 4 недели. Несмотря на то, что вокруг полно бесплатных аналогов)
👉 Этот пост про то, как за 2 недели запустили темную тему с тарифами от $5 до $99. Четыре таких продукта приносят на пассиве как зп среднего разработчика.
А вот 👉 тут — как все может грустно закончиться, если 2 года пилить сложный продукт, не показывая его рынку.
👉 Здесь, как за 30 дней сделали приложение для решения задач по математике, которое через 4 месяца вышло на $1200/месяц.
А 👉 здесь рассказывают, как заработали 1 700 000 рублей на боте для создания фотокниг и какие фейлы допустили.
Первая находка в их комьюнити IT билдеров — метод, который позволяет сделать запуск за 1 месяц.
Вторая находка — метод продвижения, который они используют. В среднем на продвижение одного IT-продукта уходит $150, причем есть продукты с 200К+ юзеров 🙂
Вот здесь можно подписаться на канал, чтобы подглядеть за их запусками. А может, и попробовать сделать такой простой продукт самому)
Летом 2023 г. появилось комьюнити инди-хакеров, в котором ребята решили запускать 1 простой продукт в онлайне каждый месяц.
И в реальном времени показывать: как разрабатывают, продвигают и сколько получилось заработать на запусках таких микро-проектов.
Например, вот 👉 пост про то, почему американцы платят $40 за простой конвертер картинок, который сделали за 4 недели. Несмотря на то, что вокруг полно бесплатных аналогов)
👉 Этот пост про то, как за 2 недели запустили темную тему с тарифами от $5 до $99. Четыре таких продукта приносят на пассиве как зп среднего разработчика.
А вот 👉 тут — как все может грустно закончиться, если 2 года пилить сложный продукт, не показывая его рынку.
👉 Здесь, как за 30 дней сделали приложение для решения задач по математике, которое через 4 месяца вышло на $1200/месяц.
А 👉 здесь рассказывают, как заработали 1 700 000 рублей на боте для создания фотокниг и какие фейлы допустили.
Первая находка в их комьюнити IT билдеров — метод, который позволяет сделать запуск за 1 месяц.
Вторая находка — метод продвижения, который они используют. В среднем на продвижение одного IT-продукта уходит $150, причем есть продукты с 200К+ юзеров 🙂
Вот здесь можно подписаться на канал, чтобы подглядеть за их запусками. А может, и попробовать сделать такой простой продукт самому)
Telegram
Короче, капитан
🔥 Забацали разбор нашего конвертера картинок под США, который за 3 месяца после старта принес +$1000
Весь путь продукта от идеи до продвижения свели в краткую статью. Внутри только самое важное:
- как придумали идею
- как реализовали
- как продвигали
- как…
Весь путь продукта от идеи до продвижения свели в краткую статью. Внутри только самое важное:
- как придумали идею
- как реализовали
- как продвигали
- как…
#заметка дня
Сказ о том, как я Hot Module Reload в секьюрном iframe настраивал.
Итак, если вы на канале достаточно давно, то можете вспомнить, что продукт, над которым я работаю — это расширение для Google Sheets и работает оно в iframe. Довольно таки огороженном iframe.
Ну как, огороженном... Там довольно странная система из четырёх вложенных iframe, каждый из которых имеет довольно жёсткие скоупы.
И в итоге, такая простая вещь как Live Reload оказалась мне попросту недоступна!
Можете себе представить, как задалбывало перезапускать проект каждый раз, когда я что-то менял? А перезапуск — это секунд 10-15, даже если сборка почти моментальная.
Любая попытка сделать window.location.reload() не то чтобы по команде из Live Server-решения, но даже по кнопке — приводила к краху iframe и, соответственно, продукта.
Оставался только один вариант — Hot Module Replacement. Да, горячая перезагрузка компонентов с нами уже несколько лет, но для легаси-проектов это достаточно проблематично. И хоть я уже 2 года как перелез на https://rspack.dev/ (и дико доволен), использовать на полную катушку не выходило.
Как я справлялся?
А я запускал куски продукта в песочницах. Набрасывал моки и запускал блоки компонентов как обычное SPA-приложение. Не очень удобно? Не то слово. Зато очень быстро и легко покрывается тестами — потому что все моки уже на месте. Сплошные плюсы.
Но при работе в команде это всё максимально неудобно. В итоге всё же пришлось разбираться с HMR.
Итак, в чём же сложности?
1. Для начала, в Google Sheets нужно передать адрес, по которому будут грузиться данные. Нет, просто localhost нельзя, нужно сохранять возможность поделиться dev-средой, как обычной таблицей.
Решение — туннели (вроде ngrok) с прокидыванием локального домена (try_files в nginx) прямо к файлам сборки.
2. Естественно, данные должны грузиться по https. К счастью, туннели и это решают.
3. Не всем разработчикам в компании нужен HMR, им достаточно и простой сборки.
4. А вот что туннели решали с трудом — это прокидывание WebSocket. Именно по ним сборка и узнаёт, что пришло время обновиться. Я никак не мог понять, как же правильно поднять одновременно https и туннель, чтобы браузер не ругался на несекьюрный источник.
И тут до меня дошло: localhost же у нас по-соглашению всегда секьюрный. Поднимать на нём https не только не имеет смысла, но и браузерам абсолютно всё равно не несекьюрные данные оттуда!
Но был нюанс: если прописать localhost в конфиге webpack-dev-server (а Rspack использует именно его), то он просто... исчезал. Растворялся в basePath, указывая на текущую страницу (aka источник iframe). Что, конечно, меня не устраивало.
К счастью, решилось старым добрым 127.0.0.1.
В остальном же проблем не возникло: HMR прекрасно настроился по официальной документации с React Fast Refresh и получился следующий конфиг:
1. Три режима среды сборки: dev, none и production. Под none подразумевается дев-билд, без запуска сервера.
2. Туннели прокинуты до каталога build внутри репозитория и предоставляют доступ из открытого интернета по кастомному домену, с https на http.
3. webpack-dev-server настроен таким образом, что чанки с обновлениями сохраняются на диск и таким способом доставляются по адресу этого же тоннеля. Формат имён одинаков для сред dev и none.
4. CORS отключён ('Access-Control-Allow-Origin': '*'), и это пока мне не очень нравится.
5. WebSocket-соединение просто запущено на 127.0.0.1.
Таким образом, получился отличный универсальный способ!
Все разработчики компании без необходимости в HMR могут просто запустить локальный билд. А те, кому надо — запускают
А главное, за счёт скорости работы Rspack я могу смело указать несколько точек входа (entrypoints) и запускать независимые друг от друга части продукта с сохранением горячей перезагрузки.
Да, немного сумбурно вышло, и большинству такое в жизни не пригодится. Но если вдруг у вас возникнет такая же необходимость шарить dev-среду проекта наружу в открытую сеть — вы знаете, что делать.
#rspack #webpack #hmr
Сказ о том, как я Hot Module Reload в секьюрном iframe настраивал.
Итак, если вы на канале достаточно давно, то можете вспомнить, что продукт, над которым я работаю — это расширение для Google Sheets и работает оно в iframe. Довольно таки огороженном iframe.
Ну как, огороженном... Там довольно странная система из четырёх вложенных iframe, каждый из которых имеет довольно жёсткие скоупы.
И в итоге, такая простая вещь как Live Reload оказалась мне попросту недоступна!
Можете себе представить, как задалбывало перезапускать проект каждый раз, когда я что-то менял? А перезапуск — это секунд 10-15, даже если сборка почти моментальная.
Любая попытка сделать window.location.reload() не то чтобы по команде из Live Server-решения, но даже по кнопке — приводила к краху iframe и, соответственно, продукта.
Оставался только один вариант — Hot Module Replacement. Да, горячая перезагрузка компонентов с нами уже несколько лет, но для легаси-проектов это достаточно проблематично. И хоть я уже 2 года как перелез на https://rspack.dev/ (и дико доволен), использовать на полную катушку не выходило.
Как я справлялся?
А я запускал куски продукта в песочницах. Набрасывал моки и запускал блоки компонентов как обычное SPA-приложение. Не очень удобно? Не то слово. Зато очень быстро и легко покрывается тестами — потому что все моки уже на месте. Сплошные плюсы.
Но при работе в команде это всё максимально неудобно. В итоге всё же пришлось разбираться с HMR.
Итак, в чём же сложности?
1. Для начала, в Google Sheets нужно передать адрес, по которому будут грузиться данные. Нет, просто localhost нельзя, нужно сохранять возможность поделиться dev-средой, как обычной таблицей.
Решение — туннели (вроде ngrok) с прокидыванием локального домена (try_files в nginx) прямо к файлам сборки.
2. Естественно, данные должны грузиться по https. К счастью, туннели и это решают.
3. Не всем разработчикам в компании нужен HMR, им достаточно и простой сборки.
4. А вот что туннели решали с трудом — это прокидывание WebSocket. Именно по ним сборка и узнаёт, что пришло время обновиться. Я никак не мог понять, как же правильно поднять одновременно https и туннель, чтобы браузер не ругался на несекьюрный источник.
И тут до меня дошло: localhost же у нас по-соглашению всегда секьюрный. Поднимать на нём https не только не имеет смысла, но и браузерам абсолютно всё равно не несекьюрные данные оттуда!
Но был нюанс: если прописать localhost в конфиге webpack-dev-server (а Rspack использует именно его), то он просто... исчезал. Растворялся в basePath, указывая на текущую страницу (aka источник iframe). Что, конечно, меня не устраивало.
К счастью, решилось старым добрым 127.0.0.1.
В остальном же проблем не возникло: HMR прекрасно настроился по официальной документации с React Fast Refresh и получился следующий конфиг:
1. Три режима среды сборки: dev, none и production. Под none подразумевается дев-билд, без запуска сервера.
2. Туннели прокинуты до каталога build внутри репозитория и предоставляют доступ из открытого интернета по кастомному домену, с https на http.
3. webpack-dev-server настроен таким образом, что чанки с обновлениями сохраняются на диск и таким способом доставляются по адресу этого же тоннеля. Формат имён одинаков для сред dev и none.
4. CORS отключён ('Access-Control-Allow-Origin': '*'), и это пока мне не очень нравится.
5. WebSocket-соединение просто запущено на 127.0.0.1.
Таким образом, получился отличный универсальный способ!
Все разработчики компании без необходимости в HMR могут просто запустить локальный билд. А те, кому надо — запускают
yarn dev
и больше никакой дополнительной конфигурации не требуется.А главное, за счёт скорости работы Rspack я могу смело указать несколько точек входа (entrypoints) и запускать независимые друг от друга части продукта с сохранением горячей перезагрузки.
Да, немного сумбурно вышло, и большинству такое в жизни не пригодится. Но если вдруг у вас возникнет такая же необходимость шарить dev-среду проекта наружу в открытую сеть — вы знаете, что делать.
#rspack #webpack #hmr