Telegram Web Link
Великолепная детективная история
Vitest: invalid JSON syntax found at position -1.

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

Я уже рассказывал, что витест для нас компромиссный опыт и породил экстравагантные практикие в духе «гоняем 100 пайплайнов и проверяем, что не флакает». В общем, задумал я обновить его немного, открыл пул-реквест, погонял те самые 100 пайплайнов — всё зеленое! Мёрджим!

Проходит 2 недели и 60% пайплайнов начинают падать… Разработчики ругаются, тимлид предлагает откатывать, я в замешательстве — работало же! Снова начинаю гонять пайплайны, находим 3 проблемных теста, которые никто не трогал уже полгода. Выключаем — всё снова стабильно и зелено. Начинаю разбираться…

Ошибка выглядит так — Error: Failed to parse JSON file, invalid JSON syntax found at position -1. Спасибо, очень информативно! Собираю такой же докер образ как на CI, тыкаю проблемные тест — ничего. Т.к. проблема воспроизводится только на CI, то решаю запатчить vite через yarn patch, добавив название файла в лог. Сработало — проблемный файл мы генерируем на CI и путь до него известен.

Проверяю содержимое файла до тестов — всё на месте. Проверяю после тестов — и снова всё на месте. Но в тестах почему-то всё так же ломается. И тут я замечаю, что у падающих шардов есть кое-что общее — падает именно первый тест. Смотрю как это работает внутри vite — обычный fs.readFile и JSON.parse. В голову закрадывается страшная идея — а что если это какя-то проблема с файловой системой и одновременным чтением одного файла из нескольких процессов. Ищу ишью в ноде, но ничего прям конкретного не вижу. Уже начинаю писать скрипт для стресс-теста одновременного чтения, чтобы проверить гипотезу и тут в голову приходит идея — а что если кто-то этот файл всё таки перезаписывает?

Проверяю файл через fs.stat сразу после записи и после тестов — даты создания и редактирования отличаются! Смотрю немного в пайплайн и понимаю, что внутри одной из команд мы запускаем генерацию этого файла. Мда! А ларчик просто открывался, как говорится. Убираю лишнюю генерацию и всё сразу же зеленеет.

Для меня было откровением, что при записи файл может принимать какое-то промежуточное состояние. Т.е. не before → after, а before → empty → after.

Рефлексируя о дебаге и что могло упростить поиск, пришёл к такому алгоритму:
1. Если ошибка указывает на неочевидное место, то её сразу же надо патчить, чтобы сузить радиус дебага (в очередной раз могу поругать бандлинг зависимостей в vite, кажется в новой версии зависимости ошибка уже содержит путь до файла).
2. В ошибках нужно искать общие признаки (в моём случае что падает только первый тест в каждом из шардов).
3. Проверять самые простые гипотезы в userland коде, а не искать какие-то баги в больших популярных библиотеках (vite и node в нашем случае)

Остаётся вопрос: а почему ошибка не сразу всплыла, а через 2 недели?
Ответ прост: у нас 4 шарда и не все тесты импортируют проблемный файл. С добавлением/удалением тестов порядок в шардах немного меняется и тесты, которые читают файл, становятся первыми в очереди и попадают в те самые первые 5 секунд, когда мы перезаписываем файл.

Такой вот детектив. А как вы провели вечер пятницы?
👍133💩2
Deep Dive into Rspack & Webpack Tree Shaking

Крутой разбор механизма работу Tree-shaking в Webpack. Tree-shaking - это фича бандлеров, которая позволяет при сборке выкидывать код, который не нужен в конечном приложении. Решение о неиспользуемости кода принимается на разных уровнях анализа - как на основе анализа стейтментов в конкретном файле, так и на основе анализа импортов и экспортов

В Webpack tree-shaking реализуется тремя механизмами: оптимизация usedExports, оптимизация sideEffect и оптимизация dead code elimination. Оптимизации разбираются от простых к сложным.

Первая разбираемая оптимизация: Dead Code Elimination (уничтожение мертвого кода). Эта оптимизация работает на двух уровнях.

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

