Skip to content

Bun spricht das WebKit Inspector Protocol, sodass Sie Ihren Code mit einem interaktiven Debugger debuggen können. Zu Demonstrationszwecken betrachten Sie den folgenden einfachen Webserver.

JavaScript und TypeScript debuggen

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

--inspect

Um das Debuggen bei der Ausführung von Code mit Bun zu aktivieren, verwenden Sie das --inspect-Flag. Dies startet automatisch einen WebSocket-Server an einem verfügbaren Port, der zur Introspektion des laufenden Bun-Prozesses verwendet werden kann.

sh
bun --inspect server.ts
txt
------------------ Bun Inspector ------------------
Lauscht auf:
  ws://localhost:6499/0tqxs9exrgrm

Im Browser inspizieren:
  https://debug.bun.sh/#localhost:6499/0tqxs9exrgrm
------------------ Bun Inspector ------------------

--inspect-brk

Das --inspect-brk-Flag verhält sich identisch zu --inspect, außer dass es automatisch einen Haltepunkt in der ersten Zeile des ausgeführten Skripts einfügt. Dies ist nützlich zum Debuggen von Skripten, die schnell ausgeführt werden und sofort beendet werden.

--inspect-wait

Das --inspect-wait-Flag verhält sich identisch zu --inspect, außer dass der Code nicht ausgeführt wird, bis ein Debugger an den laufenden Prozess angehängt wurde.

Einen Port oder eine URL für den Debugger festlegen

Unabhängig davon, welches Flag Sie verwenden, können Sie optional eine Portnummer, ein URL-Präfix oder beides angeben.

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

Debugger

Verschiedene Debugging-Tools können sich mit diesem Server verbinden, um eine interaktive Debugging-Erfahrung zu bieten.

debug.bun.sh

Bun hostet einen webbasierten Debugger unter debug.bun.sh. Es ist eine modifizierte Version von WebKits Web Inspector Interface, die Safari-Benutzern bekannt vorkommen wird.

Öffnen Sie die bereitgestellte debug.bun.sh-URL in Ihrem Browser, um eine Debugging-Sitzung zu starten. Von dieser Oberfläche aus können Sie den Quellcode der laufenden Datei anzeigen, Haltepunkte anzeigen und setzen sowie Code mit der integrierten Konsole ausführen.

Lassen Sie uns einen Haltepunkt setzen. Navigieren Sie zum Sources-Tab; Sie sollten den Code von früher sehen. Klicken Sie auf die Zeilennummer 3, um einen Haltepunkt auf unserer console.log(req.url)-Anweisung zu setzen.

Besuchen Sie dann http://localhost:3000 in Ihrem Webbrowser. Dies sendet eine HTTP-Anfrage an unseren localhost-Webserver. Es scheint, als würde die Seite nicht laden. Warum? Weil das Programm die Ausführung an dem Haltepunkt angehalten hat, den wir zuvor gesetzt haben.

Beachten Sie, wie sich die Benutzeroberfläche geändert hat.

An diesem Punkt können wir viel tun, um die aktuelle Ausführungsumgebung zu introspektieren. Wir können die Konsole unten verwenden, um beliebigen Code im Kontext des Programms auszuführen, mit vollem Zugriff auf die Variablen, die im Bereich unseres Haltepunkts sichtbar sind.

Auf der rechten Seite des Sources-Bereichs können wir alle lokalen Variablen sehen, die derzeit im Bereich sind, und uns durchklicken, um ihre Eigenschaften und Methoden zu sehen. Hier inspizieren wir die req-Variable.

Im oberen linken Bereich des Sources-Bereichs können wir die Ausführung des Programms steuern.

Hier ist eine Spickzettel, der die Funktionen der Steuerfluss-Schaltflächen erklärt.

  • Skriptausführung fortsetzen — setzt die Ausführung des Programms bis zum nächsten Haltepunkt oder einer Ausnahme fort.
  • Schritt über — Das Programm fährt mit der nächsten Zeile fort.
  • Schritt in — Wenn die aktuelle Anweisung einen Funktionsaufruf enthält, "tritt" der Debugger in die aufgerufene Funktion ein.
  • Schritt aus — Wenn die aktuelle Anweisung ein Funktionsaufruf ist, beendet der Debugger die Ausführung des Aufrufs und "tritt aus" der Funktion an die Stelle, an der sie aufgerufen wurde.

Visual Studio Code Debugger

Experimentelle Unterstützung für das Debuggen von Bun-Skripten ist in Visual Studio Code verfügbar. Um es zu verwenden, müssen Sie die Bun VSCode-Erweiterung installieren.


Netzwerkanfragen debuggen

Die Umgebungsvariable BUN_CONFIG_VERBOSE_FETCH ermöglicht es Ihnen, Netzwerkanfragen, die mit fetch() oder node:http gestellt werden, automatisch zu protokollieren.

WertBeschreibung
curlGibt Anfragen als curl-Befehle aus.
trueGibt Anfrage- und Antwortinformationen aus
falseGibt nichts aus. Standardwert

fetch- und node:http-Anfragen als curl-Befehle ausgeben

Bun unterstützt auch die Ausgabe von fetch()- und node:http-Netzwerkanfragen als curl-Befehle, indem die Umgebungsvariable BUN_CONFIG_VERBOSE_FETCH auf curl gesetzt wird. Dies gibt die fetch-Anfrage als einzeiligen curl-Befehl aus, sodass Sie ihn in Ihr Terminal kopieren können, um die Anfrage zu replizieren.

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

