Skip to content

Bun использует протокол WebKit Inspector, поэтому вы можете отлаживать свой код с помощью интерактивного отладчика. Для демонстрации рассмотрим следующий простой веб-сервер.

Отладка JavaScript и TypeScript

typescript
Bun.serve({
  fetch(req) {
    console.log(req.url);
    return new Response("Hello, world!");
  },
});

--inspect

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

sh
bun --inspect server.ts
txt
------------------ Bun Inspector ------------------
Прослушивание:
  ws://localhost:6499/0tqxs9exrgrm

Отладка в браузере:
  https://debug.bun.sh/#localhost:6499/0tqxs9exrgrm
------------------ Bun Inspector ------------------

--inspect-brk

Флаг --inspect-brk ведёт себя идентично --inspect, за исключением того, что он автоматически вставляет точку останова в первой строке выполняемого скрипта. Это полезно для отладки скриптов, которые выполняются быстро и немедленно завершаются.

--inspect-wait

Флаг --inspect-wait ведёт себя идентично --inspect, за исключением того, что код не выполняется до тех пор, пока отладчик не подключится к запущенному процессу.

Установка порта или URL для отладчика

Независимо от того, какой флаг вы используете, вы можете указать номер порта, префикс URL или оба параметра.

sh
bun --inspect=4000 server.ts
bun --inspect=localhost:4000 server.ts
bun --inspect=localhost:4000/prefix server.ts

Отладчики

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

debug.bun.sh

Bun размещает веб-отладчик по адресу debug.bun.sh. Это модифицированная версия Web Inspector Interface от WebKit, которая будет знакома пользователям Safari.

Откройте предоставленный URL debug.bun.sh в вашем браузере, чтобы начать сеанс отладки. Из этого интерфейса вы сможете просматривать исходный код запущенного файла, устанавливать и просматривать точки останова, а также выполнять код с помощью встроенной консоли.

Давайте установим точку останова. Перейдите на вкладку Sources; вы должны увидеть код из предыдущего примера. Нажмите на номер строки 3, чтобы установить точку останова на нашем операторе console.log(req.url).

Затем посетите http://localhost:3000 в вашем веб-браузере. Это отправит HTTP-запрос на наш локальный веб-сервер. Будет казаться, что страница не загружается. Почему? Потому что программа приостановила выполнение в точке останова, которую мы установили ранее.

Обратите внимание, как изменился интерфейс.

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

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

В верхней левой части панели Sources мы можем управлять выполнением программы.

Вот шпаргалка, объясняющая функции кнопок управления потоком.

  • Продолжить выполнение скрипта — продолжить выполнение программы до следующей точки останова или исключения.
  • Step over — программа продолжится до следующей строки.
  • Step into — если текущий оператор содержит вызов функции, отладчик «войдёт» в вызываемую функцию.
  • Step out — если текущий оператор является вызовом функции, отладчик завершит выполнение вызова, затем «выйдет» из функции в место, где она была вызвана.

Отладчик Visual Studio Code

Экспериментальная поддержка отладки скриптов Bun доступна в Visual Studio Code. Для использования вам нужно установить расширение Bun VSCode.


Отладка сетевых запросов

Переменная окружения BUN_CONFIG_VERBOSE_FETCH позволяет автоматически логировать сетевые запросы, сделанные с помощью fetch() или node:http.

ЗначениеОписание
curlПечатать запросы как команды curl.
trueПечатать информацию о запросе и ответе.
falseНичего не печатать. По умолчанию.

Печать запросов fetch и node:http как команды curl

Bun также поддерживает печать сетевых запросов fetch() и node:http как команды curl, установив переменную окружения BUN_CONFIG_VERBOSE_FETCH в curl. Это печатает запрос fetch как однострочную команду curl, чтобы вы могли скопировать и вставить в ваш терминал для воспроизведения запроса.

ts
process.env.BUN_CONFIG_VERBOSE_FETCH = "curl";

await fetch("https://example.com", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ foo: "bar" }),
});
txt
[fetch] $ curl --http1.1 "https://example.com/" -X POST -H "content-type: application/json" -H "Connection: keep-alive" -H "User-Agent: Bun/1.3.3" -H "Accept: */*" -H "Host: example.com" -H "Accept-Encoding: gzip, deflate, br" --compressed -H "Content-Length: 13" --data-raw "{\"foo\":\"bar\"}"
[fetch] > HTTP/1.1 POST https://example.com/
[fetch] > content-type: application/json
[fetch] > Connection: keep-alive
[fetch] > User-Agent: Bun/1.3.3
[fetch] > Accept: */*
[fetch] > Host: example.com
[fetch] > Accept-Encoding: gzip, deflate, br
[fetch] > Content-Length: 13

[fetch] < 200 OK
[fetch] < Accept-Ranges: bytes
[fetch] < Cache-Control: max-age=604800
[fetch] < Content-Type: text/html; charset=UTF-8
[fetch] < Date: Tue, 18 Jun 2024 05:12:07 GMT
[fetch] < Etag: "3147526947"
[fetch] < Expires: Tue, 25 Jun 2024 05:12:07 GMT
[fetch] < Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
[fetch] < Server: EOS (vny/044F)
[fetch] < Content-Length: 1256

Строки с [fetch] > — это запрос из вашего локального кода, а строки с [fetch] < — это ответ от удалённого сервера.

Переменная окружения BUN_CONFIG_VERBOSE_FETCH поддерживается как в запросах fetch(), так и node:http, поэтому она должна работать автоматически.

Чтобы печатать без команды curl, установите BUN_CONFIG_VERBOSE_FETCH в true.

ts
process.env.BUN_CONFIG_VERBOSE_FETCH = "true";

await fetch("https://example.com", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ foo: "bar" }),
});
txt
[fetch] > HTTP/1.1 POST https://example.com/
[fetch] > content-type: application/json
[fetch] > Connection: keep-alive
[fetch] > User-Agent: Bun/1.3.3
[fetch] > Accept: */*
[fetch] > Host: example.com
[fetch] > Accept-Encoding: gzip, deflate, br
[fetch] > Content-Length: 13

[fetch] < 200 OK
[fetch] < Accept-Ranges: bytes
[fetch] < Cache-Control: max-age=604800
[fetch] < Content-Type: text/html; charset=UTF-8
[fetch] < Date: Tue, 18 Jun 2024 05:12:07 GMT
[fetch] < Etag: "3147526947"
[fetch] < Expires: Tue, 25 Jun 2024 05:12:07 GMT
[fetch] < Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
[fetch] < Server: EOS (vny/044F)
[fetch] < Content-Length: 1256

Трассировки стека и карты источников

Bun транслирует каждый файл, что звучит так, как будто трассировки стека, которые вы видите в консоли, будут бесполезно указывать на транслированный вывод. Чтобы решить эту проблему, Bun автоматически генерирует и обслуживает файлы с картами источников для каждого файла, который он транслирует. Когда вы видите трассировку стека в консоли, вы можете нажать на путь к файлу и перейти к исходному исходному коду, даже если он был написан на TypeScript или JSX, или имеет какое-либо другое преобразование.

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

Предварительный просмотр исходного кода с подсветкой синтаксиса

Для помощи в отладке Bun автоматически печатает небольшой предварительный просмотр исходного кода, когда происходит необработанное исключение или отклонение. Вы можете симулировать это поведение, вызвав Bun.inspect(error):

ts
// Создать ошибку
const err = new Error("Something went wrong");
console.log(Bun.inspect(err, { colors: true }));

Это печатает предварительный просмотр исходного кода с подсветкой синтаксиса, где произошла ошибка, вместе с сообщением об ошибке и трассировкой стека.

ts
1 | // Create an error
2 | const err = new Error("Something went wrong");
                ^
error: Something went wrong
      at file.js:2:13

Трассировки стека V8

Bun использует JavaScriptCore в качестве своего движка, но большая часть экосистемы Node.js и npm ожидает V8. Движки JavaScript различаются в форматировании error.stack. Bun намерен быть прямой заменой для Node.js, и это означает, что это наша работа — убедиться, что хотя движок другой, трассировки стека максимально похожи.

Вот почему, когда вы логируете error.stack в Bun, форматирование error.stack такое же, как в движке V8 Node.js. Это особенно полезно, когда вы используете библиотеки, которые ожидают трассировки стека V8.

API трассировок стека V8

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

Error.prepareStackTrace

Функция Error.prepareStackTrace — это глобальная функция, которая позволяет настраивать вывод трассировки стека. Эта функция вызывается с объектом ошибки и массивом объектов CallSite и позволяет вернуть пользовательскую трассировку стека.

ts
Error.prepareStackTrace = (err, stack) => {
  return stack.map(callSite => {
    return callSite.getFileName();
  });
};

const err = new Error("Something went wrong");
console.log(err.stack);
// [ "error.js" ]

Объект CallSite имеет следующие методы:

МетодВозвращает
getThisЗначение this вызова функции
getTypeNametypeof this
getFunctionОбъект функции
getFunctionNameИмя функции как строка
getMethodNameИмя метода как строка
getFileNameИмя файла или URL
getLineNumberНомер строки
getColumnNumberНомер столбца
getEvalOriginundefined
getScriptNameOrSourceURLURL источника
isToplevelВозвращает true, если функция в глобальной области
isEvalВозвращает true, если функция — вызов eval
isNativeВозвращает true, если функция нативная
isConstructorВозвращает true, если функция — конструктор
isAsyncВозвращает true, если функция async
isPromiseAllЕщё не реализовано.
getPromiseIndexЕщё не реализовано.
toStringВозвращает строковое представления сайта вызова

В некоторых случаях объект Function мог уже быть собран сборщиком мусора, поэтому некоторые из этих методов могут возвращать undefined.

Error.captureStackTrace(error, startFn)

Функция Error.captureStackTrace позволяет захватить трассировку стека в определённой точке вашего кода, а не в точке, где была брошена ошибка.

Это может быть полезно, когда у вас есть обратные вызовы или асинхронный код, который затрудняет определение происхождения ошибки. Второй аргумент Error.captureStackTrace — это функция, с которой вы хотите начать трассировку стека.

Например, следующий код заставит err.stack указывать на код, вызывающий fn(), хотя ошибка была брошена в myInner.

ts
const fn = () => {
  function myInner() {
    throw err;
  }

  try {
    myInner();
  } catch (err) {
    console.log(err.stack);
    console.log("");
    console.log("-- captureStackTrace --");
    console.log("");
    Error.captureStackTrace(err, fn);
    console.log(err.stack);
  }
};

fn();
txt
Error: here!
    at myInner (file.js:4:15)
    at fn (file.js:8:5)
    at module code (file.js:17:1)
    at moduleEvaluation (native)
    at moduleEvaluation (native)
    at <anonymous> (native)

-- captureStackTrace --

Error: here!
    at module code (file.js:17:1)
    at moduleEvaluation (native)
    at moduleEvaluation (native)
    at <anonymous> (native)

Bun от www.bunjs.com.cn