Найти в Дзене
Chris Roylance

Состоялся релиз Bun 1.3.6

Данный релиз интересен тем, что добавляет много новых возможностей, а также неплохую оптимизацию по многим направлениям. В Bun теперь встроен API Bun.Archive для создания и извлечения tar-архивов с опциональным сжатием gzip. Это обеспечивает быстрый и независимый способ работы с tar-архивами непосредственно в JavaScript. Вы можете записывать архивы в локальные файлы: Или даже в S3: API поддерживает создание архивов из объектов, Blob, TypedArray или ArrayBuffer. Асинхронные операции выполняются в потоках пула рабочих потоков Bun для обеспечения неблокирующего ввода-вывода. Подробнее о Bun.Archive можно прочитать в документации Bun. Теперь Bun предоставляет встроенный API Bun.JSONC.parse() для анализа JSONC (JSON с комментариями) — формата, используемого файлом tsconfig.json, настройками VS Code и многими другими конфигурационными файлами. Это позволяет анализировать JSON, содержащий: Это полезно при чтении файлов tsconfig.json, конфигурационных файлов VS Code или любых JSON-файлов, испо
Оглавление

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

API Bun.Archive создает и извлекает архивы tar

В Bun теперь встроен API Bun.Archive для создания и извлечения tar-архивов с опциональным сжатием gzip. Это обеспечивает быстрый и независимый способ работы с tar-архивами непосредственно в JavaScript.

-2

Вы можете записывать архивы в локальные файлы:

-3

Или даже в S3:

-4

API поддерживает создание архивов из объектов, Blob, TypedArray или ArrayBuffer. Асинхронные операции выполняются в потоках пула рабочих потоков Bun для обеспечения неблокирующего ввода-вывода.

Подробнее о Bun.Archive можно прочитать в документации Bun.

API Bun.JSONC для анализа JSON с комментариями

Теперь Bun предоставляет встроенный API Bun.JSONC.parse() для анализа JSONC (JSON с комментариями) — формата, используемого файлом tsconfig.json, настройками VS Code и многими другими конфигурационными файлами.