Например

if(false){
console.log(a) // очевидно неиспользуемая ветвь кода, можно удалять
} else {
console.log(b);
}


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


function get_one(){
return 1;
}
let res = get_one() + get_one(); // функции заинлайнятся, а результат сложится

if(res != 2){ // сборщик понимает что тут 2 != 2, что неверно
console.log(c);
}


Оптимизация usedExports убирает из кода неиспользуемые экспорты. Бандлер, при сборке проекта, промечает все экспортируемые сущности как используемые и неиспользуемые. Все экспорты, которые в итоге оказались неиспользуемыми, можно смело удалять

Например

// index.js
import { a } from './util'
console.log(a)

// util.js
export const a = true

export const b = false // экспорт будет удален т.к. не используется


Как это работает: webpack помечаем неиспользуемые импорты особой инструкцией /* unused harmony export b */, которая обрабатывается механизмом, который отвечает за dead code elimination. Такие экспорты считаются неиспользуемым кодом, а значит его можно удалить

Поверх этих двух оптимизаций работает оптимизация sideEffects, она позволяет удалить модуль, если а) ни один его экспорт не используется б) он не имеет сайд-эффектов. Пункт а) мы уже разобрали - за это отвечает механизм usedExports, но как определить, есть ли в модуле сайд-эффекты?

Допустим, есть модуль, в котором обе экспортирующиеся переменные не используются, но есть вызов функции

export const c = 123;
export const d = test();
function test(){
/* some code */
}


Как определить, что функция test не создает сайд-эффектов (например, не добавляет что-то в window) без глубокого анализа (т.к. глубокий анализ - вещь сложная и замедлит сборку). Для этого есть 2 способа:

Первый - пометить вызов функции чистым

export const c = 123;
export const d = /*#__PURE__*/ test();
function test(){
/* some code */
}


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

Второй вариант - пометить весь модуль чистым. Делается это через поле в package.json

// package.json
{
"sideEffects": false
}


Бандлер также доверяет этому полю. Однако, здесь могут возникнуть сложные ситуации, когда модуль А имеет sideEffects: false, а он использует модуль Б, который имеет sideEffects: true. Есть еще всякие разные граничные случаи и каждый бандлер обрабатывает их по-своему.

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

Рекомендую к прочтению, если вы периодически занимаетесь инфраструктурой сборки в проекте.


https://github.com/orgs/web-infra-dev/discussions/17

#development #javascript #webpack #treeShaking #performance
👍153🔥1
Извините, но сегодня день начнется с рекомендаций других каналов 🙃

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

Подборка реально крутая, смотрите что вам по душе и подписывайтесь!

🔗 https://www.tg-me.com/addlist/Z6Efi4jXwe9lODcy
2👍2🔥2
Канал про решение алгоритмических задач и подготовку к собеседованиям - Algorithmics. Я сам не фанат алгоритмических секций на собеседованиях, но контент в канале действительно крутой контент по разбору задач. В канале постятся сами задачки и краткое решение, в блоге - детальное объяснение решения и решение задачи на нескольких языках.

Рекоменндую к подписке, если вам интересны алгоритмические задачки
👍61
Hello Bun: How Sveld now deploys 2x faster on GitHub and Render

Небольшая статья про перевод инфраструктуры сборки проекта для Svelte на Bun. В целом, миграция для такого небольшого проекта дело достаточно тривиальное - поменять несколько команд и потратить вечерок на замену небольших конструкций кода (для автора это cli-скрипт и код авто-тестов)

