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:
@@ -22,8 +22,8 @@ DEPLOY_HOST = tengo@tuttle.uberspace.de
|
|||||||
223015c_DEPLOY = /home/tengo/html/hdm/223015c
|
223015c_DEPLOY = /home/tengo/html/hdm/223015c
|
||||||
223015c_KLAUSUR = 1
|
223015c_KLAUSUR = 1
|
||||||
|
|
||||||
dhbw_NAME = Technik I – Grundlagen IT
|
dhbw_NAME = Web Engineering
|
||||||
dhbw_KAPITEL = 01_web_eng 02_css_extended 03_nodejs_basics 04_nodejs_advanced 05_testing 06_typescript 07_docker 08_best_practices
|
dhbw_KAPITEL = 01_intro 02_html_css 03_js_frameworks 04_nodejs_basics 05_express 06_testing 07_typescript 08_docker 09_best_practices
|
||||||
dhbw_DEPLOY = /home/tengo/html/dhbw
|
dhbw_DEPLOY = /home/tengo/html/dhbw
|
||||||
dhbw_KLAUSUR =
|
dhbw_KLAUSUR =
|
||||||
|
|
||||||
|
|||||||
@@ -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