dhbw slides: 1 file pro sitzung (issue #2)
01_web_eng.md (103 slides) aufgesplittet: - 01_intro.md: cover, ueber-mich, vorlesungsplan, pruefungsleistung, internet 101, onboarding - 02_html_css.md: html, a11y/wcag, css basics + css extended (aus 02_css_extended.md gemergt) - 03_js_frameworks.md: ecmascript, js, dom, fetch, async, frameworks, build tools, microfrontends renames (03-08 -> 04-09): - 03_nodejs_basics -> 04_nodejs_basics - 04_nodejs_advanced -> 05_express - 05_testing -> 06_testing - 06_typescript -> 07_typescript - 07_docker -> 08_docker - 08_best_practices -> 09_best_practices 02_css_extended.md geloescht (inhalte in 02_html_css.md) makefile: dhbw_KAPITEL + dhbw_NAME aktualisiert
This commit is contained in:
@@ -0,0 +1,606 @@
|
||||
---
|
||||
marp: true
|
||||
theme: gaia
|
||||
paginate: true
|
||||
backgroundColor: #fff
|
||||
header: "Web Engineering – DHBW Stuttgart"
|
||||
footer: "Michael Czechowski – SoSe 2026"
|
||||
title: Intro
|
||||
---
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--color-foreground: #1a1a2e;
|
||||
--color-highlight: #d63384;
|
||||
--color-dimmed: #4a4a6a;
|
||||
}
|
||||
section.invert {
|
||||
--color-foreground: #fff;
|
||||
}
|
||||
section {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
h1 {
|
||||
color: #a02060;
|
||||
}
|
||||
section.invert h1 {
|
||||
color: #fff;
|
||||
}
|
||||
h2 {
|
||||
color: #1f2937;
|
||||
}
|
||||
section.invert h2 {
|
||||
color: #f48fb1;
|
||||
}
|
||||
pre {
|
||||
background: #0f0f23;
|
||||
color: #f48fb1;
|
||||
border-radius: 8px;
|
||||
border-left: 3px solid #d63384;
|
||||
}
|
||||
pre code {
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
code {
|
||||
background: #1a1a2e;
|
||||
color: #f48fb1;
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
}
|
||||
a {
|
||||
color: var(--color-highlight);
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- _class: invert -->
|
||||
<!-- _header: '' -->
|
||||
<!-- _backgroundColor: #000 -->
|
||||
|
||||

|
||||
|
||||
# Web Engineering
|
||||
|
||||
**DHBW Stuttgart** · Informatik / Wirtschaftsinformatik
|
||||
|
||||
**Sommersemester 2026**
|
||||
|
||||
---
|
||||
|
||||
# Ressourcen zum Selbstlernen
|
||||
|
||||
- **CODE CRISPIES** — [codecrispi.es](https://codecrispi.es/)
|
||||
- **Online Code-Editor** — [codepen.io](https://codepen.io/pen/)
|
||||
- **MDN** (Mozilla Developer Network) — [developer.mozilla.org/de/](https://developer.mozilla.org/de/)
|
||||
- **Flexbox-Spiel** — [flexboxfroggy.com](https://flexboxfroggy.com/)
|
||||
- **Grid-Spiel** — [cssgridgarden.com](https://cssgridgarden.com/)
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# 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
|
||||
|
||||
<style scoped>
|
||||
.lp-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 10px;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
.lp-card {
|
||||
border: 1px solid #d63384;
|
||||
border-radius: 8px;
|
||||
padding: 10px 12px;
|
||||
background: #fff;
|
||||
font-size: 0.95em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.lp-card .head {
|
||||
font-weight: bold;
|
||||
color: #a02060;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
.lp-card .head .num {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
.lp-card .topic {
|
||||
color: #1a1a2e;
|
||||
line-height: 1.25;
|
||||
}
|
||||
.lp-card.milestone {
|
||||
background: #fce4ec;
|
||||
border-color: #a02060;
|
||||
border-width: 2px;
|
||||
}
|
||||
.lp-card.milestone .topic {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="lp-grid">
|
||||
<div class="lp-card"><div class="head"><span class="num">1</span><span>08.05.</span></div><div class="topic">Intro · Projektgruppen · Internet 101</div></div>
|
||||
<div class="lp-card"><div class="head"><span class="num">2</span><span>15.05.</span></div><div class="topic">HTML und CSS (Frameworks)</div></div>
|
||||
<div class="lp-card"><div class="head"><span class="num">3</span><span>22.05.</span></div><div class="topic">JS (Frameworks) und npm</div></div>
|
||||
<div class="lp-card"><div class="head"><span class="num">4</span><span>29.05.</span></div><div class="topic">nodeJS: Scripting, Running, Building</div></div>
|
||||
<div class="lp-card"><div class="head"><span class="num">5</span><span>05.06.</span></div><div class="topic">Express API, CRUD, Middlewares</div></div>
|
||||
<div class="lp-card milestone"><div class="head"><span class="num">6</span><span>12.06.</span></div><div class="topic">Projektwerkstattbericht</div></div>
|
||||
<div class="lp-card"><div class="head"><span class="num">7</span><span>19.06.</span></div><div class="topic">Testing (Unit · Integration · E2E)</div></div>
|
||||
<div class="lp-card"><div class="head"><span class="num">8</span><span>26.06.</span></div><div class="topic">TypeScript</div></div>
|
||||
<div class="lp-card"><div class="head"><span class="num">9</span><span>03.07.</span></div><div class="topic">Docker · Proxies · DBs</div></div>
|
||||
<div class="lp-card"><div class="head"><span class="num">10</span><span>10.07.</span></div><div class="topic">Wrap-up & Projektsupport</div></div>
|
||||
<div class="lp-card milestone"><div class="head"><span class="num">11</span><span>17.07.</span></div><div class="topic">Präsentation</div></div>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
# Prüfungsleistung – Übersicht
|
||||
|
||||
Eigenes Projekt: **Web-App** ODER **Backend** (API/CLI).
|
||||
|
||||
| Punkte | Bereich |
|
||||
|--------|---------|
|
||||
| 30 | Grundanforderungen (Projektgrundlagen + Präsentation) |
|
||||
| 25 | Clean Code Prinzipien |
|
||||
| 25 | Accessibility & UX |
|
||||
| 20 | Technische Umsetzung |
|
||||
| **100** | **Basispunkte** |
|
||||
| +15 | Bonuspunkte (max. 3 Features a 5 P.) |
|
||||
|
||||
---
|
||||
|
||||
# Prüfungsleistung – Grundanforderungen (30 P.)
|
||||
|
||||
**Projektgrundlagen (15 P.)**
|
||||
- Funktionsfähige Anwendung (8 P.)
|
||||
- Repository mit Versionskontrolle (4 P.)
|
||||
- Projektdokumentation / README (3 P.)
|
||||
|
||||
**Präsentation (15 P.)**
|
||||
- Elevator Pitch (5 P.)
|
||||
- Technische Präsentation (5 P.)
|
||||
- Projektevolution: wie hat sich das Projekt vs. Ursprungsidee verändert? (5 P.)
|
||||
|
||||
---
|
||||
|
||||
# Prüfungsleistung – Clean Code (25 P.)
|
||||
|
||||
**Projektstruktur (10 P.)**
|
||||
- Ordnerstruktur (5 P.)
|
||||
- Datei-Organisation (5 P.)
|
||||
|
||||
**Code-Qualität (10 P.)**
|
||||
- KISS – Keep It Simple, Stupid (3 P.)
|
||||
- Beschreibende Namen (3 P.)
|
||||
- Funktionsverantwortlichkeiten (4 P.)
|
||||
|
||||
**Kommentierung & Dokumentation (5 P.)**
|
||||
|
||||
---
|
||||
|
||||
# Prüfungsleistung – Accessibility & UX (25 P.)
|
||||
|
||||
**Web Accessibility (15 P.)**
|
||||
- Semantisches HTML (5 P.)
|
||||
- ARIA Labels & Alt-Texte (5 P.)
|
||||
- Tastaturnavigation (5 P.)
|
||||
|
||||
**Responsive Design (10 P.)**
|
||||
- Mobile First Approach (5 P.)
|
||||
- Flexbox/Grid Layout (5 P.)
|
||||
|
||||
---
|
||||
|
||||
# Prüfungsleistung – Technische Umsetzung (20 P.)
|
||||
|
||||
- Plattformunabhängigkeit (5 P.)
|
||||
- Package Management (5 P.)
|
||||
- Build Tools & Optimierung (5 P.)
|
||||
- Live-Demo (5 P.)
|
||||
|
||||
---
|
||||
|
||||
# Prüfungsleistung – Bonuspunkte (max. 15 P.)
|
||||
|
||||
Mindestens 2 Bereiche wählen, je 5 Punkte:
|
||||
|
||||
- API Integration
|
||||
- Local Storage / State Management
|
||||
- Progressive Web App Features
|
||||
- Testing
|
||||
- Erweiterte Responsive Features (3+ Breakpoints)
|
||||
- Security Features
|
||||
|
||||
---
|
||||
|
||||
# Prüfungsleistung – Abgabe & Termine
|
||||
|
||||
- **Code-Upload:** bis 27.07.
|
||||
- **Präsentation:** 17.07. (Gruppen, ~10 Min.)
|
||||
|
||||
Details: https://git.librete.ch/DHBW/pruefungsleistung
|
||||
|
||||
---
|
||||
|
||||
# Internet-Timeline
|
||||
|
||||
| Jahr | Meilenstein |
|
||||
|------|-------------|
|
||||
| **1966** | ARPANET-Projekt startet (DARPA) |
|
||||
| **1969** | Erste Verbindung zwischen UCLA und Stanford |
|
||||
| **1974** | TCP/IP-Protokoll entwickelt |
|
||||
| **1989** | Tim Berners-Lee erfindet das WWW (CERN) |
|
||||
| **1993** | Mosaic — erster grafischer Browser |
|
||||
| **1994** | W3C gegründet (HTML, CSS, SVG, WCAG) |
|
||||
| **1995** | ECMAScript / JavaScript wird Standard |
|
||||
| **2008** | V8 JavaScript Engine (Chrome / Node.js) |
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
# Das WWW (1989)
|
||||
|
||||
**Tim Berners-Lee** am **CERN** (Genf)
|
||||
|
||||
**Problem:** Wissenschaftler:innen können Forschungsdokumente nicht verlinken — Inkompatible Systeme, kein gemeinsames Format.
|
||||
|
||||
**Lösung — drei Bausteine:**
|
||||
|
||||
- **HTML** — Auszeichnungssprache für Dokumente
|
||||
- **HTTP** — Protokoll zur Übertragung
|
||||
- **URL** — eindeutige Adressen
|
||||
|
||||
**1991:** erste Webseite geht online · 1993 vom CERN gemeinfrei freigegeben.
|
||||
|
||||
→ WWW ≠ Internet. Das WWW ist eine **Anwendung auf** dem Internet.
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
# Heute: Physische Infrastruktur
|
||||
|
||||
- **5,5 Milliarden** Menschen online
|
||||
- **> 400 Unterseekabel**, ca. **1,3 Mio. km** Glasfaser
|
||||
- Daten reisen mit **Lichtgeschwindigkeit**
|
||||
- Latenz Frankfurt — New York: ~80 ms
|
||||
|
||||
→ Keine "Cloud" ohne Kabel. Das Internet ist **physische** Infrastruktur — und damit angreifbar.
|
||||
|
||||
**Geopolitik:** Five-Eyes-Allianz (USA, UK, CA, AU, NZ) zapft Unterseekabel ab (Programm "Tempora", aufgedeckt 2013 durch Snowden). DE ist Teil der Fourteen Eyes.
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
|
||||

|
||||
|
||||
|
||||
---
|
||||
|
||||
# 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"}, ...]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: invert -->
|
||||
<!-- _header: '' -->
|
||||
<!-- _backgroundColor: #000 -->
|
||||
|
||||
# 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](https://brew.sh)**
|
||||
|
||||
```bash
|
||||
# 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](https://nodejs.org)
|
||||
|
||||
---
|
||||
|
||||
# Node.js installieren – Linux
|
||||
|
||||
Empfohlen: **LTS** (aktuell **Node.js 24**).
|
||||
|
||||
**Debian / Ubuntu** ([NodeSource](https://github.com/nodesource/distributions)):
|
||||
```bash
|
||||
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
```
|
||||
|
||||
**Arch / Manjaro:**
|
||||
```bash
|
||||
sudo pacman -S nodejs npm
|
||||
```
|
||||
|
||||
**Fedora / RHEL:**
|
||||
```bash
|
||||
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):
|
||||
```powershell
|
||||
winget install OpenJS.NodeJS.LTS
|
||||
```
|
||||
|
||||
**Option 2: Chocolatey** ([chocolatey.org](https://chocolatey.org)):
|
||||
```powershell
|
||||
choco install nodejs-lts
|
||||
```
|
||||
|
||||
**Option 3: Scoop** ([scoop.sh](https://scoop.sh)):
|
||||
```powershell
|
||||
scoop install nodejs-lts
|
||||
```
|
||||
|
||||
**Option 4:** Installer von [nodejs.org](https://nodejs.org)
|
||||
|
||||
→ **Empfehlung:** WSL2 + Linux-Workflow nutzen.
|
||||
|
||||
---
|
||||
|
||||
# Direkt-Install: Wenn es eng wird
|
||||
|
||||
**Typisches Szenario** — 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 → Konflikt.
|
||||
|
||||
---
|
||||
|
||||
# Symptome im Alltag
|
||||
|
||||
- `npm install` bricht mit `engines`-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 |
|
||||
|
||||
```bash
|
||||
# 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 |
|
||||
|
||||
```bash
|
||||
# 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](https://www.jetbrains.com/community/education/#students)
|
||||
- **Vim / Neovim / Emacs** — für CLI-Profis
|
||||
- **Zed** — modern, schnell
|
||||
|
||||
---
|
||||
|
||||
# Browser DevTools
|
||||
|
||||
Chromium / Firefox / Safari — `F12` oder `Cmd+Opt+I`
|
||||
|
||||
<small>Chromium = Open-Source-Basis von Chrome, Edge, Brave, Opera, Vivaldi etc.</small>
|
||||
|
||||
**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](https://usebruno.com)) — open source, git-friendly
|
||||
- **Hoppscotch** ([hoppscotch.io](https://hoppscotch.io)) — open source, browser-basiert (vormals Postwoman)
|
||||
- **Insomnia** / **Postman** — etabliert, freemium
|
||||
- **curl** / **httpie** — CLI (Command-Line Interface, scriptbar)
|
||||
|
||||
---
|
||||
|
||||
# Git Setup & Workflow
|
||||
|
||||
**Einmalige Konfiguration:**
|
||||
```bash
|
||||
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:**
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -C "vorname.nachname@example.com"
|
||||
cat ~/.ssh/id_ed25519.pub # → in GitHub-Settings einfügen
|
||||
```
|
||||
|
||||
**Tägliche Befehle:**
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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:**
|
||||
```json
|
||||
{
|
||||
"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.
|
||||
|
||||
---
|
||||
@@ -1,292 +0,0 @@
|
||||
---
|
||||
marp: true
|
||||
theme: gaia
|
||||
paginate: true
|
||||
backgroundColor: #fff
|
||||
header: "Web Engineering – DHBW Stuttgart"
|
||||
footer: "Michael Czechowski – SoSe 2026"
|
||||
---
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--color-foreground: #1a1a2e;
|
||||
--color-highlight: #d63384;
|
||||
--color-dimmed: #4a4a6a;
|
||||
}
|
||||
section.invert {
|
||||
--color-foreground: #fff;
|
||||
}
|
||||
section {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
h1 {
|
||||
color: #a02060;
|
||||
}
|
||||
section.invert h1 {
|
||||
color: #fff;
|
||||
}
|
||||
h2 {
|
||||
color: #1f2937;
|
||||
}
|
||||
section.invert h2 {
|
||||
color: #f48fb1;
|
||||
}
|
||||
pre {
|
||||
background: #0f0f23;
|
||||
color: #f48fb1;
|
||||
border-radius: 8px;
|
||||
border-left: 3px solid #d63384;
|
||||
}
|
||||
pre code {
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
code {
|
||||
background: #1a1a2e;
|
||||
color: #f48fb1;
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
}
|
||||
a {
|
||||
color: var(--color-highlight);
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- _class: invert -->
|
||||
<!-- _header: '' -->
|
||||
<!-- _backgroundColor: #000 -->
|
||||
|
||||
# Web Engineering
|
||||
|
||||
**DHBW Stuttgart** · Informatik / Wirtschaftsinformatik
|
||||
|
||||
**Sommersemester 2026** · Sitzung 2 — HTML & CSS (Frameworks)
|
||||
|
||||
---
|
||||
|
||||
# Ressourcen zum Selbstlernen
|
||||
|
||||
- **CODE CRISPIES** — [codecrispi.es](https://codecrispi.es/)
|
||||
- **Online Code-Editor** — [codepen.io](https://codepen.io/pen/)
|
||||
- **MDN** (Mozilla Developer Network) — [developer.mozilla.org/de/](https://developer.mozilla.org/de/)
|
||||
- **Flexbox-Spiel** — [flexboxfroggy.com](https://flexboxfroggy.com/)
|
||||
- **Grid-Spiel** — [cssgridgarden.com](https://cssgridgarden.com/)
|
||||
|
||||
---
|
||||
|
||||
# Inhalt
|
||||
|
||||
Aufbauend auf den Grundlagen aus Sitzung 1.
|
||||
|
||||
1. Attribut-Selektoren
|
||||
2. Combinators (vertieft)
|
||||
3. Pseudo-Klassen — erweitert
|
||||
4. Shorthand Properties
|
||||
5. Flexbox-Shorthands
|
||||
6. Custom Properties (Variables)
|
||||
7. CSS Functions (`calc`, `clamp`, ...)
|
||||
8. Transition & Animation
|
||||
9. CSS Frameworks (Tailwind & Co.)
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: invert -->
|
||||
<!-- _backgroundColor: #000 -->
|
||||
|
||||
# CSS: Extended
|
||||
|
||||
---
|
||||
|
||||
# CSS Selectors – Attribut-Selektoren
|
||||
|
||||
```css
|
||||
/* presence */
|
||||
[disabled] { opacity: 0.5; }
|
||||
|
||||
/* exact value */
|
||||
[type="email"] { border-color: blue; }
|
||||
|
||||
/* contains word */
|
||||
[class~="btn"] { cursor: pointer; }
|
||||
|
||||
/* starts with */
|
||||
[href^="https"] { color: green; }
|
||||
|
||||
/* ends with */
|
||||
[src$=".png"] { border: 1px solid #ccc; }
|
||||
|
||||
/* contains substring */
|
||||
[class*="icon"] { padding-left: 20px; }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# CSS Combinators
|
||||
|
||||
```css
|
||||
/* Child (direkt) */
|
||||
div > p { margin: 0; }
|
||||
|
||||
/* Descendant (Nachkomme) */
|
||||
div p { margin: 0; }
|
||||
|
||||
/* Next Sibling */
|
||||
h1 + p { font-size: 1.2em; }
|
||||
|
||||
/* Subsequent Sibling */
|
||||
h1 ~ p { color: #666; }
|
||||
|
||||
/* Selector List */
|
||||
h1, h2, h3 { font-weight: bold; }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Pseudo Classes – Erweitert
|
||||
|
||||
```css
|
||||
/* Form States */
|
||||
:valid { border-color: green; }
|
||||
:invalid { border-color: red; }
|
||||
:placeholder-shown { color: #999; }
|
||||
|
||||
/* Content */
|
||||
:before { content: "→ "; }
|
||||
:after { content: " [Wichtig]"; }
|
||||
:first-letter { font-size: 2em; }
|
||||
:first-line { font-weight: bold; }
|
||||
|
||||
/* NOT */
|
||||
:not(.disabled) { pointer-events: auto; }
|
||||
:not(:last-child) { border-bottom: 1px solid #ccc; }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Shorthand Properties
|
||||
|
||||
```css
|
||||
/* margin: top right bottom left */
|
||||
margin: 10px 20px 10px 20px;
|
||||
|
||||
/* centering */
|
||||
margin: 0 auto;
|
||||
|
||||
/* padding same */
|
||||
padding: 20px;
|
||||
|
||||
/* border: width style color */
|
||||
border: 1px solid #333;
|
||||
|
||||
/* background: color image position/size repeat */
|
||||
background: #fff url(logo.png) 0 0 no-repeat;
|
||||
|
||||
/* font: style variant weight size/line-height family */
|
||||
font: italic normal bold 16px/1.5 Arial, sans-serif;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Flexbox Shorthands
|
||||
|
||||
```css
|
||||
/* flex: grow shrink basis */
|
||||
flex: 1 0 auto;
|
||||
|
||||
/* place-items: align-items justify-items */
|
||||
place-items: center stretch;
|
||||
|
||||
/* place-content: align-content justify-content */
|
||||
place-content: space-between center;
|
||||
|
||||
/* gap: row-gap column-gap */
|
||||
gap: 20px 40px;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# CSS Custom Properties (Variables)
|
||||
|
||||
```css
|
||||
:root {
|
||||
--primary-color: #d63384;
|
||||
--spacing: 20px;
|
||||
--radius: 8px;
|
||||
}
|
||||
|
||||
.button {
|
||||
background: var(--primary-color);
|
||||
padding: var(--spacing);
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# CSS Functions
|
||||
|
||||
```css
|
||||
/* calc */
|
||||
width: calc(100% - 40px);
|
||||
|
||||
/* min/max/clamp */
|
||||
width: min(100%, 600px);
|
||||
font-size: clamp(14px, 2vw, 20px);
|
||||
|
||||
/* var with fallback */
|
||||
color: var(--text-color, #333);
|
||||
|
||||
/* rgb/rgba/hsl/hsla */
|
||||
color: hsl(200, 100%, 50%);
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Transition & Animation
|
||||
|
||||
```css
|
||||
/* transition: property duration timing-function */
|
||||
transition: all 0.3s ease-in-out;
|
||||
transition: background 0.2s, transform 0.1s;
|
||||
|
||||
/* animation */
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeIn 0.5s ease-out;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# CSS Frameworks
|
||||
|
||||
| Framework | Stil |
|
||||
|-----------|------|
|
||||
| **Bootstrap** | Komponenten + Grid, opinionated |
|
||||
| **Tailwind CSS** | Utility-First, atomar |
|
||||
| **Bulma** | klassisch, ohne JS |
|
||||
| **shadcn/ui** | kopierbare Komponenten (Tailwind-basiert) |
|
||||
| **Flowbite** | Tailwind-Komponentenbib. |
|
||||
|
||||
---
|
||||
|
||||
# Tailwind CSS – Beispiel
|
||||
|
||||
```html
|
||||
<button class="bg-blue-600 hover:bg-blue-700
|
||||
text-white font-semibold
|
||||
px-4 py-2 rounded-lg
|
||||
transition shadow-sm">
|
||||
Klick mich
|
||||
</button>
|
||||
```
|
||||
|
||||
- Keine eigenen CSS-Klassen mehr
|
||||
- JIT-Compiler erzeugt nur genutzte Klassen
|
||||
- Design-System via `tailwind.config.js`
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,403 @@
|
||||
---
|
||||
marp: true
|
||||
theme: gaia
|
||||
paginate: true
|
||||
backgroundColor: #fff
|
||||
header: "Web Engineering – DHBW Stuttgart"
|
||||
footer: "Michael Czechowski – SoSe 2026"
|
||||
title: JavaScript & Frameworks
|
||||
---
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--color-foreground: #1a1a2e;
|
||||
--color-highlight: #d63384;
|
||||
--color-dimmed: #4a4a6a;
|
||||
}
|
||||
section.invert {
|
||||
--color-foreground: #fff;
|
||||
}
|
||||
section {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
h1 {
|
||||
color: #a02060;
|
||||
}
|
||||
section.invert h1 {
|
||||
color: #fff;
|
||||
}
|
||||
h2 {
|
||||
color: #1f2937;
|
||||
}
|
||||
section.invert h2 {
|
||||
color: #f48fb1;
|
||||
}
|
||||
pre {
|
||||
background: #0f0f23;
|
||||
color: #f48fb1;
|
||||
border-radius: 8px;
|
||||
border-left: 3px solid #d63384;
|
||||
}
|
||||
pre code {
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
code {
|
||||
background: #1a1a2e;
|
||||
color: #f48fb1;
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: 4px;
|
||||
}
|
||||
a {
|
||||
color: var(--color-highlight);
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- _class: invert -->
|
||||
<!-- _header: '' -->
|
||||
<!-- _backgroundColor: #000 -->
|
||||
|
||||

|
||||
|
||||
# Web Engineering
|
||||
|
||||
**DHBW Stuttgart** · Informatik / Wirtschaftsinformatik
|
||||
|
||||
**Sommersemester 2026** · Sitzung 3 — JS, Frameworks & Build Tools
|
||||
|
||||
---
|
||||
|
||||
# Ressourcen zum Selbstlernen
|
||||
|
||||
- **CODE CRISPIES** — [codecrispi.es](https://codecrispi.es/)
|
||||
- **Online Code-Editor** — [codepen.io](https://codepen.io/pen/)
|
||||
- **MDN** (Mozilla Developer Network) — [developer.mozilla.org/de/](https://developer.mozilla.org/de/)
|
||||
- **Flexbox-Spiel** — [flexboxfroggy.com](https://flexboxfroggy.com/)
|
||||
- **Grid-Spiel** — [cssgridgarden.com](https://cssgridgarden.com/)
|
||||
|
||||
|
||||
<!-- _class: invert -->
|
||||
<!-- _header: '' -->
|
||||
<!-- _backgroundColor: #000 -->
|
||||
|
||||
# JavaScript
|
||||
|
||||
---
|
||||
|
||||
# ECMAScript
|
||||
|
||||
- **Ecma International** — European Computer Manufacturers Association
|
||||
- Seit **1997** standardisiert als **ECMA-262**
|
||||
- Implementierungen: **JavaScript** (Netscape, später Mozilla), **JScript** (Microsoft), **ActionScript** (Adobe Flash) etc.
|
||||
- Aktuelle Version: **ECMAScript 2024 (ES15)**, jährliche Releases
|
||||
|
||||
**Browser-Kompatibilität:**
|
||||
- Faustregel: **ES2017+** läuft in allen modernen Browsern
|
||||
- Ältere Targets via Transpiler (Babel, esbuild, swc, tsc)
|
||||
- Kompatibilitätstabelle: [kangax.github.io/compat-table](https://kangax.github.io/compat-table/)
|
||||
|
||||
---
|
||||
|
||||
# JavaScript Grundlagen
|
||||
|
||||
```javascript
|
||||
// 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
|
||||
|
||||
```javascript
|
||||
// Element auswählen
|
||||
const title = document.querySelector('h1');
|
||||
|
||||
// Inhalt ändern
|
||||
title.textContent = 'Neue Überschrift';
|
||||
|
||||
// Event Listener
|
||||
button.addEventListener('click', () => {
|
||||
alert('Geklickt!');
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Fetch API
|
||||
|
||||
```javascript
|
||||
fetch('/api/products')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
console.log(data);
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Async/Await
|
||||
|
||||
```javascript
|
||||
async function loadProducts() {
|
||||
try {
|
||||
const res = await fetch('/api/products');
|
||||
const data = await res.json();
|
||||
return data;
|
||||
} catch (err) {
|
||||
console.error('Fehler:', err);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<!-- _header: '' -->
|
||||
<!-- _footer: '' -->
|
||||
<!-- _backgroundColor: #050517 -->
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
<!-- _backgroundColor: #050517 -->
|
||||
<!-- _color: #e2e8f0 -->
|
||||
|
||||
# Web Engineering Mandala
|
||||
|
||||
Interaktive version: [nextlevelshit.github.io/web-engineering-mandala](https://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
|
||||
|
||||
```html
|
||||
<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>
|
||||
```
|
||||
|
||||
**Pro:** hohe Kompatibilität, simpel
|
||||
**Contra:** State-Management und Re-Rendering werden schnell komplex
|
||||
|
||||
---
|
||||
|
||||
# React – Counter (JSX)
|
||||
|
||||

|
||||
|
||||
```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
|
||||
|
||||

|
||||
|
||||
```vue
|
||||
<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
|
||||
|
||||

|
||||
|
||||
```svelte
|
||||
<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
|
||||
|
||||

|
||||
|
||||
```astro
|
||||
---
|
||||
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 | ja | ja | `/app/page.js` |
|
||||
| **Nuxt** | Vue | ja | ja | `/pages/*.vue` |
|
||||
| **Gatsby** | React | nein | ja | 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
|
||||
|
||||

|
||||
|
||||
```javascript
|
||||
// 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
|
||||
|
||||

|
||||
|
||||
```json
|
||||
{
|
||||
"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)
|
||||
|
||||
Reference in New Issue
Block a user