mitmario.dev

Die Sandbox in diesem Kurs

Node.js Sandbox 8 Min Lesezeit 3 BeispieleLektion 5 von 6

Dein Code läuft in diesem Kurs nicht im Browser. Er läuft auch nicht auf deinem Rechner. Er läuft in einer kleinen virtuellen Maschine in einem Rechenzentrum, die für diesen einen Zweck entsteht und danach wieder verschwindet.

Das hat Folgen, die du kennen solltest. Sonst hältst du jede dieser Grenzen für einen eigenen Fehler und suchst ihn im eigenen Code.

Was hier nicht geht

Kein Internet. Die Maschine hat keinen Netzzugang, nicht einmal eine Namensauflösung.

Ein Zugriff nach draußen schlägt fehl
const antwort = await fetch("https://mitmario.dev/lernen/api/kurse.json");
console.log(await antwort.json());

Dieser Aufruf endet mit einem TypeError: fetch failed, und darunter steht als Ursache EAI_AGAIN. Das heißt genau das: Der Name ließ sich nicht auflösen. Wenn du so etwas siehst, ist es kein Fehler in deinem Code, sondern die Firewall. Und es gibt keine Ausnahme, auch nicht beim Installieren: Die beiden Pakete, die dieser Kurs benutzt, liegen schon auf der Maschine und werden nur an die richtige Stelle kopiert. Tippst du im Terminal ein npm install für irgendetwas anderes, bekommst du dieselbe Meldung wie oben, nur aus npm: npm error code EAI_AGAIN.

Keine Tastatureingabe während des Laufs. Ein Programm, das auf eine Eingabe wartet, bekommt sofort das Ende der Eingabe zu sehen, denn hier sitzt niemand. Das heißt nicht, dass du Eingaben in diesem Kurs nie ausprobieren kannst: Im Terminal geht eine Pipe, und Lektion 4.4 zeigt beides nebeneinander.

Höchstens zehn Sekunden Laufzeit. Danach wird das Programm hart beendet.

Eine Endlosschleife wird abgebrochen
console.log("Los");

let n = 0;
while (true) {
  n = n + 1;
}

Der Abbruch meldet sich nicht. Im Terminal steht das Los aus der ersten Zeile, und dann hört es auf. Kein Hinweis, keine Zahl, nichts, was dir sagt, dass hier jemand den Stecker gezogen hat. Wenn eine Ausgabe mitten im Nichts endet und du vorher ein paar Sekunden gewartet hast, ist das die Erklärung, und der Grund ist fast immer derselbe: eine Schleife ohne Ende, ein await auf etwas, das nie kommt, ein Server, der auf einen falschen Port hört. Nur bei den Server-Aufgaben ab Abschnitt 8 gilt eine großzügigere Grenze, dort läuft der Prozess ja mit Absicht weiter.

Im Terminal ist es anders herum: Dort hast du 30 Sekunden statt zehn, und wenn sie um sind, steht da ein Satz dazu. Eine Zahl bekommst du auch dort nur, wenn du sie anhängst, und zwar in derselben Zeile: node index.js; echo $?. Jeder getippte Befehl fährt in einer eigenen Shell, ein echo $? als nächster Befehl wüsste also nichts mehr von dem davor.

Der Prüfknopf räumt auf. Er fängt mit genau den Dateien an, die im Editor stehen, und was dein Programm beim letzten Mal angelegt hat, ist dann weg. So hängt keine Aufgabe daran, was in der vorigen liegen geblieben ist. Das Terminal räumt dagegen nicht auf: Was dort entsteht, bleibt stehen, solange die Sandbox läuft. Der Unterschied wird in Abschnitt 3 wichtig, wenn du Dateien schreibst und danach nachsehen willst, ob sie wirklich da sind.

Was dafür geht

Alles, was den Kurs ausmacht. Echte Dateien, die du liest und schreibst. Echte Module über mehrere Dateien. Ein echter Server auf localhost. Eine echte SQLite-Datenbank. Ein echtes npm install.

Das ist der Punkt: Es ist keine Nachbildung. Wenn hier etwas läuft, läuft es auf deinem Rechner genauso, und wenn hier ein Stacktrace steht, ist es derselbe Stacktrace.

Warum es so gebaut ist

Zwei Gründe, und beide sind langweilig und richtig.

Eine Umgebung ohne Netz lässt sich nicht für fremde Zwecke missbrauchen. Fremden Code auszuführen und ihn dann ins Internet zu lassen, wäre ein offenes Scheunentor.

Und ein sauberer Start bei jedem Prüflauf sorgt dafür, dass eine Aufgabe nicht davon abhängt, was in der vorigen liegen geblieben ist. Andernfalls bestünde eine Challenge irgendwann nur noch deshalb, weil zwei Lektionen vorher zufällig die passende Datei entstanden ist.

Wo ein Ergebnis auftaucht

Unten steht, was läuft, rechts steht der Browser, links das Urteil. Wer das einmal auseinanderhält, sucht später nicht an der falschen Stelle.

Die Prüfliste steht links bei der Aufgabe und sagt, ob es zählt. Sie ist das Urteil, und sie ist die einzige Fläche, die etwas entscheidet. Der Knopf, der sie füllt, steht darunter.

Das Terminal unter dem Editor ist in diesem Kurs die wichtigste Fläche. Dort steht, was dein Programm auf die Standardausgabe geschrieben hat, darunter der Fehlerkanal in Rot. Genau das, was auch auf einer echten Konsole stünde, und nichts sonst: Was dein Programm nicht selbst geschrieben hat, steht auch nicht dort.

Über jeder Ausgabe steht der Befehl, der sie erzeugt hat. Auch der Prüfknopf schreibt seinen dorthin, so als hättest du ihn selbst getippt, denn genau das tut er: dieselbe Maschine, dasselbe Arbeitsverzeichnis, derselbe Befehl. Und du kannst dort selbst tippen; Abschnitt 3 zeigt, was das kann. Die Befehle, um die es in einer Lektion geht, stehen dabei unten in der Befehlsleiste: Ein Klick schreibt den Befehl in die Eingabezeile, ändern darfst du ihn noch, und Enter drückst du selbst.

Rechts liegen vier Reiter, dieselben wie in den drei Kursen davor.

Unter Browser steht ein Browser, mit Adresszeile und den Knöpfen dazu. Ab Abschnitt 8, sobald du einen Server startest, lädt er dessen Adresse und zeigt, was er antwortet: eine Seite, ein Stück JSON, eine Fehlermeldung. Startet dein Code keinen Server, bleibt die Seite weiß und sagt das auch. Bis Abschnitt 8 ist das der Normalfall.

Unter Console steht die Console dieses Browsers, also das, was der Code in der Seite mit console.log schreibt. Das ist nicht dasselbe wie die Ausgabe deines Programms: Dein Node-Code läuft auf dem Server, und was er schreibt, steht unten im Terminal. In diesem Kurs bleibt die Console deshalb meistens leer, und das ist keine Panne.

Unter Netzwerk steht, was der Browser daneben geladen hat: die Seite selbst, ihr Stylesheet, ihre Bilder, jede mit Status, Größe und Dauer. Browser, Console und Netzwerk sind dieselben drei Werkzeuge, die du später in jedem Browser benutzt. Die Anfragen der Prüfung stehen woanders, nämlich links in der Prüfliste unter der Zeile, die sie gestellt hat: Dort willst du sie haben, wenn eine Zeile rot ist.

Unter Debug liegt das Werte-Protokoll, das du aus dem JavaScript-Kurs kennst. Ein Druck auf Aufzeichnen, und dein Programm läuft noch einmal, diesmal mit einer Meldung vor jeder Zeile: was stand in diesem Moment in deinen Variablen. Danach blätterst du durch die Liste, und der Editor springt mit. Drei Dinge sind hier anders als in den Browser-Kursen. Es ist ein eigener Lauf und kostet darum so viel wie jeder andere. Aufgezeichnet wird die Datei, die im Editor gerade vorn liegt; wer ein Modul sehen will, das der Server nur benutzt, holt es vorher nach vorn. Und einen Schub von Schritten beginnt hier keine Maus, sondern eine Anfrage: Bei einer Aufgabe mit Server steht über den Schritten, welche der Prüfanfragen sie ausgelöst hat.

Zwei Werkzeuge aus den Kursen davor gibt es auch hier. Das Fadenkreuz in der Browser-Leiste ist der Inspector: Zeig damit auf ein Element der Seite, die dein Server geschickt hat, und im Auskunftsstreifen darunter stehen seine Maße und seine berechneten Werte. Und unter den Console-Zeilen steht die Eingabezeile der Console, in die du einen Ausdruck tippen kannst; er läuft in genau der Seite, die gerade rechts steht. Auf einem schmalen Bildschirm fehlt das Fadenkreuz, wie in den Kursen davor. Brauchen wirst du beide hier seltener als im CSS-Kurs: Was über die Leitung ging, steht im Reiter Netzwerk, und ab Abschnitt 8 fragst du deinen Server im Terminal direkt. Wofür sie trotzdem gut sind, ist die Gegenprobe: nachsehen, was aus dem HTML, das dein Code zusammenbaut, im Browser wirklich geworden ist.

Was rechts steht, gehört immer zum letzten Lauf. Ergibt der nächste keine Seite, wird der Browser wieder leer. Das ist Absicht: Eine Seite, die dem gerade gelaufenen Code widerspricht, wäre schlimmer als keine. Und kommt dein Server gar nicht erst hoch, sagt er auch das, statt still leer zu bleiben.

Eine Ausgabe, die eine Seite ist
const kurse = ["HTML", "CSS", "JavaScript", "Node.js"];

const zeilen = kurse.map((kurs) => `  <li>${kurs}</li>`).join("\n");

console.log(`<h1>Vier Kurse</h1>
<ul>
${zeilen}
</ul>`);

Dieses Beispiel schreibt Markup, und trotzdem passiert im Browser daneben nichts. Im Terminal stehen die Zeichen, die dein Programm geschrieben hat, also <h1>Vier Kurse</h1> und die Liste darunter, und rechts bleibt es weiß. Das ist kein Fehler: Hier läuft kein Server, es gibt also niemanden, der diese Zeichen an einen Browser schicken würde.

Der Unterschied zwischen den Zeichen und ihrer Wirkung ist oft genau der Punkt, um den es geht. Ab Abschnitt 8 schickst du dasselbe Markup über HTTP, und dann steht rechts eine Überschrift mit vier Aufzählungspunkten. Bis dahin liest du es so, wie dein Programm es geschrieben hat.

Dann wird auch der Reiter „Browser” ernst. Dort läuft wirklich ein Server, und was dort steht, ist kein Bild davon: du kannst Links anklicken, Formulare abschicken und dich später an deiner eigenen Anmeldung anmelden.

Am bequemsten geht das mit dem Knopf Sandbox starten oben über dem Editor. Solange die Sandbox läuft, zieht die Seite bei jeder Änderung an deinem Code von selbst nach, ohne dass du klicken musst. Der Knopf heißt dann Sandbox beenden; nach fünf Minuten, in denen du nichts tust, endet sie von selbst, und der Knopf sagt eine Minute vorher Bescheid.

Der Kostenteil, im Klartext

Eine solche Maschine kostet bei jedem Lauf Geld. Nicht viel, aber echtes Geld, und das ist der Unterschied zu den drei Kursen davor: Dort lief dein Code im Browser, und ein Browser gehört dir.

Daraus folgen drei Dinge, die dir in diesem Kurs auffallen werden.

Erstens zählt hier die Zeit. Lesen kostet nichts: die Artikel, der Code aller Beispiele, die Aufgaben und die Abschnittstests. Sobald eine Maschine läuft, zählt ihre Laufzeit auf ein Kontingent, das jeden Monat neu beginnt: 1 Stunde mit dem Basis Konto, 60 Stunden mit dem Premium Konto. Wie viel davon übrig ist, siehst du in jeder Lektion mit Sandbox und unter „Nutzung” in deinem Konto. Ist es aufgebraucht, geht es mit dem Premium Konto sofort weiter, sonst im nächsten Monat.

Zweitens läuft nichts von selbst, solange du die Sandbox nicht gestartet hast. In den Browser-Kursen lief deine Seite immer mit, hier wäre das eine Maschine, die durchgehend läuft; mit Sandbox starten entscheidest du selbst, wann sie es ist, und wie lange.

Drittens steht nur dann etwas da, wenn wirklich etwas gelaufen ist. Keine nachgestellten Ausgaben, keine Zahlen, für die am Ende niemand geradesteht. Was du liest, hat deine Maschine gerade ausgegeben, mit deinem Code.

Diese Lektion hat keine Aufgabe, und das ist Absicht. Die ersten beiden Beispiele zeigen zwei Grenzen, gegen die man sonst aus Versehen läuft. Absichtlich dagegenzulaufen kostet eine Maschine und bringt dir nichts bei, was hier nicht schon steht. Ab der nächsten Lektion läuft dein Code.

Zum Mitnehmen

Die ersten beiden Beispiele sind zum Lesen da, nicht zum Ausprobieren: sie zeigen Grenzen der Umgebung und keine Fehler in deinem Code. Das dritte zeigt, wo ein Ergebnis überall auftauchen kann.

Jetzt du

Basis Konto, kostenlos

Im Editor änderst du die Beispiele dieser Lektion und lässt sie gleich laufen. So merkst du am schnellsten, ob es sitzt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.

Was in dieser Lektion steckt

  • Artikel mit 3 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.