Это позволяет анализировать JSON, содержащий:

  • Однострочные комментарии (//)
  • Блочные комментарии (/* */)
  • Заключительные запятые в объектах и ​​массивах
-5

Это полезно при чтении файлов tsconfig.json, конфигурационных файлов VS Code или любых JSON-файлов, использующих упрощенный формат JSONC, — без необходимости использования сторонних библиотек.

Параметр metafile в Bun.build

Функция Bun.build() теперь поддерживает опцию metafile, соответствующую формату esbuild, что обеспечивает бесшовную совместимость с существующими инструментами анализа пакетов.

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

-6

cli исполнение:

bun build ./src/index.ts --outdir ./dist --metafile ./dist/meta.json

Структура метафайла включает в себя:

входные данные: Карта исходных файлов с указанием размеров в байтах, импортов (с указанием типа, пути и типа (внешний)) и формата модуля

выходные данные: Карта выходных фрагментов с указанием размеров в байтах, входящих входных данных, импортов, экспортов, точек входа и связанных пакетов CSS

Подробнее см. в документации Bun.

Параметр files в Bun.build

Bun.build теперь поддерживает опцию files, которая позволяет включать в сборку виртуальные файлы, отсутствующие на диске, или перезаписывать содержимое существующих файлов.

-7

Файлы, находящиеся в оперативной памяти, имеют приоритет над файлами на диске, поэтому вы можете переопределять определенные файлы, сохраняя при этом остальную часть вашего кода без изменений:

-8

Реальные файлы на диске могут импортировать виртуальные файлы, а виртуальные файлы могут импортировать реальные файлы — это полезно для генерации кода, внедрения констант времени сборки или тестирования с помощью фиктивных модулей:

-9

Содержимое файла может быть предоставлено в виде строки, Blob, TypedArray или ArrayBuffer.

Подробнее см. в документации Bun.

CLI параметр --compile-executable-path

При кросс-компиляции исполняемых файлов в одном файле с помощью команды `bun build --compile` Bun обычно загружает исполняемый файл Bun для целевой платформы из npm. Новый флаг `--compile-executable-path` позволяет вместо этого указать локальный исполняемый файл Bun.

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

bun build --compile --target=bun-linux-x64 --compile-executable-path=/path/to/bun-linux-x64 app.ts

Это позволяет использовать параметр executablePath, который уже был доступен в JavaScript API:

-10

Параметр reactFastRefresh в Bun.build

Теперь API Bun.build поддерживает опцию reactFastRefresh, аналогичную существующему флагу командной строки --react-fast-refresh.

-11

При включении этой функции сборщик внедряет код преобразования React Fast Refresh ($RefreshReg$, $RefreshSig$) в выходные данные. Это позволяет осуществлять горячую замену модулей для компонентов React без необходимости использования отдельного плагина.

Метод Response.json(object) теперь работает в 3,5 раза быстрее

Вызов метода Response.json() был значительно медленнее, чем ручной вызов JSON.stringify() + new Response(). Эта проблема была решена путем запуска оптимизированного для SIMD пути выполнения FastStringifier из JavaScriptCore.

-12

Было:

Response.json(): 2415ms

JSON.stringify() + Response(): 689ms

Ratio: 3.50x slower

Стало:

Response.json(): ~700ms

JSON.stringify() + Response(): ~700ms

Ratio: ~1.0x (parity)

Производительность

В рамках данного обнволения async/await стал на 15% быстрее. Promise.race в свою очередь, стал производительнее на 30%.

Загрузка больших встроенных дополнений .node napi в Linux осуществляется немного быстрее с помощью исполняемых файлов, состоящих из одного файла.

Ускоренная межпроцессная обработка. В 9 раз более быстрая межпроцессная обработка JSON с большими сообщениями.

Производительность в Buffer.indexOf

Функции Buffer.indexOf и Buffer.include теперь используют оптимизированные для SIMD поисковые функции, что значительно ускоряет поиск шаблонов в больших буферах.

В простом тесте производительности это делает процесс до 2 раз быстрее:

-13

❯ bun bench/snippets/buffer-includes.js

Run 99,999 times with a warmup:

[21.90ms] 44,500 bytes .includes true

[1.42s] 44,500 bytes .includes false

❯ bun-1.3.5 bench/snippets/buffer-includes.js

Run 99,999 times with a warmup:

[25.52ms] 44,500 bytes .includes true

[3.25s] 44,500 bytes .includes false

Более быстрая работа Bun.spawnSync() в Linux ARM64

Исправлена ​​ошибка производительности, из-за которой Bun.spawnSync() работал до 30 раз медленнее, чем ожидалось, в системах Linux с высокими ограничениями на количество файловых дескрипторов.

Проблема возникала из-за того, что номер системного вызова close_range() не определялся во время компиляции в более старых версиях glibc, в результате чего Bun переключался на перебор всех возможных файловых дескрипторов (до 65 000) по отдельности:

-14

Флаг --grep для bun test

Теперь bun test поддерживает --grep в качестве псевдонима для --test-name-pattern, что соответствует знакомому флагу, используемому Jest, Mocha и другими средствами запуска тестов.

-15

Ускоренная сериализация JSON в API Bun

Сериализация JSON теперь примерно в 3 раза быстрее для нескольких внутренних API благодаря использованию оптимизированного для SIMD пути выполнения FastStringifier в JSC:

console.log с форматом %j — более быстрый вывод отладочной информации

Типы JSON/JSONB для PostgreSQL — более быстрые операции с базой данных

Тип JSON для MySQL — более быстрые операции с базой данных

Спецификаторы формата Jest %j/%o — более быстрый вывод результатов тестирования

Теперь фиктивные таймеры работают с @testing-library/react

Функция jest.useFakeTimers() теперь корректно работает с @testing-library/react и @testing-library/user-event, исправляя ошибку, из-за которой тесты зависали на неопределенное время при использовании user.click() или аналогичных взаимодействий.

Были решены две проблемы:

  • Обнаружение фиктивных таймеров — Bun теперь устанавливает setTimeout.clock = true, когда включены фиктивные таймеры, что проверяется @testing-library/react для определения необходимости вызова jest.advanceTimersByTime() при очистке очереди микрозадач.
  • Обработка немедленных таймеров — advanceTimersByTime(0) теперь корректно запускает коллбэки setTimeout(fn, 0). Согласно спецификации HTML, setTimeout(fn, 0) внутренне планируется с задержкой в ​​1 мс, но Jest и testing-library ожидают, что advanceTimersByTime(0) запустит эти «немедленные» таймеры.
-16

Вспомогательная функция sql() для INSERT теперь учитывает значения undefined

Вспомогательная функция шаблона с тегом sql() теперь отфильтровывает значения undefined в операторах INSERT вместо преобразования их в NULL. Это позволяет столбцам со значениями DEFAULT правильно использовать значения по умолчанию из базы данных при передаче undefined, а не переопределяться значением NULL.

-17

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

-18

Bun.hash.crc32 теперь работает в 20 раз быстрее

Теперь Bun.hash.crc32 использует аппаратное ускорение инструкций CRC32 через zlib, что делает его примерно в 20 раз быстрее на типичных рабочих нагрузках.

Предыдущая реализация использовала только программный алгоритм, который не задействовал современные инструкции ЦП, такие как PCLMULQDQ на x86 или собственные инструкции CRC32 на ARM.

Заказчик S3 оплачивает поддержку

Теперь S3-клиент Bun поддерживает корзины с оплатой за передачу данных (Requester Pays), что позволяет получать доступ к публичным корзинам S3, где плата за передачу данных взимается с запрашивающего лица, а не с владельца корзины.

Установите requestPayer: true при доступе к объектам в корзинах с оплатой за передачу данных:

-19

Эта опция работает со всеми операциями S3, включая чтение, запись, получение статистики и многокомпонентную загрузку.

Поддержка HTTP/HTTPS-прокси для WebSocket

В конструкторе Bun для работы с WebSocket теперь поддерживается подключение через HTTP и HTTPS-прокси с помощью новой опции proxy. Это позволяет устанавливать WebSocket-соединения в корпоративных средах и других сценариях, где прямое подключение невозможно.

-20

Поддерживаются все комбинации соединений ws:// и wss:// через HTTP и HTTPS прокси, а также базовая аутентификация и пользовательские заголовки прокси. Опция TLS теперь также поддерживает полную конфигурацию TLS (CA, сертификат, ключ, парольная фраза и т. д.), аналогичную опциям, доступным в fetch.

Обновлена ​​версия SQLite до 3.51.2

Встроенная база данных SQLite от Bun (bun:sqlite) обновлена ​​с версии 3.51.1 до 3.51.2. Это обновление включает исправления для граничных случаев с предложениями DISTINCT и OFFSET, улучшенное поведение блокировки в режиме WAL и перенумерацию курсоров.

Внесенные исправления

Улучшения совместимости с Node.js

Исправлено: обработчик события CONNECT сервера node:http не получал данные конвейера в параметре head, если они отправлялись в том же сегменте TCP, что и заголовки запроса, что вызывало проблемы совместимости с библиотекой KJ HTTP от Cap'n Proto, используемой средой выполнения workerd Cloudflare.

Исправлено: разрешение временного каталога теперь корректно проверяет переменные среды TMPDIR, TMP и TEMP по порядку, что соответствует поведению os.tmpdir() в Node.js.

Исправлено: утечка памяти в потоках сжатия Brotli, Zstd и Zlib в node:zlib, где многократный вызов reset() выделял новые состояния кодировщика/декодера без освобождения предыдущих.

Исправлено: модуль ws теперь корректно поддерживает опцию agent для прокси-соединений.

Улучшено: управление потоком в модуле node:http2.

API Bun

  • Исправлено: Исправлена ​​редкая крайняя ситуация при очистке стандартного ввода в подпроцессе
  • Исправлено: Зависание HTTP-запросов клиента при одновременной аутентификации нескольких запросов через прокси (код состояния 407) без прямого прохождения через прокси
  • Исправлено: Потенциальное повреждение данных в Bun.write() для файлов размером более 2 ГБ
  • Исправлено: Ошибка синтаксического анализа с переменной среды NO_PROXY, включающая пустые записи
  • Исправлено: Потенциальная утечка памяти при проксировании потоковых ответов через Bun.serve() с использованием ReadableStream
  • Исправлено: Редкий сбой в Bun Shell, влияющий на открытый код
  • Исправлено: Гипотетический сбой, вызванный асинхронными операциями сжатия zstd, scrypt и транспиляции, когда буферы могли быть удалены сборщиком мусора, оставаясь при этом доступными для рабочих потоков
  • Исправлено: Ошибка EBADF при использовании перенаправления &> со встроенными командами Bun Shell
  • Исправлено: Драйвер Bun SQL MySQL теперь корректно возвращает Buffer для столбцов BINARY, VARBINARY и BLOB вместо поврежденных строк UTF-8, что соответствует Поведение драйверов PostgreSQL и SQLite.
  • Исправлено: драйвер Bun SQL Postgres некорректно выдавал ошибки InvalidByteSequence при разборе массивов, содержащих строки или JSON размером более 16 КБ.
  • Исправлено: драйвер Bun SQL Postgres не мог прочитать пустые массивы PostgreSQL (например, INTEGER[] хранящиеся как {}) с ошибкой ERR_POSTGRES_INVALID_BINARY_DATA, особенно при повторном использовании подключений к базе данных.
  • Исправлено: ошибки разбора JSON из столбцов базы данных SQL (например, PostgreSQL JSON/JSONB) теперь корректно выдают исключения SyntaxError вместо молчаливого возврата пустых значений.
  • Исправлено: проверка учетных данных S3 теперь корректно отклоняет недопустимые значения pageSize, partSize и retry, выходящие за пределы допустимых диапазонов.
  • Исправлено: Bun.write() теперь корректно учитывает параметр mode при копировании файлов из Bun.file(), вместо молчаливого наследования разрешений от исходного файла.
  • Улучшено: Bun теперь отклоняет нулевые байты в аргументах, передаваемых в Bun.spawn, Bun.spawnSync, переменные окружения и литералы шаблонов оболочки. Это предотвращает атаки с внедрением нулевого байта (CWE-158).
  • Улучшено: Bun теперь обеспечивает более строгое сопоставление сертификатов с использованием подстановочных знаков в соответствии с разделом 6.4.3 RFC 6125 для повышения безопасности.

Веб-API

  • Исправлено: URLSearchParams.prototype.size не был настраиваемым параметром, что не соответствовало спецификации Web IDL.
  • Исправлено: клиент WebSocket теперь отклоняет атаки типа «бомба декомпрессии», устанавливая ограничение в 128 МБ на размер декомпрессированного сообщения, что предотвращает потенциальные атаки исчерпания памяти.
  • Исправлено: Крайний случай в функции fetch() с телом ReadableStream, когда потоки в редких случаях некорректно освобождались после завершения запроса, что приводило к утечке памяти.

bun install

  • Исправлено: Ошибки проверки границ с отклонением на единицу в сборщике и установщике пакетов, которые могли вызывать неопределенное поведение, когда индексы массива равны длине массива.
  • Исправлено: Чтение параметра ca в .npmrc для пользовательских центров сертификации.
  • Исправлено: Редкий сбой при выполнении bun install при повторной попытке выполнения неудачных HTTP-запросов (например, когда API GitHub возвращает ошибки 504).
  • Исправлено: bun --filter '*' не учитывает порядок зависимостей, когда имя пакета длиннее 8 символов, что приводит к параллельному выполнению сборок вместо последовательного выполнения на основе зависимостей рабочей области.
  • Исправлено: Уязвимость обхода пути через символическую ссылку при извлечении архива. Теперь Bun отклоняет абсолютные цели символических ссылок (пути, начинающиеся с /) и относительные символические ссылки, которые выходят за пределы каталога извлечения через ../.

Минификатор JavaScript

Исправлено: Удаление мертвого кода приводило к появлению недопустимого синтаксиса, например, { ...a, x: }, при упрощении пустых объектов в контекстах расширения, что вызывало ошибки сборки в некоторых проектах Next.js 16 (Turbopack).

Сборщик JavaScript

  • Исправлено: команда `bun build --compile` с 8+ встроенными файлами работает как ожидалось
  • Исправлено: конфигурация CLI отладчика теперь корректно распространяется на исполняемые файлы в одном файле
  • Исправлено: скомпилированные байт-кодом пакеты CJS молча не выполнялись, если исходный файл содержал shebang (#!/usr/bin/env bun)
  • Улучшено: внутренняя структура данных в сборщике путем упаковки логических флагов и переупорядочивания полей для минимизации заполнения структуры. Это снижает накладные расходы на память при сборке больших пакетов примерно на 200 КБ–1,5 МБ.

CSS-парсер

Исправлено: Логические свойства CSS (например, inset-inline-end) удалялись из вывода сборщика, когда вложенные правила, такие как псевдоэлементы (&:after, &:before), присутствовали в одном блоке.

Типы TypeScript

  • Исправлено: Отсутствующие типы TypeScript для параметров autoloadTsconfig и autoloadPackageJson в конфигурации автономной компиляции Bun.build().
  • Исправлено: Некорректные типы TypeScript и документация для метода bun:sqlite .run() теперь корректно показывают, что он возвращает объект Changes со свойствами changes и lastInsertRowid, а не undefined или экземпляр Database.
  • Исправлено: Тип возвращаемого значения FileSink.write() теперь корректно включает Promise<number> для асинхронной записи, когда запись находится в ожидании.

Windows

  • Предполагаемое исправление: сбой на машинах Windows при запуске, когда доступно очень мало памяти
  • Исправлено: ошибка «целое число не помещается в целевой тип» при чтении файлов, измененных другим процессом или на сетевых дисках, где libuv возвращает не отображенные коды ошибок, такие как UV_UNKNOWN

bun create

Исправлено: сбой в bun create при использовании --no-install с шаблоном, у которого задача bun-create.postinstall начинается с "bun"