Die Zeilen mit [fetch] > sind die Anfrage von Ihrem lokalen Code, und die Zeilen mit [fetch] < sind die Antwort vom Remote-Server.

Die Umgebungsvariable BUN_CONFIG_VERBOSE_FETCH wird sowohl in fetch()- als auch in node:http-Anfragen unterstützt, sodass sie einfach funktionieren sollte.

Um ohne den curl-Befehl auszugeben, setzen Sie BUN_CONFIG_VERBOSE_FETCH auf 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

Stacktraces und Sourcemaps

Bun transpiliert jede Datei, was so klingt, als würden die Stacktraces, die Sie in der Konsole sehen, unnötigerweise auf die transpilierte Ausgabe verweisen. Um dies zu adressieren, generiert und stellt Bun automatisch sourcemapped Dateien für jede Datei bereit, die es transpiliert. Wenn Sie einen Stacktrace in der Konsole sehen, können Sie auf den Dateipfad klicken und zum ursprünglichen Quellcode gebracht werden, auch wenn er in TypeScript oder JSX geschrieben wurde oder eine andere Transformation angewendet wurde.

Bun lädt Sourcemaps automatisch sowohl zur Laufzeit beim Transpilieren von Dateien bei Bedarf als auch bei Verwendung von bun build zum Vorab-Kompilieren von Dateien.

Syntax-hervorgehobene Quellcode-Vorschau

Um beim Debuggen zu helfen, druckt Bun automatisch eine kleine Quellcode-Vorschau, wenn eine unbehandelte Ausnahme oder Ablehnung auftritt. Sie können dieses Verhalten simulieren, indem Sie Bun.inspect(error) aufrufen:

ts
// Einen Fehler erstellen
const err = new Error("Something went wrong");
console.log(Bun.inspect(err, { colors: true }));

Dies druckt eine syntax-hervorgehobene Vorschau des Quellcodes, an dem der Fehler aufgetreten ist, zusammen mit der Fehlermeldung und dem Stacktrace.

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

V8 Stack Traces

Bun verwendet JavaScriptCore als Engine, aber ein Großteil des Node.js-Ökosystems und npm erwartet V8. JavaScript-Engines unterscheiden sich in der error.stack-Formatierung. Bun beabsichtigt, ein Drop-in-Ersatz für Node.js zu sein, und das bedeutet, dass es unsere Aufgabe ist, sicherzustellen, dass, obwohl die Engine anders ist, die Stacktraces so ähnlich wie möglich sind.

Deshalb ist beim Protokollieren von error.stack in Bun die Formatierung von error.stack dieselbe wie in Node.js' V8-Engine. Dies ist besonders nützlich, wenn Sie Bibliotheken verwenden, die V8-Stacktraces erwarten.

V8 Stack Trace API

Bun implementiert die V8 Stack Trace API, eine Reihe von Funktionen, die es Ihnen ermöglichen, Stacktraces zu manipulieren.

Error.prepareStackTrace

Die Error.prepareStackTrace-Funktion ist eine globale Funktion, die es Ihnen ermöglicht, die Stacktrace-Ausgabe anzupassen. Diese Funktion wird mit dem Fehlerobjekt und einem Array von CallSite-Objekten aufgerufen und ermöglicht es Ihnen, einen benutzerdefinierten Stacktrace zurückzugeben.

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" ]

Das CallSite-Objekt verfügt über die folgenden Methoden:

MethodeRückgabe
getThisthis-Wert des Funktionsaufrufs
getTypeNametypeof this
getFunctionFunktionsobjekt
getFunctionNameFunktionsname als String
getMethodNameMethodenname als String
getFileNameDateiname oder URL
getLineNumberZeilennummer
getColumnNumberSpaltennummer
getEvalOriginundefined
getScriptNameOrSourceURLQuell-URL
isToplevelgibt true zurück, wenn sich die Funktion im globalen Geltungsbereich befindet
isEvalgibt true zurück, wenn die Funktion ein eval-Aufruf ist
isNativegibt true zurück, wenn die Funktion nativ ist
isConstructorgibt true zurück, wenn die Funktion ein Konstruktor ist
isAsyncgibt true zurück, wenn die Funktion async ist
isPromiseAllNoch nicht implementiert.
getPromiseIndexNoch nicht implementiert.
toStringgibt eine String-Repräsentation der Aufrufstelle zurück

In einigen Fällen wurde das Function-Objekt möglicherweise bereits vom Garbage Collector gesammelt, sodass einige dieser Methoden undefined zurückgeben können.

Error.captureStackTrace(error, startFn)

Die Error.captureStackTrace-Funktion ermöglicht es Ihnen, einen Stacktrace an einer bestimmten Stelle in Ihrem Code zu erfassen, anstatt an der Stelle, an der der Fehler ausgelöst wurde.

Dies kann hilfreich sein, wenn Sie Callbacks oder asynchronen Code haben, der es schwierig macht, den Ursprung eines Fehlers zu bestimmen. Das zweite Argument von Error.captureStackTrace ist die Funktion, an der der Stacktrace beginnen soll.

Zum Beispiel wird der folgende Code err.stack auf den Code verweisen, der fn() aufruft, obwohl der Fehler bei myInner ausgelöst wurde.

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 von www.bunjs.com.cn bearbeitet