Какие результаты:
- Сборка пакета в github-actions проходит в 2-3 раза быстрее
- Пакеты устанавливаются в 2-20 раз быстрее. При этом bun без кешей не сильно отстает от Yarn с кэшами.
- Юнит-тесты бегут в 2 раза быстрее
- В 2 раза ускорился деплой в Render (это платформа для деплоя статичных сайтов

https://render.com/blog/hello-bun-deploy-2x-faster-on-github-render

#development #javascript #bun #migration #svelte
👍8
The Front End Developer (Engineer) Handbook 2024

Невероятно огромный handbook про профессию фронтенд инженера в 2024 году. В хендбуке описано все - начиная от определения профессии, переходя через базовые знания (работы сети например) и заканчивая обзором современных инструментов и практик.

Рекомендую к просмотру

https://frontendmasters.com/guides/front-end-handbook/2024/

#development #frontend
👍15🔥2
HTML attributes vs DOM properties

Джейк Арчибальд написал хорошую статью про разницу между HTML Атрибутами и свойствами DOM-элемента. Я, честно говоря, никогда даже об этом не задумывался - работает и работает. В статье хорошо объясняется разница между ними, а также показываются подводные камни при работе с ними

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

const div = document.createElement('div');

div.setAttribute('foo', 'bar');
div.hello = 'world';

console.log(div.outerHTML); // '<div foo="bar"></div>'

const obj = { foo: 'bar' }
div.setAttribute('foo', obj);
console.log(typeof div.getAttribute('foo')); // 'string'
console.log(div.getAttribute('foo')); // '[object Object]'

// <div id="test" HeLlO="world"></div>
const div = document.querySelector('#test'); console.log(div.getAttributeNames()); // ['id', 'hello']


При этом атрибуты и свойства друг с другом не связаны - можно установить одноименные свойство и атрибут в разные значения

const  div = document.createElement('div')

div.setAttribute('kek', 'true')
div.kek = false

console.log(div.getAttribute('kek')) // true


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

const div = document.querySelector('#foo'); console.log(div.getAttribute('id')); // 'foo'
console.log(div.id); // 'foo'

div.id = 'bar';
console.log(div.getAttribute('id')); // 'bar'
console.log(div.id); // 'bar'


Все эти связи описаны в спеке и описаны немного по-разному. Например, свойство crossOrigin и атрибут crossorigin, но свойство ariaLabel и атрибут aria-label

Также есть приколы, связанные с приведением типов, валидацией и дефолтами

const input = document.createElement('input'); 
console.log(input.getAttribute('type')); // null
console.log(input.type); // 'text'

input.type = 'number';
console.log(input.getAttribute('type')); // 'number'
console.log(input.type); // 'number'

input.type = 'foo';
console.log(input.getAttribute('type')); // 'foo'
console.log(input.type); // 'text'


https://jakearchibald.com/2024/attributes-vs-properties/

#development #dom #domProperties #domAttributes
👍7🔥63
cpupro — лучший cpu профайлер

Не так давно я искал узкие места в витесте и вебпаке и внезапно наткнулся на cpupro. Когда я увидел, кто автор, то понял что инструмент плохим быть не может в принципе: Рома Дворнов — знак качества!

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

https://github.com/lahmatiy/cpupro/releases/tag/v0.5.0
👍9
Дайджест за 2024-05-06 - 2024-05-10


React 19 Beta
Выпущен React 19 Beta! Обновляться пока рано, но уже можно готовиться к изменениям.

Первое большое изменение - Actions. Команда React не стала мудрить и взяла термин, который используется кучей тулов для менеджмента состояния и начала его использовать. В React-компонентах часто необходимо делать асинхронные действия, например, загружать данные из API. Сейчас в React это можно сделать композицией нескольких useState. А в React 19 можно использовать несколько новых хуков, которые упрощают работу с такими функциями

Deep Dive into Rspack & Webpack Tree Shaking
Крутой разбор механизма работу Tree-shaking в Webpack. Tree-shaking - это фича бандлеров, которая позволяет при сборке выкидывать код, который не нужен в конечном приложении. Решение о неиспользуемости кода принимается на разных уровнях анализа - как на основе анализа стейтментов в конкретном файле, так и на основе анализа импортов и экспортов

В Webpack tree-shaking реализуется тремя механизмами: оптимизация usedExports, оптимизация sideEffect и оптимизация dead code elimination. Оптимизации разбираются от простых к сложным.

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

Канал про митапы\конференции и другие IT-движухи в России.
В канале постится достаточно много событий разной тематики и в разных городах.

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

Рекоменндую к подписке, если вам интересны алгоритмические задачки

Hello Bun: How Sveld now deploys 2x faster on GitHub and Render
Небольшая статья про перевод инфраструктуры сборки для Svelte на Bun. В целом, миграция небольшого проекта дело достаточно тривиальное - поменять несколько команд и потратить вечерок на замену небольших конструкций кода (для автора это cli-скрипт и код авто-тестов)

The Front End Developer (Engineer) Handbook 2024
Невероятно огромный handbook про профессию фронтенд инженера в 2024 году. В хендбуке описано все - начиная от определения профессии, переходя через базовые знания (работы сети например) и заканчивая обзором современных инструментов и практик.

Рекомендую к просмотру

HTML attributes vs DOM properties
Джейк Арчибальд написал хорошую статью про разницу между HTML Атрибутами и свойствами DOM-элемента. Я, честно говоря, никогда даже об этом не задумывался - работает и работает. В статье хорошо объясняется разница между ними, а также показываются подводные камни при работе с ними

Репост cpupro — лучший cpu профайлер
это самый быстрый аналайзер из существующих, способный переваривать огромные (2гб) профайлы.

——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегамдрузьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂
👍151
Development notes from xkcd's "Machine"

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

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

Так, относительно игроков принципы были следующие:
- Дать больше возможностей игрокам, даже ценой корректности создаваемых машин. Можно было бы сделать так, чтобы все было строго детерминировано и шары все летели в одной карте только по одному маршруту. Но это а) не так весело б) ограничивает игроков
- Т.к. все отдельные песочницы должны склеиваться в одно огромное поле, то необходимо зафиксировать "интерфейс" - откуда приходят шары и куда должны уходить. Что нужны шары уходят в нужные дырки даже проверяется автоматикой.
- Сколько нужно ждать, чтоб убедиться, что шары действительно летят туда, куда нужно? Ведь можно построить весьма заковыристый механизм, который будет очень долго жонглировать шарами. Разработчики приняли решение, что шары должны достигать своей цели за 30 секунд

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

Про техническую сторону написано не очень много: как движок физики был взят Rapier (написан на Rust, запускается в WASM). Над Rapier был написан UI на React с кастомным контекстом, который управляет объектами Rapier. Использование React позволило легко создавать виджеты, которые влияли на физику (например, Вентилятор). Также удобным оказалась цикл жизни React-компонентов - при скроле холста с механизмами, те механизмы, которые пропали из вида анмаунтились в React, что убирало объекты из Rapier. Получается, что нет на экране - нет и в симуляции физики, что звучит как хороший паттерн. В статье есть ссылки на репозиторий с реализацией и код там выглядит внушительно.

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


https://chromakode.com/post/xkcd-machine/

#development #javascript #react #xkcd
👍5
The evolution of Figma’s mobile engine: Compiling away our custom programming language

Статья от команды Figma про то, как они мигрировали с языка Skew на Typescript. Если я правильно понял, Skew - это сайд-проект с ранних дней Figma, цель которого - предоставить язык, который быстро работает и компилируется.

Основные причины, по которым решили отказаться от Skew в пользу Typescript'а заключаются в следующем:
- Тяжело масштабировать разработку т.к. специалистов по Skew нет на рынке и никто его учить не хочет
- Typescript стал де-факто стандартом в вебе и заимел много полезных фичей (особенно по сравнению с временами, когда Figma только стартовала) и имеет прекрасный тулинг вокруг
- Мобильные браузеры стали поддерживать WASM, что позволяет перевести наиболее требовательные к производительности части кода в WASM

Т.е. в целом 2 основных причины: WASM позволяет портировать наиболее "горячий" код без потери производительности (а по замерам команды, потеря производительности при компиляции в JS составляет в 2 раза по сравнению с WASM), а Typescript позволяет разрабатывать на современном популярном языке остальные части.

Первый прототип миграции ребята делали еще в 2020 год и убедились, что это в целом реальная история и поставили себе цель - полностью уйти со Skew. Но т.к. нельзя переписать такой большой проект разом на другой язык, то миграция реализовывалась в 3 фазы

