#инструмент дня
Я уже один раз потерял ссылку на этот сервис, потому на правах закладки.
Встречайте, 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
#заметка дня
Подумал тут, что talk is cheap и стоило бы, наверное, показать свой получившийся конфиг Rspack из предыдущего поста.
Когда-то я очень сильно топил за то, что тулинг для простых задач должен быть максимально простым. Я во все поля использовал create-react-app для React-проектов, но при этом использовал Broccoli.js (интересно, кто из подписчиков о нём знает?) для сборки лендингов и классических сайтов.
Не в последнюю очередь из-за скорости, но и формат конфига казался проще, чем у Gulp.
Использование же Webpack для классических HTML-страниц или библиотек выглядело тогда как совершенный бред. Вебпак — по своей сути — собирает все ресурсы в один JS-бандл (да-да, под словом все я имею в виду и HTML, и CSS, и JSON и вообще что угодно, включая картинки) и потом, если настроено, выплёвывает обратно уже обработанные файлы.
Тулинг прошёл большой путь с тех пор. И прямо сейчас в интернетах проходит срач на тему того, что create-react-app объявили устаревшим, а вместо него разработчикам предлагают подвязаться на Next.js, почти безальтернативно. При этом, команда React продолжает активно всех убеждать, что SPA всё ещё имеет смысл и конечно-конечно они не заставляют всех перейти на фреймворки и RSC. А ребятам из Vite.js крайне обидно :)
А мне, в свою очередь, обидно, что мало кто знает про Rspack! Потому, пришло время вам узреть мой конфиг :) Точнее, один из: https://gist.github.com/bekharsky/14ddc91ad72c736d56536b2fa4e16ea1
Если вы знакомы в Webpack, ничего удивительного не найдёте. А если вам придётся одновременно собирать несколько точек входа — то, поверьте, даже в Vite.js придётся прописать несколько html-файлов.
Итак, из интересного:
1. Несколько точек входа aka index.tsx-файлов в entry:
2. Специально прописанный publicPath в секции output, позволяющий сёрвить результат откуда угодно (в моём случае — из Google Sheets). В идеале, он должен браться из .env:
3. В секции module можно встретить кастомные загрузчики. И выглядят они довольно страшно, но на самом деле буквально взяты из документации по Fast Refresh. SCSS и PostCSS поддерживаются стандартными scss-loader и postcss-loader.
Опять же, если хочется простой замены CRA или Vite — есть Rsbuild, https://rsbuild.dev/. В нём всё из коробки.
Но, в целом, понимать, что же происходит — нужно.
4. Одной из крайне необходимых в легаси-проектах вещей является поддержка старых библиотек и плагинов. Поэтому в секции plugins я буквально копирую пару старых файлов в нужное место. Ну и, конечно, индикатор текущей среды — process — так необходимый реакту.
5. И что у нас остаётся? А остаётся немного настроить devServer. Я не использую https по простой причине: этим занимаются туннели. Ну и запись на диск совсем не обязательна. Да и вообще этот конфиг не нужен, если. не менять порт и работать локально.
Повторю, всё это уже из коробки имеется что в Vite, что в Rsbuild. В большинстве случаев конфиг или совсем не нужен, или будет раза в три меньше.
И если вы продолжаете собирать SPA — совсем не обязательно переходить на Next. В этом отношении мне поведение команды React очень непонятно.
Если интересна тема настройки конфигов сборки — пишите. Например, в том же Vite можно иметь несколько HTML-файлов и собирать их одновременно.
Делитесь своими конфигами. Наверняка же кто-то и Rollup использует, и Rolldown, и чистый esbuild.
#rspack #rsbuild #config
Подумал тут, что talk is cheap и стоило бы, наверное, показать свой получившийся конфиг Rspack из предыдущего поста.
Когда-то я очень сильно топил за то, что тулинг для простых задач должен быть максимально простым. Я во все поля использовал create-react-app для React-проектов, но при этом использовал Broccoli.js (интересно, кто из подписчиков о нём знает?) для сборки лендингов и классических сайтов.
Не в последнюю очередь из-за скорости, но и формат конфига казался проще, чем у Gulp.
Использование же Webpack для классических HTML-страниц или библиотек выглядело тогда как совершенный бред. Вебпак — по своей сути — собирает все ресурсы в один JS-бандл (да-да, под словом все я имею в виду и HTML, и CSS, и JSON и вообще что угодно, включая картинки) и потом, если настроено, выплёвывает обратно уже обработанные файлы.
Тулинг прошёл большой путь с тех пор. И прямо сейчас в интернетах проходит срач на тему того, что create-react-app объявили устаревшим, а вместо него разработчикам предлагают подвязаться на Next.js, почти безальтернативно. При этом, команда React продолжает активно всех убеждать, что SPA всё ещё имеет смысл и конечно-конечно они не заставляют всех перейти на фреймворки и RSC. А ребятам из Vite.js крайне обидно :)
А мне, в свою очередь, обидно, что мало кто знает про Rspack! Потому, пришло время вам узреть мой конфиг :) Точнее, один из: https://gist.github.com/bekharsky/14ddc91ad72c736d56536b2fa4e16ea1
Если вы знакомы в Webpack, ничего удивительного не найдёте. А если вам придётся одновременно собирать несколько точек входа — то, поверьте, даже в Vite.js придётся прописать несколько html-файлов.
Итак, из интересного:
1. Несколько точек входа aka index.tsx-файлов в entry:
entry: {
main: './src/index.tsx',
migrationTool: './migrationTool/index.tsx',
insights: './insights/index.tsx',
},
2. Специально прописанный publicPath в секции output, позволяющий сёрвить результат откуда угодно (в моём случае — из Google Sheets). В идеале, он должен браться из .env:
output: {
publicPath: `https://www.somedevtunnel.com/static/`,
...
}
3. В секции module можно встретить кастомные загрузчики. И выглядят они довольно страшно, но на самом деле буквально взяты из документации по Fast Refresh. SCSS и PostCSS поддерживаются стандартными scss-loader и postcss-loader.
Опять же, если хочется простой замены CRA или Vite — есть Rsbuild, https://rsbuild.dev/. В нём всё из коробки.
Но, в целом, понимать, что же происходит — нужно.
4. Одной из крайне необходимых в легаси-проектах вещей является поддержка старых библиотек и плагинов. Поэтому в секции plugins я буквально копирую пару старых файлов в нужное место. Ну и, конечно, индикатор текущей среды — process — так необходимый реакту.
5. И что у нас остаётся? А остаётся немного настроить devServer. Я не использую https по простой причине: этим занимаются туннели. Ну и запись на диск совсем не обязательна. Да и вообще этот конфиг не нужен, если. не менять порт и работать локально.
Повторю, всё это уже из коробки имеется что в Vite, что в Rsbuild. В большинстве случаев конфиг или совсем не нужен, или будет раза в три меньше.
И если вы продолжаете собирать SPA — совсем не обязательно переходить на Next. В этом отношении мне поведение команды React очень непонятно.
Если интересна тема настройки конфигов сборки — пишите. Например, в том же Vite можно иметь несколько HTML-файлов и собирать их одновременно.
Делитесь своими конфигами. Наверняка же кто-то и Rollup использует, и Rolldown, и чистый esbuild.
#rspack #rsbuild #config
🏊🏻 Бассейн, скрэмбл, код — идеальная комбо!
В Битрикс24 работают не просто айтишники, а люди, которые умеют кайфовать от жизни. Проплывают, сотни метров каждое утро, готовят завтраки, достойные мишленовских ресторанов, разбираются в футболе не хуже, чем в коде👩💻
Что их объединяет? Любовь к своему делу и место работы.
⚡️ Узнайте их истории в новых сериях «Люди Битрикс».
В Битрикс24 работают не просто айтишники, а люди, которые умеют кайфовать от жизни. Проплывают, сотни метров каждое утро, готовят завтраки, достойные мишленовских ресторанов, разбираются в футболе не хуже, чем в коде
Что их объединяет? Любовь к своему делу и место работы.
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
#фишка дня
Итак, верстаешь ты страницу с кучей врезок, аккордеонов, вкладок и прочих интерактивных элементов, требующих действия пользователя.
Но у аккордеонов есть один очевидный минус: поиск по странице не подсветит найденное. Ну ещё бы, оно же скрыто.
Так вот, Chrome очень старается это исправить и именно поэтому начиная со 102 версии у атрибута
Ссылка на блог разработчиков: https://developer.chrome.com/docs/css-ui/hidden-until-found
Сразу пример, если кому-то в лом на статью лезть: https://codepen.io/web-dot-dev/pen/JjMxmom
Попробуйте поискать слово, которое скрыто в каком-либо из аккордеонов.
Ну и для браузеров, которые не поддерживают этот атрибут, либо для иных UI-виджетов, они предлагают проверять поддержку события onbeforematch:
Довольно странное решение, если честно, но очевидно, что проблема существует и делать с ней что-то надо.
#chrome #hidden #бородач
Итак, верстаешь ты страницу с кучей врезок, аккордеонов, вкладок и прочих интерактивных элементов, требующих действия пользователя.
Но у аккордеонов есть один очевидный минус: поиск по странице не подсветит найденное. Ну ещё бы, оно же скрыто.
Так вот, Chrome очень старается это исправить и именно поэтому начиная со 102 версии у атрибута
hidden
есть уникальное для Chrome значение until-found
, говорящее само за себя.Ссылка на блог разработчиков: https://developer.chrome.com/docs/css-ui/hidden-until-found
Сразу пример, если кому-то в лом на статью лезть: https://codepen.io/web-dot-dev/pen/JjMxmom
Попробуйте поискать слово, которое скрыто в каком-либо из аккордеонов.
Ну и для браузеров, которые не поддерживают этот атрибут, либо для иных UI-виджетов, они предлагают проверять поддержку события onbeforematch:
if (!(‘onbeforematch' in document.body)) {
// expand all hidden content
}
Довольно странное решение, если честно, но очевидно, что проблема существует и делать с ней что-то надо.
#chrome #hidden #бородач
#проект дня
Не так давно проходила выставка в Смитсоновском музее американского искусства и на ней была представлена целая стена из ЭЛТ-телевизоров. Почему-то на это обратил внимание твиттер FPGA Gaming (я просто очень эмуляторы люблю).
И я подумал: «А чем я хуже?» Тем более, что лет 8 назад мы делали проект для одного энергетического напитка, в котором был буквально ровно похожая идея. И они решили повторить её и на своём сайте.
Сайт уже давно поменялся, но подготовленные к проекту изображения у меня остались. По прошествии такого количества времени — зачем пропадать красоте, верно?
Итак, вашему вниманию совершенно бесполезная, но такая забавная, пирамида из телевизоров: https://bekharsky.github.io/tvs/
На айфонах не открывайте ссылку пока, я позже переделаю загрузку видео :) С автоматическим проигрыванием видео в мобильном Safari всегда были проблемы.
Что же понадобилось для сборки?
Первым делом, естественно, нужно собрать кадры аналоговых глюков воедино, чтобы получилось несколько видео. Их и будем запускать:
После чего подготовим наш список видео и подумаем: а что нужно сделать-то?
Простой запуск всех видео разом даёт интересный, но быстро надоедающий результат. Видеть подобное, например, на заставке — банально скучно. Очевидно, нужно запускать видео рандомно.
А лучше не просто рандомно, а ещё и сами видео на телевизорах менять!
И тут нам помогут вечные друзья: raf и ref.
В смысле, requestAnimationFrame и reference в React. А не то, что вы подумали.
С помощью requestAnimationFrame добиваемся рандомного запуска в пределах от секунды до трёх, а с помощью массива рефов — просто подменяем src видео в цикле.
Кстати, забавный трюк:
Проп ref представлен в виде функции, ref callback:
В этот момент React присваивает ссылку на ноду элементу массива. Это хорошо описано в документации и не только экономит число ссылок и использований useRef, но и позволяет динамически этим списком управлять.
Ну и осталось — а осталось только запустить несколько рандомных видео и вовремя остановить их.
Повторю, на айфонах не всё так просто, поэтому запуск видео там я отложил на потом.
Исходный код, как всегда, доступен: https://github.com/bekharsky/tvs
Кстати, чтобы сделать эффекты ещё более интересными, можно не в видео их собирать, а перебирать картинки на лету. Что даст абсолютный контроль над кадрами. Чем, наверное, и займёмся вскорости.
Задавайте ваши ответы, котаны :)
#react #art #ref
Не так давно проходила выставка в Смитсоновском музее американского искусства и на ней была представлена целая стена из ЭЛТ-телевизоров. Почему-то на это обратил внимание твиттер FPGA Gaming (я просто очень эмуляторы люблю).
И я подумал: «А чем я хуже?» Тем более, что лет 8 назад мы делали проект для одного энергетического напитка, в котором был буквально ровно похожая идея. И они решили повторить её и на своём сайте.
Сайт уже давно поменялся, но подготовленные к проекту изображения у меня остались. По прошествии такого количества времени — зачем пропадать красоте, верно?
Итак, вашему вниманию совершенно бесполезная, но такая забавная, пирамида из телевизоров: https://bekharsky.github.io/tvs/
На айфонах не открывайте ссылку пока, я позже переделаю загрузку видео :) С автоматическим проигрыванием видео в мобильном Safari всегда были проблемы.
Что же понадобилось для сборки?
Первым делом, естественно, нужно собрать кадры аналоговых глюков воедино, чтобы получилось несколько видео. Их и будем запускать:
ffmpeg -f image2 -r 25 -pattern_type glob -i '*.png' -vcodec libx264 -crf 22 video.mp4
После чего подготовим наш список видео и подумаем: а что нужно сделать-то?
Простой запуск всех видео разом даёт интересный, но быстро надоедающий результат. Видеть подобное, например, на заставке — банально скучно. Очевидно, нужно запускать видео рандомно.
А лучше не просто рандомно, а ещё и сами видео на телевизорах менять!
И тут нам помогут вечные друзья: raf и ref.
В смысле, requestAnimationFrame и reference в React. А не то, что вы подумали.
С помощью requestAnimationFrame добиваемся рандомного запуска в пределах от секунды до трёх, а с помощью массива рефов — просто подменяем src видео в цикле.
Кстати, забавный трюк:
<video
ref={(el) => (videoRefs.current[i] = el)}
className="video"
key={`video-${i}`}
src={name}
loop
muted
/>
Проп ref представлен в виде функции, ref callback:
ref={(el) => (videoRefs.current[i] = el)}
В этот момент React присваивает ссылку на ноду элементу массива. Это хорошо описано в документации и не только экономит число ссылок и использований useRef, но и позволяет динамически этим списком управлять.
Ну и осталось — а осталось только запустить несколько рандомных видео и вовремя остановить их.
Повторю, на айфонах не всё так просто, поэтому запуск видео там я отложил на потом.
Исходный код, как всегда, доступен: https://github.com/bekharsky/tvs
Кстати, чтобы сделать эффекты ещё более интересными, можно не в видео их собирать, а перебирать картинки на лету. Что даст абсолютный контроль над кадрами. Чем, наверное, и займёмся вскорости.
Задавайте ваши ответы, котаны :)
#react #art #ref
#инструмент дня
Даже два. И оба для работы с SVG.
Одной из сильно раздражающих проблем при работе с SVG является, как ни странно, сложность кропа. Ну, обрезки полей, whitespace.
Почему? Ну, потому что многие редакторы (Inksape тот же) делают просто изменение viewBox или ещё трансформами подгоняют кривые.
Работает ли это? Ну, в целом, да. Правда, приносит с собой неожиданности вроде замыленных границ, сложности с расчётом анимаций и внезапном отсутствии поддержки в различных других редакторах.
Гарантии, что любой SVG загрузится в любом редакторе и так в принципе нет. Стандарт слишком большой, мусора напихать можно слишком много.
Так вот, к чему это я. Точно, к обрезке.
Раз: https://svgcrop.com/
Два: http://editor.method.ac/
Первая утилита обрезает по viewBox. А вот второй редактор — в него можно загрузить SVG с применёнными трансформациями сдвига, выделить и выбрать в меню Object 👉 Reorient path, что перепишет кривые с учётом трансформаций.
Вспомню, как это делать в Inkscape — напишу 🙂
#svg #crop #бородач
Даже два. И оба для работы с SVG.
Одной из сильно раздражающих проблем при работе с SVG является, как ни странно, сложность кропа. Ну, обрезки полей, whitespace.
Почему? Ну, потому что многие редакторы (Inksape тот же) делают просто изменение viewBox или ещё трансформами подгоняют кривые.
Работает ли это? Ну, в целом, да. Правда, приносит с собой неожиданности вроде замыленных границ, сложности с расчётом анимаций и внезапном отсутствии поддержки в различных других редакторах.
Гарантии, что любой SVG загрузится в любом редакторе и так в принципе нет. Стандарт слишком большой, мусора напихать можно слишком много.
Так вот, к чему это я. Точно, к обрезке.
Раз: https://svgcrop.com/
Два: http://editor.method.ac/
Первая утилита обрезает по viewBox. А вот второй редактор — в него можно загрузить SVG с применёнными трансформациями сдвига, выделить и выбрать в меню Object 👉 Reorient path, что перепишет кривые с учётом трансформаций.
Вспомню, как это делать в Inkscape — напишу 🙂
#svg #crop #бородач
#статья дня
Встроенная в браузеры функция выполнения HTTP-запросов
Топорная, если хотите.
Ошибки бросает только на ошибках сервера или соединения (404 — не ошибка), нужно самому формировать заголовки запроса, даже самому формировать строку с JSON или данными формы в urlencode...
Очень многие вместо неё как использовали, так и продолжают использовать тот же axios, кто-то берёт разные иные обёртки, как Tanstack Query aka React Query, а кто-то один раз написал свою реализацию обработки ошибок и прочего бойлерплейта — и забыл.
Так вот, позвольте вам напомнить, что таки есть причина для этой кондовости. По-порядку.
Чаще всего получение данных сводится к разрешению двух промисов:
Но почему? Почему fetch сразу данные-то не отдаёт? К чему эти танцы?
Так вот, всё дело в том, что мир не ограничивается гонянием джисонов по сети. Возможно, нужен просто текст. Возможно, решение нужно принять ещё до того, как заняться обработкой тела запроса. Возможно, бинарные данные. А, возможно, данные кусками или потоком — stream — который можно прервать в любой момент:
В любом случае, так или иначе, собственно, fetch возвращает промис с результатами запроса, а уже потом — дело за вами, как его обработать.
И вот хороший пример — от Тома Стивена: https://tomontheinternet.com/why-two-awaits/
В статье он даёт ссылку на код с демонстрацией: https://github.com/tom-on-the-internet/fetch-demonstration
Ну и я решил и в песочницу этот код запихать, для наглядности и понимания процесса: https://codesandbox.io/p/devbox/mvhrgz
Так что, возможно,
#fetch #http #stream
Встроенная в браузеры функция выполнения HTTP-запросов
fetch
— штука достаточно кондовая. Топорная, если хотите.
Ошибки бросает только на ошибках сервера или соединения (404 — не ошибка), нужно самому формировать заголовки запроса, даже самому формировать строку с JSON или данными формы в urlencode...
Очень многие вместо неё как использовали, так и продолжают использовать тот же axios, кто-то берёт разные иные обёртки, как Tanstack Query aka React Query, а кто-то один раз написал свою реализацию обработки ошибок и прочего бойлерплейта — и забыл.
Так вот, позвольте вам напомнить, что таки есть причина для этой кондовости. По-порядку.
Чаще всего получение данных сводится к разрешению двух промисов:
let response = await fetch("/some-url")
let myObject = await response.json()
Но почему? Почему fetch сразу данные-то не отдаёт? К чему эти танцы?
Так вот, всё дело в том, что мир не ограничивается гонянием джисонов по сети. Возможно, нужен просто текст. Возможно, решение нужно принять ещё до того, как заняться обработкой тела запроса. Возможно, бинарные данные. А, возможно, данные кусками или потоком — stream — который можно прервать в любой момент:
async function readData(url) {
const response = await fetch(url);
for await (const chunk of response.body) {
// Do something with each "chunk"
}
// Exit when done
}
В любом случае, так или иначе, собственно, fetch возвращает промис с результатами запроса, а уже потом — дело за вами, как его обработать.
И вот хороший пример — от Тома Стивена: https://tomontheinternet.com/why-two-awaits/
В статье он даёт ссылку на код с демонстрацией: https://github.com/tom-on-the-internet/fetch-demonstration
Ну и я решил и в песочницу этот код запихать, для наглядности и понимания процесса: https://codesandbox.io/p/devbox/mvhrgz
Так что, возможно,
fetch
хорош таким, какой он есть. Универсальным.#fetch #http #stream
#фишка дня
Думаю, все знают про :nth-child,
Что в них самое раздражающее?
Кто сказал нумерация с единицы? Иди в свой Си.
Конечно же это неочевидность, а когда-то и невозможность, выбора элементов по классу или иному атрибуту!
Да-да, :nth-of-type выбирает по тегу, даже не по классу. Так что же делать?
А делать вот что: уже пару лет с нами присутствует синтаксис-дополнение к
Выглядит так:
А применяется так:
Первый выберет второе появление элемента с классом
Подробнее — в блоге разработчиков Chrome.
#css #nth #selector
Думаю, все знают про :nth-child,
:nth-last-child
. А также про :nth-of-type
и :nth-last-of-type
.Что в них самое раздражающее?
Кто сказал нумерация с единицы? Иди в свой Си.
Конечно же это неочевидность, а когда-то и невозможность, выбора элементов по классу или иному атрибуту!
Да-да, :nth-of-type выбирает по тегу, даже не по классу. Так что же делать?
А делать вот что: уже пару лет с нами присутствует синтаксис-дополнение к
nth-child
. И называется он of S
.Выглядит так:
:nth-child(An+B [of S]?)
:nth-last-child(An+B [of S]?)
А применяется так:
:nth-child(2 of .highlight)
:nth-child(even of :not([hidden]))
Первый выберет второе появление элемента с классом
.highlight
, а второй — все чётные не скрытые элементы.Подробнее — в блоге разработчиков Chrome.
#css #nth #selector
#фишка дня
От Темани Афифа aka CSS Challenges! Он нам уже много крутого подарил :)
Что делать, если нужно несколько кнопок одной ширины? В смысле, подстраивающихся под самую широкую, а не просто заданной.
Использовать гриды, конечно!
Как-то так:
Подробнее: https://css-tip.com/equal-width-button/
#css #button #grid
От Темани Афифа aka CSS Challenges! Он нам уже много крутого подарил :)
Что делать, если нужно несколько кнопок одной ширины? В смысле, подстраивающихся под самую широкую, а не просто заданной.
Использовать гриды, конечно!
Как-то так:
.container {
display: inline grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
}
Подробнее: https://css-tip.com/equal-width-button/
#css #button #grid
This media is not supported in your browser
VIEW IN TELEGRAM
#фишка дня
Надоело искать гит-бранчи в бесконечном их списке в консоли?
Это всё потому что они сортируются по алфавиту. Что вообще далеко не всегда удобно. Точнее, это удобно только когда название ветки начинается с номера тикета.
Но, опять же, а если проектов несколько?..
Решение очевидно: сортировать бранчи по дате изменения!
Для чего нужен вот этот конфиг:
И всё, бранчи отсортируются по дате последнего коммита. Сильно удобнее, кмк.
Автор видео с примером — Бен Холмс.
P. S. сейчас евангелисты GUI для Git придут мне напихивать :)
#git #feature
Надоело искать гит-бранчи в бесконечном их списке в консоли?
Это всё потому что они сортируются по алфавиту. Что вообще далеко не всегда удобно. Точнее, это удобно только когда название ветки начинается с номера тикета.
Но, опять же, а если проектов несколько?..
Решение очевидно: сортировать бранчи по дате изменения!
Для чего нужен вот этот конфиг:
git config --global branch.sort -committerdate
И всё, бранчи отсортируются по дате последнего коммита. Сильно удобнее, кмк.
Автор видео с примером — Бен Холмс.
P. S. сейчас евангелисты GUI для Git придут мне напихивать :)
#git #feature
#инструмент дня
Наткнулся на тред Андрея Романова про мониторинг крашей. Публикуется с изменениями.
Не тех крашей, что с чёлкой, а крашей браузера. Падений на ровном месте.
Очевидно, при падении ваш код перестанет выполняться, поэтому стандартные методы здесь не работают.
Зато Chrome нарисует симпатичную графику, очень полезно.
Однако, есть экспериментальный Reporting API, который позволяет браузеру отправлять отчёты о сбоях, нарушениях политик безопасности и использовании устаревших функций:
🔗 Спецификация API: https://w3c.github.io/reporting/
🔗 Обзор на Chrome for Developers: https://developer.chrome.com/docs/capabilities/web-apis/reporting-api
Reporting API предоставляет два способа получения отчётов:
📌 Глобальный класс ReportingObserver — позволяет подписаться на предупреждения и обрабатывать их в JavaScript. Он не фиксирует падения, так как работает на клиенте.
📌 HTTP-заголовок Reporting-Endpoints — задаёт серверные эндпойнты, на которые браузер отправляет отчёты. Этот метод покрывает все виды ошибок, включая падения вкладки.
Хотя API остаётся нестабильным и реализован не во всех браузерах, у него нет аналогов. Например, Figma уже использует его для мониторинга крашей браузера:
🔗 Разбор использования в Figma: https://neugierig.org/software/blog/2023/01/browser-crashes.html
Лучше так, чем совсем не иметь :)
Впрочем, отличным вариантом остаётся и пульс aka heartbeat с выставлением флага. Если приложение завершилось адекватно — флаг помечается как закрытый, а по пути можно собрать дополнительных данных.
Ну и, как минимум, средства вроде Sentry и Datadog отлично справляются с трекингом ошибок, по которым тоже можно косвенно понять причину падения.
#web #crash #report
Наткнулся на тред Андрея Романова про мониторинг крашей. Публикуется с изменениями.
Не тех крашей, что с чёлкой, а крашей браузера. Падений на ровном месте.
Очевидно, при падении ваш код перестанет выполняться, поэтому стандартные методы здесь не работают.
Зато Chrome нарисует симпатичную графику, очень полезно.
Однако, есть экспериментальный Reporting API, который позволяет браузеру отправлять отчёты о сбоях, нарушениях политик безопасности и использовании устаревших функций:
🔗 Спецификация API: https://w3c.github.io/reporting/
🔗 Обзор на Chrome for Developers: https://developer.chrome.com/docs/capabilities/web-apis/reporting-api
Reporting API предоставляет два способа получения отчётов:
📌 Глобальный класс ReportingObserver — позволяет подписаться на предупреждения и обрабатывать их в JavaScript. Он не фиксирует падения, так как работает на клиенте.
📌 HTTP-заголовок Reporting-Endpoints — задаёт серверные эндпойнты, на которые браузер отправляет отчёты. Этот метод покрывает все виды ошибок, включая падения вкладки.
Хотя API остаётся нестабильным и реализован не во всех браузерах, у него нет аналогов. Например, Figma уже использует его для мониторинга крашей браузера:
🔗 Разбор использования в Figma: https://neugierig.org/software/blog/2023/01/browser-crashes.html
Лучше так, чем совсем не иметь :)
Впрочем, отличным вариантом остаётся и пульс aka heartbeat с выставлением флага. Если приложение завершилось адекватно — флаг помечается как закрытый, а по пути можно собрать дополнительных данных.
Ну и, как минимум, средства вроде Sentry и Datadog отлично справляются с трекингом ошибок, по которым тоже можно косвенно понять причину падения.
#web #crash #report
Фронтенд — это не только натянуть верстку и подключить API. Чем глубже вникаешь в технологии, тем больше вопросов возникает. Как браузер работает с памятью? Почему одни операции быстрее других? Как устроены алгоритмы, которые ты используешь, даже не задумываясь?
Я уже некоторое время подписан на канал Андрея Кобеца (www.tg-me.com/kobezzza_channel). Андрей — инженер с 20-летним опытом, 10 лет руководил фронтендом в Яндексе, а теперь делится знаниями с разработчиками, которые хотят расти не только в грейде, но и в понимании технологий.
Что у него интересного:
🔹 Разборы концепций — «Передача по ссылке и по значению», «Как интерпретируется код», «Потоки и память в JS»
🔹 Как алгоритмы помогают фронтендеру — реальные кейсы, без теории ради теории
🔹 Карьерные советы — что делать, чтобы зарабатывать больше, но не превращаться в менеджера
🔹 Нестандартные темы — например, как устроена безопасность по памяти или почему в Unix «всё есть файл»
Читается легко, но плотно. Если интересно не просто писать код, а понимать, как он работает под капотом, рекомендую заглянуть:
👉 www.tg-me.com/kobezzza_channel
Реклама. ИП Кобец Д.Д. ОГРНИП: 322237500264561 erid: 2VtzqwmTdAW
Я уже некоторое время подписан на канал Андрея Кобеца (www.tg-me.com/kobezzza_channel). Андрей — инженер с 20-летним опытом, 10 лет руководил фронтендом в Яндексе, а теперь делится знаниями с разработчиками, которые хотят расти не только в грейде, но и в понимании технологий.
Что у него интересного:
🔹 Разборы концепций — «Передача по ссылке и по значению», «Как интерпретируется код», «Потоки и память в JS»
🔹 Как алгоритмы помогают фронтендеру — реальные кейсы, без теории ради теории
🔹 Карьерные советы — что делать, чтобы зарабатывать больше, но не превращаться в менеджера
🔹 Нестандартные темы — например, как устроена безопасность по памяти или почему в Unix «всё есть файл»
Читается легко, но плотно. Если интересно не просто писать код, а понимать, как он работает под капотом, рекомендую заглянуть:
👉 www.tg-me.com/kobezzza_channel
Реклама. ИП Кобец Д.Д. ОГРНИП: 322237500264561 erid: 2VtzqwmTdAW
This media is not supported in your browser
VIEW IN TELEGRAM
#инструмент дня
Как сконвертировать что угодно во что угодно?
Через https://transform.tools/, конечно!
SVG в JSX, CSS в TailwindCSS и обратно, Flow в TypeScript, JSON Schema в OpenAPI schema и так далее до бесконечности.
Конечно, если нужно делать это массово — не вопрос, стоит использовать специально подготовленные утилиты. Но, как минимум, их можно подсмотреть прямо в репозитории проекта: https://github.com/ritz078/transform
#tool
Как сконвертировать что угодно во что угодно?
Через https://transform.tools/, конечно!
SVG в JSX, CSS в TailwindCSS и обратно, Flow в TypeScript, JSON Schema в OpenAPI schema и так далее до бесконечности.
Конечно, если нужно делать это массово — не вопрос, стоит использовать специально подготовленные утилиты. Но, как минимум, их можно подсмотреть прямо в репозитории проекта: https://github.com/ritz078/transform
#tool