Kurz: Node.js führt JavaScript außerhalb des Browsers aus, auf Servern, in Skripten und in Werkzeugen. Es basiert auf derselben Engine (V8) wie Chrome, hat aber kein DOM, sondern Module für Dateien, Netzwerk und Betriebssystem.
Teil des Kurses JavaScript
Kapitel 34 von 40 im Kurs JavaScript (Abschnitt „Node.js“). Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.
Node.js führt JavaScript außerhalb des Browsers aus, auf Servern, in Skripten und in Werkzeugen. Es basiert auf derselben Engine (V8) wie Chrome, hat aber kein DOM, sondern Module für Dateien, Netzwerk und Betriebssystem.
Installieren und starten
Lade Node.js (empfohlen: die LTS-Version) von nodejs.org. Prüfen im Terminal:
node --version
npm --version
node hallo.js
node # interaktive Konsole (REPL)Globale Objekte
console.log(typeof process, typeof global, typeof __dirname);
console.log(process.platform.length > 0, process.version.startsWith("v"));
console.log(process.argv.length >= 2);
console.log(typeof process.env.PATH, typeof process.cwd());
console.log(typeof setTimeout, typeof fetch, typeof structuredClone);Ausgabe:
object object string
true true
true
string string
function function functionprocess.argvArgumente der Befehlszeile ([node, skript, ...])process.envUmgebungsvariablen (process.env.PORT)process.exit(code)beendet das Programm__dirname,__filenamePfad der Datei (nur CommonJS; in ESM:import.meta.dirname)
Dateien lesen und schreiben
Das Modul fs (file system) hat synchrone und asynchrone Funktionen. Bevorzuge die Promise-Variante:
const fs = require("node:fs/promises");
const path = require("node:path");
const os = require("node:os");
async function main() {
const ordner = await fs.mkdtemp(path.join(os.tmpdir(), "demo-"));
const datei = path.join(ordner, "notiz.txt");
await fs.writeFile(datei, "Zeile 1\nZeile 2\n", "utf8");
await fs.appendFile(datei, "Zeile 3\n");
const inhalt = await fs.readFile(datei, "utf8");
console.log(inhalt.trim().split("\n"));
const infos = await fs.stat(datei);
console.log(infos.size, infos.isFile());
console.log(await fs.readdir(ordner));
await fs.rm(ordner, { recursive: true });
console.log("aufgeräumt");
}
main().catch(console.error);Ausgabe:
[ 'Zeile 1', 'Zeile 2', 'Zeile 3' ]
24 true
[ 'notiz.txt' ]
aufgeräumtPfade baust du mit path zusammen, nie mit +:
const path = require("node:path");
console.log(path.join("ordner", "unter", "datei.txt"));
console.log(path.basename("/a/b/bild.png"), path.extname("bild.png"), path.dirname("/a/b/bild.png"));
console.log(path.parse("/home/mia/text.md").name);Ausgabe:
ordner/unter/datei.txt
bild.png .png /a/b
textArgumente und Umgebung
const [, , ...args] = ["node", "skript.js", "--name=Mia", "--laut"];
const optionen = Object.fromEntries(
args.filter(a => a.startsWith("--")).map(a => a.slice(2).split("=")).map(([k, v = true]) => [k, v])
);
console.log(optionen);
console.log(process.env.UNBEKANNT ?? "Standardwert");Ausgabe:
{ name: 'Mia', laut: true }
StandardwertFür ernsthafte Programme nimmst du util.parseArgs (eingebaut) oder Pakete wie commander.
Ein einfacher Webserver
import { createServer } from "node:http";
const server = createServer((anfrage, antwort) => {
console.log(anfrage.method, anfrage.url);
antwort.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
antwort.end("Hallo vom Server!");
});
server.listen(3000, () => console.log("Läuft auf http://localhost:3000"));Starte mit node server.mjs und öffne http://localhost:3000. In der Praxis nimmt man dafür Frameworks wie Express, Fastify oder Hono.
Streams
Streams verarbeiten große Daten stückweise, ohne alles in den Speicher zu laden:
const { Readable, Transform } = require("node:stream");
const { pipeline } = require("node:stream/promises");
const gross = new Transform({
transform(chunk, _enc, cb) { cb(null, chunk.toString().toUpperCase()); },
});
const ausgabe = [];
pipeline(Readable.from(["hallo ", "welt"]), gross, async function (quelle) {
for await (const teil of quelle) ausgabe.push(teil.toString());
}).then(() => console.log(ausgabe.join("")));Ausgabe:
HALLO WELTEvents
Viele Node-Objekte senden Ereignisse über EventEmitter:
const { EventEmitter } = require("node:events");
class Chat extends EventEmitter {}
const raum = new Chat();
raum.on("nachricht", (von, text) => console.log(`${von}: ${text}`));
raum.once("start", () => console.log("Chat gestartet"));
raum.emit("start");
raum.emit("start");
raum.emit("nachricht", "Mia", "Hallo!");Ausgabe:
Chat gestartet
Mia: Hallo!Prozesse starten
const { execFileSync } = require("node:child_process");
console.log(execFileSync("node", ["--version"]).toString().startsWith("v"));Ausgabe:
trueAchtung
Baue Befehle nie durch Zusammenkleben von Nutzereingaben (
exec("rm " + eingabe)). NutzeexecFile/spawnmit Argumentliste, um Befehlseinschleusung zu verhindern.
Merke
- Node.js führt JavaScript ohne Browser aus (kein DOM, dafür
fs,http,process) fs/promisesundpathfür Dateien und Pfadeprocess.argv,process.envfür Argumente und Umgebung- Streams für große Daten,
EventEmitterfür Ereignisse - Eingaben nie ungeprüft an Shell-Befehle hängen
Übungsaufgabe
Schreibe ein Skript, das eine Textdatei einliest, die Wörter zählt und das Ergebnis in eine neue Datei schreibt.
Quiz zur Selbstkontrolle
Welches Modul liest und schreibt Dateien?
- fs (richtig)
- http
- os
- events
Wie erreichst du Umgebungsvariablen?
- process.env (richtig)
- os.env
- global.env
- env()
Warum Pfade mit path.join bauen?
- Es nutzt das richtige Trennzeichen für das Betriebssystem (richtig)
- Es ist kürzer
- Es prüft, ob die Datei existiert
- Es erstellt den Ordner
Weiter im Kurs
Zurück: Zeichnen mit Canvas und Animation
Weiter: npm und Pakete
Alle Kapitel: JavaScript im Überblick