Первая фаза: разработали транспайлер Skew => Typescript. Конечно же не без проблем и их приходилось фиксить.
Вторая фаза: когда генерируемый код стал похож на работающий, начали отдавать его пользователям
Третья фаза: когда убедились, что весь код работает хорошо, просто запустили транспиляцию Skew => Typescript и удалили все Skew исходники

Отдельного внимания заслуживает транспилятор Skew => Typescript. В целом Skew уже умел билдится в Javascript, поэтому транспиляция в Typescript делалась не с нуля. Тем не менее, во время создания транспилятора нашлись интересные нюансы

Например, использование деструктуризации замедляет код на 25%, поэтому при обращении к arguments Skew генерирует код, в котором доступ к элементам массива осуществляется по индексу.

Другая проблема оказалась связана с интересным механизмом в Skew, который называется devirtualization. Суть его в том, что метод класса отвязывается от класса и становится обособленной функцией
myObject.myFunc(a, b)
// becomes...
myFunc(myObject, a, b)

Эта оптимизация как-то ускоряет код и она была в Skew, но её нет в Typescript. Я так понял, что ребята решили отказаться от нее и на основе логов искали код, который рассчитывал на эту фичу Skew

Еще одна прикольная штука связанная с компилятором - это то что ребята сделали мапинг сорс мапов javascript => typescript => skew. Первую часть (ts => js) давал esbuld из коробки. Вторую часть (ts => skew) ребята написали сами.



https://www.figma.com/blog/figmas-journey-to-typescript-compiling-away-our-custom-programming-language/

#development #typescript #figma #migration #skew
13👍2🔥2
How to document your JavaScript package

Хорошая статья от команды Deno про то, как писать документацию к пакету в виде JSDoc. В рамках данной статьи рассказывается, как пользоваться JSDoc и как JSR использует JSDoc для автоматического создания документации к пакету.

Отдельно замечу, что реализация автодокументации от JSR очень хороша. Идея проста - пишите документацию к коду, а инструмент это все распарсит и опубликует в удобном для людей виде. Но, не смотря на простоту этой идеи, хороший реализаций не так много. Если грамотно писать JSDoc к пакету и публиковать его в JSR, то JSR сделает реальную крутую автодоку к пакету.

Что умеет делать JSR с JSdoc:
- Красиво выводит форматирование доки. Можно использовать markdown внутри JSDoc и быть уверенным, что форматирование будет корректно отображено
- Резолвит ссылки на другие сущности внутри пакета
- Объединяет типы TS и jsdoc
- Красиво выводит примеры использования кода
- Автоматически проверяет корректность примеров использования кода

Последняя фича отлично реализована в Rust. Её лучше всего показывать на примере.

Допустим, у вас есть функция sum и вы к ней в JSDoc приводите пример запуска кода и его результат
/**
* Adds two values and returns the sum.
*
* @example
* \`\`\`ts
* import { sum } from "jsr:@deno/sum";
* const finalValue = sum(1, "this is a string"); // 3
* \`\`\`
*/
export function sum(value1: number, value2: number): number {
return value1 + value2;
}


В данном случае в JSDoc ошибка, ведь нельзя прокинуть "this is a string" как число. Deno умеет тестировать доки и найдет ошибку

deno test --doc
Check file:///Users/sum.ts$8-13.ts
error: TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'number'.
const finalValue = sum(1, "this is a string");


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

В статье также описывают бест-практисы по ведению JSDoc в проекте.

https://deno.com/blog/document-javascript-package

#development #javascript #deno #jsr #jsdoc
👍9🔥51
Дайджест за 2024-05-13 - 2024-05-17


Development notes from xkcd's "Machine"
Достаточно знаменитый сайт с узнаваемыми комиксами xkcd в апреле запускал Machine - игру-песочницу, в которой игроку необходимо расставить различные механизмы так, чтобы входящие в поля шарики вылетали в нужном направлении. Наверное, лучше увидеть это глазами прямо в статье, потому что словами описать сложно. При этом песочницы разных игроков склеиваются в огромную безразмерную Machine, в которой шарики циркулируют бесконечно

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

