Telegram Web Link
А оказывается, Node.js 24 поддерживает синтаксис using

Что позволяет сделать даже логи проще и приятнее.

Когда mainGroup выйдет из скоупа (функция, if, for или {}), автоматически будет вызвана функция [Symbol.dispose]

Хоть изначально предназначено для очистки ресурсов, но здесь хорошо работает

https://github.com/tc39/proposal-explicit-resource-management
Плавный переезд Vite на Rolldown

https://voidzero.dev/posts/announcing-rolldown-vite

Ещё один инструмент фронтендеров уходит с JavaScript runtime на Rust.
С одной стороны это обосновано, там какие-то нереальные цифры профита по производительности и по памяти, а с другой уходят не полностью.

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

Меня радует, что авторы обещают отсутствие мажорных отличий. Конечно, для популярных плагинов/фреймворков этот переезд не критичен — баги быстро пофиксят, а критичные места можно покрыть через if(vite.rolldownVersion)

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

Благо это крайне легко:

{
"pnpm": {
"overrides": {
"vite": "npm:rolldown-vite@latest"
}
}
}
Ecma International approves ECMAScript 2025: What’s new?

25 июня зафиксировали стандарт ECMAScript 2025.

Что зафиксировали: импорт-атрибуты (нужны для JSON-модулей), хелперы для итераторов, новые методы Set, немного улучшили RegExp, добавили Promise.try и поддержки 16-битных чисел с плавающей точкой

Import attributes
Добавили в язык возможность импортировать не JS код. Для этого понадобилось добавлять синтаксис, который бы объяснял движку или рантайму, что сейчас будет импорчено
import configData1 from './config-data.json' with { type: 'json' };

// Dynamic import
const configData2 = await import(
'./config-data.json', { with: { type: 'json' } }
);


Хелперы для итераторов
Для массивов есть удобные методы, а для итераторов - нет. Решили исправить эту несправедливость и перенесли часть методов на итераторы
const arr = ['a', '', 'b', '', 'c', '', 'd', '', 'e'];
assert.deepEqual(
arr.values() // creates an iterator
.filter(x => x.length > 0)
.drop(1)
.take(3)
.map(x => `=${x}=`)
.toArray()
,
['=b=', '=c=', '=d=']
);


Адаптированные для итератора методы
- iterator.filter(filterFn)
- iterator.map(mapFn)
- iterator.flatMap(mapFn)
- iterator.some(fn)
- iterator.every(fn)
- iterator.find(fn)
- iterator.reduce(reducer, initialValue?)
- iterator.forEach(fn)

Также сделали аналоги slice
- iterator.drop(limit) возвращает новый итератор без первых limit значений (по сути slice(limit))
- iterator.take(limit) возвращает новый итератор с первыми limit значениями (по сути slice(0, limit))

Еще сделали удобный метод для преобразования итератора в массив iterator.toArray()

Новые методы Set
- Создание нового сета из двух существующих:
- Set.prototype.intersection(other) - пересечение - только те значения, которые есть в обоих наборах
- Set.prototype.union(other) - объединение - значение из обоих наборов
- Set.prototype.difference(other) - позволяет достать множество, которое получится если из множества А убрать все элементы множества Б
- Set.prototype.symmetricDifference(other) - позволяет достать множество, которое содержит элементы которые входят только в одно из множеств
- Определение отношения наборов:
- Set.prototype.isSubsetOf(other) - является ли набор А - подмножеством набора Б
- Set.prototype.isSupersetOf(other) является ли набор А - надмножеством набора Б
- Set.prototype.isDisjointFrom(other) - возвращает true, если у множеств нет пересечений

assert.deepEqual(
new Set(['a', 'b', 'c']).union(new Set(['b', 'c', 'd'])),
new Set(['a', 'b', 'c', 'd'])
);
assert.deepEqual(
new Set(['a', 'b', 'c']).intersection(new Set(['b', 'c', 'd'])),
new Set(['b', 'c'])
);
assert.deepEqual(
new Set(['a', 'b']).isSubsetOf(new Set(['a', 'b', 'c'])),
true
);
assert.deepEqual(
new Set(['a', 'b', 'c']).isSupersetOf(new Set(['a', 'b'])),
true
);



Улучшения RegExp
RegExp.escape(text) позволяет вставить текст в RegExp и быть уверенным, что вставленный текст не сломает RegExp

 const regExp = new RegExp(
`(?<!“)${RegExp.escape(text)}(?!”)`,
'gu'
);


Флаги теперь можно применять не ко всему RegExp, а к отдельным группам
 /^x(?i:HELLO)x$/.test('xHELLOx') // true


Можно использовать одинаковые имена для групп
const RE = /(?<chars>a+)|(?<chars>b+)/v;


Promise.try
Promise.try немного упрощает создание промиса с синхронными функциями
 return Promise.try(() => {
const value = syncFuncMightThrow();
return asyncFunc(value);
});


Если функция syncFuncMightThrow бросит исключение, то Promise.try вернет реджектнутый промис.

Работа с 16-битными числами
По дефолту числа в JS представлены 64-битными числами с плавающей точкой. Но есть кейсы, когда необходимо вести все вычисления в 16 или 32-битных числах. В JS добавили разные хелперы для работы с такими числами, например Math.f16round делает округление в пространстве 16-битных чисел

console.log(Math.f16round(2**16)) // Infinity

console.log(2**16) // 65536


https://2ality.com/2025/06/ecmascript-2025.html

#development #javascript #ecmascript #releaseNotes
Please open Telegram to view this post
VIEW IN TELEGRAM
По какому поводу стоит писать в личку:

1. любые вопросы про frontend.vision
2. запросить разъяснения интересующей темы (это будет пост в канале)
3. попросить консультацию
4. что-то рандомное, не являющееся рекламой и не входящее в категории выше
2025/07/04 15:45:47
Back to Top
HTML Embed Code: