223015c/02: - glossar landkarte: klausur, prosa, reihenfolge (host→client→server→req→res→protokoll), tcp/http als beispiel - glossar adressen/daten/eigenschaften/protokolle: prosa-sätze - tcp/ip-modell: nichtssagenden satz ersetzt - dateneinheiten: merkhilfe durch prosa ersetzt - osi vs tcp/ip: bg right statt h:440, prosa statt einzeiler - port: tabelle→liste, prosa statt bullets - ip vs mac vs port: prosa - tcp vs udp, http-methoden, status-codes, einheiten: prosa - selektoren id + farben: klausur markiert - farben: mdn-link, prosa-satz dhbw/01: - farben: prosa-satz synchronisiert - über-mich: collage-bild hinzugefügt
29 KiB
marp, theme, paginate, backgroundColor, header, footer, title
| marp | theme | paginate | backgroundColor | header | footer | title |
|---|---|---|---|---|---|---|
| true | gaia | true | Web Engineering – DHBW Stuttgart | Michael Czechowski – SoSe 2026 | Web Engineering |
Web Engineering
DHBW Stuttgart · Informatik / Wirtschaftsinformatik
Sommersemester 2026
Herzlich Willkommen!
1. Sitzung: 08.05.2026
Über mich
Michael Werner Czechowski
- Systems and Platform Engineer
- Schwerpunkte:
- Web-Technologien, Barriere-Armut, Open Source
- Hintergrund:
- Philosophie (Uni Stuttgart)
- Wirtschaftsinformatik (Leibniz-FH Hannover)
- Honorardozent (DHBW Stuttgart, HdM Stuttgart, Leibniz-FH)
- Kontakt: michael.czechowski@lehre.dhbw-stuttgart.de
Vorlesungsplan
| Sitzung | Datum | Thema |
|---|---|---|
| 1 | 08.05. | Intro, Projektgruppen, Internet 101 |
| 2 | 15.05. | HTML und CSS (Frameworks) |
| 3 | 22.05. | JS (Frameworks) und npm |
| 4 | 29.05. | nodeJS: Scripting, Running and Building |
| 5 | 05.06. | Express API, CRUD und "Middlewares" |
| 6 | 12.06. | Projektwerkstattbericht |
| 7 | 19.06. | Testing (unit, integration, end-to-end) |
| 8 | 26.06. | TypeScript |
| 9 | 03.07. | Docker, Proxies and DBs |
| 10 | 10.07. | Wrap-up & Projektsupport |
| 11 | 17.07. | Präsentation |
Prüfungsleistung – Übersicht
Eigenes Projekt: Web-App ODER Backend (API/CLI — Command-Line Interface).
Grundanforderungen (75 Punkte)
| Punkte | Bereich |
|---|---|
| 20 | Idee, Konzeption, Planung |
| 5 | Plattformunabhängigkeit |
| 25 | Clean Code (KISS, SOLID, DI, Testing, Error Handling) |
| 15 | Präsentation |
| 10 | Dokumentation |
Zusatzpunkte (max. 10): TypeScript, Docker, Dev/Prod-Parity, .env, npm-Publish, Domain, HTTPS, Responsive Design.
Prüfungsleistung – Idee & Konzeption (20 P.)
- "Powerpoint"-Präsentation + Folien
- Aussagekräftiger Arbeitstitel + Beschreibung
- Elevator Pitch (max. 1 Min.)
- Repo-Link (GitHub / GitLab / Codeberg / BitBucket)
- Logs: wie hat sich Projekt verändert vs. Ursprungsidee?
- Schematischer Projektaufbau (UML o. Ä.)
Prüfungsleistung – Clean Code (25 P.)
README.md(clone, start, contribute)- KISS – Keep It Simple, Stupid
- SOLID:
- Single Responsibility Principle
- Open/Closed Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
- DI – Dependency Injection
- Testing-Pyramide (Unit, Integration, E2E)
- Exception/Error Handling
Prüfungsleistung – Abgabe & Termine
- Code-Upload: bis 27.07.
- Präsentation: 17.07. (Gruppen, ~10 Min.)
Details: https://git.dailysh.it/DHBW/pruefungsleistung
Internet 101 – Zeitleiste
| Jahr | Ereignis |
|---|---|
| 1966 | ARPANET |
| 1969 | RFCs |
| 1986 | IETF |
| 1992 | Internet Society |
| 1974 | TCP/IP und HTTP(S) |
| 1987 | Domain Names und DNS |
| 1993 | "Erster" Browser: Mosaic |
| 1994 | W3C (HTML, XML, CSS, SVG, WCAG etc.) |
| 1995 | ECMAScript (JS) |
| 2006/08 | V8 JS Runtime Engine |
| Heute | 1,3 Mio. km Unterseekabel |
HTTP – Hypertext Transfer Protocol
Request:
GET /products HTTP/1.1
Host: localhost:8080
Response:
HTTP/1.1 200 OK
Content-Type: application/json
[{"id": 1, "name": "Produkt A"}, ...]
Onboarding
Tools, Runtimes, Workflows
Werkzeuge & Betriebssystem
Erforderliche Werkzeuge:
- Terminal (zsh / bash / fish / pwsh) — Kommandozeile
- Editor (siehe folgende Folie)
- JavaScript-Runtime (Node.js / Bun / Deno)
- Browser mit DevTools (Chromium / Firefox / Safari)
- Git — verteiltes Versionskontrollsystem (Stand der Industrie)
OS-Empfehlung:
| OS | Status |
|---|---|
| macOS | First-class, viele Tools "just work" |
| Linux | First-class, beste Server-Parität |
| Windows + WSL2 | Empfohlen — Windows-CLI hat Edge Cases |
| Windows nativ (PowerShell) | Funktioniert, aber holpriger Pfad |
Node.js installieren – macOS
Empfohlen: LTS (aktuell Node.js 24 — Stand 2026).
Paketmanager: Homebrew
# Homebrew installieren (falls nicht vorhanden)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Node.js LTS installieren
brew install node@24
# Version prüfen
node --version
npm --version
Alternative: Installer von nodejs.org
Node.js installieren – Linux
Empfohlen: LTS (aktuell Node.js 24).
Debian / Ubuntu (NodeSource):
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs
Arch / Manjaro:
sudo pacman -S nodejs npm
Fedora / RHEL:
sudo dnf module install nodejs:24/common
→ Distro-Pakete sind oft veraltet. Versionsmanager (folgende Folie) bevorzugen.
Node.js installieren – Windows
Empfohlen: LTS (aktuell Node.js 24).
Option 1: winget (empfohlen, Win 10/11):
winget install OpenJS.NodeJS.LTS
Option 2: Chocolatey (chocolatey.org):
choco install nodejs-lts
Option 3: Scoop (scoop.sh):
scoop install nodejs-lts
Option 4: Installer von nodejs.org
→ Empfehlung: WSL2 + Linux-Workflow nutzen.
Direkt-Install: Wenn es eng wird
Typisches Szenario in Studium und Beruf — drei parallele Projekte mit unterschiedlichen Anforderungen:
| Projekt | Stack | Node-Version |
|---|---|---|
| Praktikums-API | Express (Legacy) | 18.x (LTS Hydrogen) |
| Studienarbeit | Next.js 15 | 22.x (LTS Jod) |
| Aktuelles Lab-Projekt | neueste Features | 24.x (Iron, current LTS) |
System-Install kennt nur eine Node-Version global.
Symptome im Alltag:
npm installbricht mitengines-Warning ab- native Module (z. B.
node-sass) bauen nicht - CI-Pipeline ist grün, lokal rot — oder umgekehrt
- erheblicher Zeitverlust beim Debuggen von Versions-Konflikten
→ Lösung: Versionsmanager und Node-Version pro Projekt pinnen.
Node-Versionsmanager
Verschiedene Projekte brauchen oft verschiedene Node-Versionen. Lösung: Versionsmanager.
| Tool | Sprache | Geschwindigkeit | Plattform |
|---|---|---|---|
| nvm | Bash | langsam (Shell-Funktion) | macOS, Linux |
| fnm | Rust | sehr schnell | macOS, Linux, Windows |
| asdf | Bash | mittel, multi-language | macOS, Linux |
| volta | Rust | schnell, pinning per package.json |
alle |
# fnm
curl -fsSL https://fnm.vercel.app/install | bash
fnm install --lts # aktuell Node 24
fnm use lts-latest
# .nvmrc / .node-version automatisch
echo "lts/*" > .nvmrc
fnm use # liest .nvmrc
Alternative Runtimes
| Runtime | Erschienen | Engine | USP |
|---|---|---|---|
| Node.js | 2009 | V8 (C++) | Standard, größtes Ökosystem |
| Deno | 2020 | V8 (Rust) | Sicherheit, TypeScript nativ, Std-Lib |
| Bun | 2022 | JavaScriptCore (Zig) | Geschwindigkeit, all-in-one |
# Deno
curl -fsSL https://deno.land/install.sh | sh
deno run main.ts
# Bun
curl -fsSL https://bun.sh/install | bash
bun install
bun run dev
→ Im Kurs primär Node.js. Bun und Deno sind ebenfalls zulässig.
Editor
- VS Code (empfohlen) — kostenlos, große Plugin-Auswahl
- JetBrains WebStorm — sehr mächtig, kostenpflichtig
- kostenlos für Studierende via JetBrains Education
- Vim / Neovim / Emacs — für CLI-Profis
- Zed — modern, schnell
Browser DevTools
Chromium / Firefox / Safari — F12 oder Cmd+Opt+I
Chromium = Open-Source-Basis von Chrome, Edge, Brave, Opera, Vivaldi etc.
Wichtigste Panels:
- Network — HTTP-Requests, Responses, Timing
- Console —
console.log, JS-Errors, REPL - Elements — DOM-Inspektor, Live-CSS-Editor
- Sources — Debugger, Breakpoints, Source-Maps
- Performance — Profiling, Frame-Rate, FPS
- Application — LocalStorage, Cookies, Service Workers
HTTP-Clients
- Bruno (usebruno.com) — open source, git-friendly
- Hoppscotch (hoppscotch.io) — open source, browser-basiert (vormals Postwoman)
- Insomnia / Postman — etabliert, freemium
- curl / httpie — CLI (Command-Line Interface, scriptbar)
Git Setup & Workflow
Einmalige Konfiguration:
git config --global user.name "Vorname Nachname"
git config --global user.email "vorname.nachname@example.com"
git config --global init.defaultBranch main
git config --global pull.rebase true
SSH-Key für GitHub/GitLab:
ssh-keygen -t ed25519 -C "vorname.nachname@example.com"
cat ~/.ssh/id_ed25519.pub # → in GitHub-Settings einfügen
Tägliche Befehle:
git status # was hat sich geändert?
git add <file> # für Commit vormerken
git commit -m "feat: ..." # Conventional Commits
git push # hochladen
git pull --rebase # neueste Änderungen holen
Projekt-Skeleton
mkdir mein-projekt && cd mein-projekt
git init
npm init -y # erzeugt package.json
echo "node_modules" > .gitignore
echo ".env" >> .gitignore
npm install express
package.json minimal:
{
"name": "mein-projekt",
"version": "0.1.0",
"type": "module",
"scripts": {
"start": "node index.js",
"dev": "node --watch index.js"
}
}
.env für Secrets (nie committen!), .env.example mit Dummy-Werten committen.
HTML – Hypertext Markup Language
Was ist HTML? (1/2)
HyperText Markup Language
- Keine Programmiersprache
- Am ehesten eine Formattierungssprache
- Beschreibt Struktur und Aufbau einer Webseite
<p>Das ist ein Absatz.</p>
<input type="date" />
Erfunden 1989 von Tim Berners-Lee. Aktuelle Version: HTML5 (seit 2014).
Was ist HTML? (2/2)
- Mit HTML werden HTML-Dokumente beschrieben (
index.html) - Ein HTML-Dokument beschreibt das Document Object Model (DOM)
- Der DOM ist eine hierarchische Baumstruktur (Eltern, Kinder, Geschwister)
- parent nodes / elements
- child nodes / elements
- sibling nodes / elements
In HTML sprechen wir von Elementen, in JavaScript eher von Nodes.
HTML-Anatomie (1/2)
Formattierungssprache mit strenger Syntax:
<element attribute="value"> ... </element>
- Öffnende und schließende Tags müssen identisch sein
- Schließendes Tag hat ein
/nach der Spitzklammer
HTML-Anatomie (2/2)
Wir unterscheiden umschließende und selbst-schließende Tags.
Umschließend:
<b> ... </b>– fett-gedruckter Text (inline)<a> ... </a>– Hyperlink<body> ... </body>– sichtbarer Teil eines HTML-Dokuments<details> ... </details>– Aufklapp-Text / Akkordion
Selbst-schließend:
<img />– Bild, Vektorgrafik<input />– Eingabefeld<meta />– Metadaten
Darstellungsebene und Metadaten
<html>
<head>
METADATEN
</head>
<body>
DARSTELLUNGSEBENE
</body>
</html>
Ein HTML-Dokument besteht aus zwei Teilen:
<head> ... </head>– Metadaten für Browser, Suchmaschinen, Social Sharing<body> ... </body>– darzustellender Inhalt, Text, Formulare
HTML Metadaten
<html>
<head>
<title>DHBW Stuttgart</title>
<meta name="description" content="Studium mit Praxis" />
<meta property="og:image" content="https://...." />
</head>
...
</html>
Webseiten besuchen nicht nur Menschen, sondern auch Suchmaschinen, Bots, Screen-Reader. Metadaten helfen beim "Verstehen" der Inhalte.
HTML Metadaten – Vertiefung
| Tag | Funktion |
|---|---|
<title> |
Browser-Tab, Suchergebnis-Titel |
<meta charset> |
Zeichenkodierung (Umlaute!) |
<meta viewport> |
Mobile Darstellung |
<meta description> |
Suchergebnis-Snippet (max 160 Zeichen) |
Open Graph (Social-Media-Vorschau):
<meta property="og:title" content="Artikel-Titel">
<meta property="og:image" content="https://example.com/preview.jpg">
→ Wirkt auf Mastodon, LinkedIn, Signal, Slack, MS Teams ...
SEO: Google nutzt <title> + <meta description> für Ranking + Snippet.
HTML-Tags und Attribute
<body>
<p class="wichtig">Das ist ein wichtiger Absatz.</p>
<p>Das ist ein gewöhnlicher Absatz.</p>
</body>
| Teil | Bezeichnung |
|---|---|
<p> |
Opening Tag |
class="wichtig" |
Attribut |
Das ist ein wichtiger Absatz. |
Inhalt |
</p> |
Closing Tag |
HTML-Tags und Attribute (selbst-schließend)
Geburtsdatum <input type="date" />
| Teil | Bezeichnung |
|---|---|
<input ... |
Eingabefeld |
type="date" |
Attribut type mit Wert date |
... /> |
Schließendes / im (öffnenden) Tag |
Vollständiges Grundgerüst
<!DOCTYPE html>
<html lang="de">
<head>
<title>Portfolio von ...</title>
<meta name="description" content="..." />
<meta property="og:image" content="https://...." />
</head>
<body>
<h1>Hallo Welt!</h1>
<p>Das ist mein erster Absatz.</p>
</body>
</html>
Die wichtigsten Tags
| Tag | Bedeutung |
|---|---|
<h1> … <h6> |
Überschriften (h1 = größte) |
<p> |
Absatz (Paragraph) |
<a href="..."> ... </a> |
Hyperlink |
<img src="..." /> |
Bild |
<ul>, <ol>, <li> |
Listen |
<div> |
Container / Box |
<span> |
Inline-Container |
<input type="..."> |
Eingabefeld |
Semantische Tags (<header>, <main>, <article>, <footer>, <nav>, <aside>) wichtig für Accessibility.
Natives HTML
Was früher mit JavaScript gelöst wurde, kann HTML heute selbst. JS dafür einzusetzen ist heute oft ein Code Smell.
| Funktion | HTML-Element |
|---|---|
| Aufklapp-Text | <details> + <summary> |
| Popup / Modal | <dialog> |
| Fortschrittsbalken | <progress> |
| Datum-Auswahl | <input type="date"> |
| Validierung | Attribute: required, min, max, pattern |
Beispiel: Details/Summary
Akkordion · Accordion · Aufklappmenü · Collapsible
<details>
<summary>Klick mich!</summary>
<p>Dieser Text ist versteckt.</p>
</details>
Doku: developer.mozilla.org
Beispiel: Details/Summary (geöffnet)
<details open>
<summary>Klick mich!</summary>
<p>Dieser Text war versteckt.</p>
</details>
Beispiel: Button
<button>Add to favorites</button>
Doku: developer.mozilla.org
Beispiel: Input/Eingabefeld
<input
type="text"
maxlength="8"
size="10" />
Doku: developer.mozilla.org
Beispiel: Dialog
Modal · Modales Fenster · Popup · Overlay · Dialogfenster
<dialog open>
<p>Greetings, one and all!</p>
<form method="dialog">
<button>OK</button>
</form>
</dialog>
Doku: developer.mozilla.org
CSS – Cascading Style Sheets
Was ist CSS?
Cascading Style Sheets
p {
color: blue;
font-size: 16px;
}
- Trennt Inhalt (HTML) von Darstellung (CSS)
- "Cascading" = Regeln können überschrieben werden
- Eine CSS-Datei kann viele HTML-Seiten stylen
CSS einbinden
Option 1: Externe Datei ✓
<link rel="stylesheet" href="style.css">
Option 2: Style-Tag
<style>p { color: blue; }</style>
Option 3: Inline ✗
<p style="color: blue;">...</p>
→ Standard ist externe Datei. Inline vermeiden (schwer zu warten, keine Wiederverwendung).
CSS-Anatomie
selector {
property: value;
}
Beispiel:
h1 {
color: #333333;
font-size: 2rem;
margin-bottom: 1rem;
}
Selektor → was wird gestylt Property → welche Eigenschaft Value → welcher Wert
Selektoren: Element
/* Alle <p>-Elemente */
p {
color: gray;
}
/* Mehrere Elemente gleichzeitig */
h1, h2, h3 {
font-family: sans-serif;
}
Element-Selektoren sind die einfachsten. Komma = "oder".
Selektoren: Klasse
<p class="wichtig">Dieser Text ist wichtig.</p>
<p>Dieser nicht.</p>
.wichtig {
color: red;
font-weight: bold;
}
Punkt vor dem Namen = Klasse. Beliebig oft anwendbar; ein Element kann mehrere Klassen haben.
Selektoren: ID
<nav id="hauptnavigation">...</nav>
#hauptnavigation {
background: #333;
padding: 1rem;
}
Raute vor dem Namen = ID.
⚠️ IDs sollten einmalig pro Seite sein. In der Praxis: Klassen meist besser.
Selektoren: Kombinationen
/* Nachfahre (beliebig tief verschachtelt) */
article p { line-height: 1.6; }
/* Direktes Kind (eine Ebene) */
nav > a { text-decoration: none; }
/* Nächstes Geschwister */
h2 + p { font-size: 1.2rem; }
/* Element mit Klasse */
p.wichtig { color: red; }
Spezifität: Welche Regel gewinnt?
| Selektor | Spezifität |
|---|---|
Element (p) |
0,0,0,1 |
Klasse (.wichtig) |
0,0,1,0 |
ID (#header) |
0,1,0,0 |
Inline (style="...") |
1,0,0,0 |
p { color: blue; } /* 0,0,0,1 */
.text { color: green; } /* 0,0,1,0 → gewinnt */
#intro { color: red; } /* 0,1,0,0 → gewinnt über beide */
CSS Spezifität – Vertiefung
| Selektor | Inline | IDs | Klassen | Elemente | Gesamt |
|---|---|---|---|---|---|
p |
0 | 0 | 0 | 1 | 0,0,0,1 |
.info |
0 | 0 | 1 | 0 | 0,0,1,0 |
p.info |
0 | 0 | 1 | 1 | 0,0,1,1 |
#header |
0 | 1 | 0 | 0 | 0,1,0,0 |
#header .nav a |
0 | 1 | 1 | 1 | 0,1,1,1 |
Regeln:
- Eine Klasse (0,0,1,0) schlägt jede Anzahl Elemente (0,0,0,99)
- Eine ID schlägt jede Anzahl Klassen
!importantbricht alles → vermeiden
Best Practice: Flache Spezifität. BEM-Methodik (.block__element--modifier) hält sie niedrig.
Box-Modell
Jedes HTML-Element ist eine rechteckige Box.
Schichten innen → außen:
- content – Inhalt (Text, Bild)
- padding – Innenabstand
- border – Rahmen
- margin – Außenabstand
Gesamt-Breite = width + padding + border + margin. Tipp: box-sizing: border-box rechnet padding + border mit ein.
Box-Modell: CSS
.box {
width: 200px;
height: 100px;
padding: 20px;
border: 2px solid black;
margin: 10px;
}
Wichtig:
* {
box-sizing: border-box;
}
→ width/height inkludiert padding + border.
Farben
CSS kennt fünf Notationen für Farben: Keyword, Hex, RGB, RGBA (mit Transparenz) und HSL.
/* Keyword */
color: red;
color: rebeccapurple;
/* Hex */
color: #FF0000;
color: #F00;
/* RGB / RGBA */
color: rgb(255, 0, 0);
color: rgba(255, 0, 0, 0.5);
/* HSL */
color: hsl(0, 100%, 50%);
Einheiten
| Einheit | Bedeutung |
|---|---|
px |
Pixel (absolut) |
% |
Prozent vom Elternelement |
em |
Relativ zur Schriftgröße des Elements |
rem |
Relativ zur Schriftgröße des Root-Elements |
vw / vh |
Prozent der Viewport-Breite/-Höhe |
Empfehlung:
rem für Schrift, % oder vw/vh für Layout.
Pseudo-Klassen
/* Hover */
a:hover { color: red; }
/* Besuchter Link */
a:visited { color: purple; }
/* Fokussiertes Element */
input:focus { border-color: blue; }
/* Erstes/n-tes Kind */
li:first-child { font-weight: bold; }
li:nth-child(odd) { background: #eee; }
: vor dem Namen = Pseudo-Klasse.
Pseudo-Elemente
/* Vor dem Inhalt einfügen */
.required::before {
content: "* ";
color: red;
}
/* Erster Buchstabe */
p::first-letter {
font-size: 2em;
}
:: = Pseudo-Element (erzeugt "virtuelles" Element)
: = Pseudo-Klasse (wählt existierendes Element im Zustand)
Layout: Flexbox
.container {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
→ Eindimensionales Layout (Zeile oder Spalte). Tiefer in 02_css_extended.
Layout: Grid
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
→ Zweidimensionales Layout (Zeilen und Spalten gleichzeitig).
Responsive Design
/* Mobile First: Basis-Styles */
.container {
padding: 1rem;
}
/* Ab 768px (Tablet) */
@media (min-width: 768px) {
.container { padding: 2rem; }
}
/* Ab 1024px (Desktop) */
@media (min-width: 1024px) {
.container { padding: 3rem; }
}
Responsive Design – Vertiefung
Mobile First ist Standard: Basis-CSS für kleine Screens, dann Erweiterungen.
| Breakpoint | Gerät | Media Query |
|---|---|---|
| < 576px | Smartphone (Portrait) | Basis |
| ≥ 576px | Smartphone (Landscape) | @media (min-width: 576px) |
| ≥ 768px | Tablet | @media (min-width: 768px) |
| ≥ 992px | Desktop | @media (min-width: 992px) |
| ≥ 1200px | Large Desktop | @media (min-width: 1200px) |
Viewport-Meta-Tag (kritisch!):
<meta name="viewport" content="width=device-width, initial-scale=1">
Moderne Alternativen: clamp(), Container Queries, CSS Grid auto-fit/auto-fill.
JavaScript
JavaScript Grundlagen
// Variablen
let name = "Welt";
const alter = 25;
// Funktionen
function gruss(name) {
return `Hallo, ${name}!`;
}
// Arrow Functions
const add = (a, b) => a + b;
// Arrays
const arr = [1, 2, 3];
arr.map(x => x * 2); // [2, 4, 6]
DOM Manipulation
// Element auswählen
const title = document.querySelector('h1');
// Inhalt ändern
title.textContent = 'Neue Überschrift';
// Event Listener
button.addEventListener('click', () => {
alert('Geklickt!');
});
Fetch API
fetch('/api/products')
.then(res => res.json())
.then(data => {
console.log(data);
})
.catch(err => console.error(err));
Async/Await
async function loadProducts() {
try {
const res = await fetch('/api/products');
const data = await res.json();
return data;
} catch (err) {
console.error('Fehler:', err);
}
}
Web Engineering Mandala
Interaktive version: nextlevelshit.github.io/web-engineering-mandala
3 Schichten:
- Core Layer — JS, HTML, CSS (vanilla)
- Build Layer — bundlers, runtimes, template engines, pre/post processors
- Application Layer — frontend, backend, frameworks, SSR, CSS-utilities
3 Segmente: HTML (blau) · JavaScript (rot) · CSS (grün) · Mittelpunkt: package.json
JavaScript Frameworks – Kategorien
| Kategorie | Beispiele |
|---|---|
| CSS Frameworks | Tailwind, Bootstrap, shadcn/ui |
| Frontend Frameworks | React, Vue, Svelte, Astro |
| Rendering / Meta | Next.js, Nuxt, Gatsby |
| Build Tools / Bundler | Webpack, Vite, Parcel, esbuild |
| Backend Frameworks | Express, Fastify, NestJS |
Vanilla JS – Counter
<button id="myButton">Clicked 0 times</button>
<script>
let count = 0;
const btn = document.getElementById('myButton');
btn.addEventListener('click', () => {
count++;
btn.textContent = `Clicked ${count} times`;
});
</script>
✓ hohe Kompatibilität, simpel ✗ State-Management, Re-Rendering wird schnell komplex
React – Counter (JSX)
import { useState } from "react";
function MyButton() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Clicked {count} times
</button>
);
}
- Component-Based Architecture
- Virtual DOM, JSX, Hooks
- großes Ökosystem (React Router, Redux, …)
Vue 3 – Composition API
<script setup>
import { ref } from "vue";
const count = ref(0);
</script>
<template>
<button @click="count++">
Clicked {{ count }} times
</button>
</template>
- Reactive Data Binding
- Single-File Components (
.vue) - Vue Router, Pinia (State)
Svelte – Counter
<script>
let count = 0;
</script>
<button on:click={() => count += 1}>
Clicked {count} {count === 1 ? 'time' : 'times'}
</button>
- Compiler-Based – kein Runtime-Framework
- Reactive Assignments (
let) - Built-in Animationen
Astro – Content-First
---
const greeting = "Hallo DHBW";
---
<html>
<body>
<h1>{greeting}</h1>
<MyReactButton client:load />
</body>
</html>
- Islands Architecture – Komponenten mehrerer Frameworks mischen
- Default: kein JS im Output (nur statisches HTML)
- Hydration on demand (
client:load,client:visible)
Rendering Frameworks
| Frontend | SSR | SSG | File Routing | |
|---|---|---|---|---|
| Next.js | React | ✓ | ✓ | /app/page.js |
| Nuxt | Vue | ✓ | ✓ | /pages/*.vue |
| Gatsby | React | – | ✓ | GraphQL Data |
Build Tools – Webpack
- Module Bundling (JS, CSS, Images)
- Module Loaders + großes Plugin-Ökosystem
- Code Splitting, HMR
- Konfigurations-lastig (
webpack.config.js)
→ Standard für viele Legacy-Setups.
Build Tools – Vite
// vite.config.js
import { defineConfig } from "vite";
export default defineConfig({
server: {
proxy: {
"/api": {
target: "http://localhost:4567",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, "")
}
}
}
});
- Rollup unter der Haube, HMR mit ES Modules
- Tree-Shaking, Code Splitting, React + Vue out-of-the-box
Build Tools – Parcel
{
"name": "my-project",
"source": "src/index.html",
"browserslist": "> 0.5%, last 2 versions, not dead",
"scripts": {
"start": "parcel",
"build": "parcel build"
},
"devDependencies": {
"parcel": "latest"
}
}
- Zero-Config
- Auto-Resolution, HMR
- TS / CSS-Preprocessors out-of-the-box
Microfrontends
- Mehrere unabhängige Frontend-Apps in einer Page
- Module Federation (Webpack 5)
- single-spa: https://single-spa.js.org/
- Anwendungsfall: große Teams, unterschiedliche Tech-Stacks pro Domain
→ Komplexitätskosten: nur bei echtem Skalierungsbedarf.
Demo-Repos
- https://github.com/nextlevelshit/dhbw-client-js (Counter, multi-framework)
- https://github.com/nextlevelshit/node-cache-api (API + Tests)
- https://github.com/nextlevelshit/dhbw-docker (Compose-Stack)