The evolution of Figma’s mobile engine: Compiling away our custom programming language
Статья от команды Figma про то, как они мигрировали с языка Skew на Typescript. Если я правильно понял, Skew - это сайд-проект с ранних дней Figma, цель которого - предоставить язык, который быстро работает и компилируется.


How to document your JavaScript package
Хорошая статья от команды Deno про то, как писать документацию к пакету в виде JSDoc. В рамках данной статьи рассказывается, как пользоваться JSDoc и как JSR использует JSDoc для автоматического создания документации к пакету.

Отдельно замечу, что реализация автодокументации от JSR очень хороша. Идея проста - пишите документацию к коду, а инструмент это все распарсит и опубликует в удобном для людей виде. Но, не смотря на простоту этой идеи, хороший реализаций не так много. Если грамотно писать JSDoc к пакету и публиковать его в JSR, то JSR сделает реальную крутую автодоку к пакету.

——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегамдрузьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂
👍11
ECMAScript proposal: Promise.withResolvers

Недавно в стандарт языка попала фича, которая немного упрощает кейсы, когда нужно создать промис и управлять резолвом промиса снаружи. Новое API: Promise.withResolvers. В статье разбирается основная проблема, из-за которое появилось API, само API, а также приводится несколько примеров использования

В чем суть и что вообще за проблема. Достаточно часто (по крайней мере в моей практике), нужно создать промис, резолвом которого нужно управлять снаружи


const tasks = []
function someTask(id) {
let _resolve;
const promise = new Promise(resolve => { _resolve = resolve})
// Сохраняем в очередь данные и функцию для резолва
tasks.push({resolve:_resolve, id})
// Возвращаем promise
return promise;
}

// setInterval - как показатель, что бизнес-логика где-то в другом месте
// и соответственно резолвить надо тоже в другом месте
setInternval(()=>{
for(let task of tasks) {
// Выполнили всю логики, резолвим
task.resolve(task.id)
}
}, 10000)


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

В целом, чтобы создавать такой промис, можно сделать свою утилку
function getPromiseWithResolvers() {
let _resolve, _reject
const promise = new Promise((res, rej)=>{
_resolve = res;
_reject = rej;
})
return {promise, resolve: _resolve, reject: _reject}
}


И именно это и делает новое API

 const { promise, resolve, reject } = Promise.withResolvers();


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

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

https://2ality.com/2024/05/proposal-promise-with-resolvers.html

#development #javascript #Promise
👍17
Athena Crisis is now Open Source

Пока все носятся с выводом в опен-сорс React компилятора, я показываю вам вывод в опен-сорс игры, написанной на TypeScript. Разработчик игры Athena Crisis решил выложить более 100 000 строк исходников игры в опенсорс. Достаточно редко можно посмотреть на то, как реализованы большие комерческие игровые проекты на веб-технологиях. Это как раз тот случай

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

https://cpojer.net/posts/athena-crisis-open-source

#development #javascript #Promise
👍91
React Google Maps

Вышел релиз 1.0.0 пакета react-google-maps. Честно сказать, не залазил далеко во внутренности, но уверен, что многие из вас используют Google Maps, а тут вышел первый стабильный релиз библиотеки для работы с Google Maps внутри React. Кому-то точно окажется интересным

https://visgl.github.io/react-google-maps/

#development #javascript #react #library #googleMaps
👍14
В эти выходные (25-26 мая) в Новосибирске проходит конференция Codefest, на которой я буду рассказывать про парное программирование. Я расскажу про бест-практисы проведения парного программирования и какие преимущества от этой техники мы наблюдаем конкретно в моей команде. Приходите, развиртуализируемся!

Также по этой причине в ближайшие несколько дней новостей в канале не будет т.к. то время, которое я трачу на чтение дайджестов, я сейчас трачу на подготовку к выступлению. На следующей неделе новости возобновятся
👍24
2025/10/02 19:12:16
Back to Top
HTML Embed Code: