Bun использует протокол WebKit Inspector, поэтому вы можете отлаживать свой код с помощью интерактивного отладчика. Для демонстрации рассмотрим следующий простой веб-сервер.
Отладка JavaScript и TypeScript
Bun.serve({
fetch(req) {
console.log(req.url);
return new Response("Hello, world!");
},
});--inspect
Чтобы включить отладку при запуске кода с помощью Bun, используйте флаг --inspect. Это автоматически запускает WebSocket-сервер на доступном порту, который можно использовать для интроспекции запущенного процесса Bun.
bun --inspect server.ts------------------ 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 или оба параметра.
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, чтобы вы могли скопировать и вставить в ваш терминал для воспроизведения запроса.
process.env.BUN_CONFIG_VERBOSE_FETCH = "curl";
await fetch("https://example.com", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ foo: "bar" }),
});[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.
process.env.BUN_CONFIG_VERBOSE_FETCH = "true";
await fetch("https://example.com", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ 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Трассировки стека и карты источников
Bun транслирует каждый файл, что звучит так, как будто трассировки стека, которые вы видите в консоли, будут бесполезно указывать на транслированный вывод. Чтобы решить эту проблему, Bun автоматически генерирует и обслуживает файлы с картами источников для каждого файла, который он транслирует. Когда вы видите трассировку стека в консоли, вы можете нажать на путь к файлу и перейти к исходному исходному коду, даже если он был написан на TypeScript или JSX, или имеет какое-либо другое преобразование.
Bun автоматически загружает карты источников как во время выполнения при трансляции файлов по требованию, так и при использовании bun build для предварительной компиляции файлов заранее.
Предварительный просмотр исходного кода с подсветкой синтаксиса
Для помощи в отладке Bun автоматически печатает небольшой предварительный просмотр исходного кода, когда происходит необработанное исключение или отклонение. Вы можете симулировать это поведение, вызвав Bun.inspect(error):
// Создать ошибку
const err = new Error("Something went wrong");
console.log(Bun.inspect(err, { colors: true }));Это печатает предварительный просмотр исходного кода с подсветкой синтаксиса, где произошла ошибка, вместе с сообщением об ошибке и трассировкой стека.
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 и позволяет вернуть пользовательскую трассировку стека.
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 вызова функции |
getTypeName | typeof this |
getFunction | Объект функции |
getFunctionName | Имя функции как строка |
getMethodName | Имя метода как строка |
getFileName | Имя файла или URL |
getLineNumber | Номер строки |
getColumnNumber | Номер столбца |
getEvalOrigin | undefined |
getScriptNameOrSourceURL | URL источника |
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.
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();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)