per user-feedback nach QA-render-check aller 493 folien (overflow-detector via PIL bottom-band-darkness): 223015b/01-daten-grundlagen s.036 nyquist: H1 'Nyquist-Theorem — warum 2× reicht' → 'Nyquist — warum 2× reicht' body text gekürzt, drei fälle als * statt - (marp fragmented list) 223015b/03-inhalte-bild-audio-video s.009 RGB→Y'CbCr: H1 verkürzt, bg right 50% → 45% contain, list-marker * (Y/Cb/Cr reveal) text 'unabhängig komprimiert werden' eingedampft 223015b/03-inhalte-bild-audio-video s.031 inter-frame: H1 'Inter-Frame-Kompression — die zentrale Idee' → 'Inter-Frame — die zentrale Idee' bg right 42% → 40% contain bullets I/P/B mit * (fragmented reveal) 223015b/05-distribution-metadaten s.012 EXIF-tabelle: 8 zeilen → 5 zeilen (kamera+linse zusammengelegt, belichtung kompakt, software+bearbeitung zusammengelegt) 223015b/05-distribution-metadaten s.014 EXIF-stripping: 7 plattform-zeilen → 5 (facebook+iMessage und E-mail+slack+discord zusammen) faustregel als italic-zeile statt bold-block 223015c/01-geschichte-grundlagen-html s.006 alan turing: bg right 35% (default fill) → 33% contain (verhindert dass composite-bild bis footer reicht) 3 jahres-zeilen als * bullets (fragmented reveal) dhbw/01_web_eng s.054 counter: in 2 folien gesplittet: 'Counter — Vanilla + React' und 'Counter — Vue + Svelte' pointe 'vier frameworks, dasselbe pattern: state → UI re-rendert' am ende der 2. folie dhbw/08_best_practices s.005 .gitignore: code-block gekürzt: 6 sektionen → 5, mehrere lines pro logical group zusammengezogen (pem+key zusammen, vscode+idea zusammen) github.com/github/gitignore als markdown-link bonus: wo pädagogisch sinnvoll - durch * ersetzt (marp progressive-reveal in presenter-modus). nicht überall — nur wo bullets sequenziell aufgedeckt werden sollten. klausurfolien regeneriert (223015b 27, 223015c 19)
9.2 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 | Best Practices |
Kapitel 8 — Best Practices
Git · README · SOLID · 12-Factor · SemVer
Git-Hygiene
Sinnvolle Commits
Schlecht:
fix
wip
asdf
final
final2
final-final
Gut:
fix(auth): handle expired JWT correctly
feat(api): add /users/:id/posts endpoint
docs(readme): update Docker setup instructions
test(utils): cover edge cases in greet()
Eine Commit-Message = Was + Warum, nicht Wie.
Conventional Commits
<type>(<scope>): <subject>
[optional body]
[optional footer]
Types:
feat:neue Funktionfix:Bugfixdocs:Dokurefactor:Code-Restrukturierungtest:Testschore:Build/Toolsperf:Performancestyle:Formatierung
Automatisches Changelog + SemVer-Bump möglich.
.gitignore — was nie rein gehört
# Dependencies + Build
node_modules/
dist/
build/
.cache/
# Secrets
.env
.env.local
*.pem *.key
# Editor + OS
.vscode/ .idea/
.DS_Store
# Logs
*.log
Vorlagen: github.com/github/gitignore
Branches + PRs
# Neuer Feature-Branch
git checkout -b feat/user-profile
# Arbeit, Commits
git add .
git commit -m "feat(profile): add avatar upload"
# Push + PR
git push -u origin feat/user-profile
# → PR via GitHub/Gitea-UI
# Nach Merge: aufräumen
git checkout main
git pull
git branch -d feat/user-profile
Faustregel: kurzlebige Branches (Tage, nicht Monate).
README
README — das Visitenkarten-Dokument
Wenn jemand euer Projekt im Browser sieht: die README ist die erste und oft einzige Berührung.
Schlechte README = Repo nicht verwendet.
Eine gute README beantwortet:
- Was tut das Projekt?
- Wie installiere ich es?
- Wie starte ich es?
- Wie teste ich es?
- Wie deploye ich es?
- Lizenz?
README-Template
# Mein Projekt
> Eine Zeile Beschreibung.
## Features
- ✓ etwas
- ✓ etwas anderes
## Setup
```sh
git clone https://...
cd projekt
cp .env.example .env
npm install
npm run dev
Tests
npm test
npm run test:e2e
Stack
Node 24, Express, SQLite, Vitest.
License
MIT
---
<!-- _class: lead -->
# SOLID — OO-Prinzipien
---
# SOLID — die fünf
| | Prinzip | Bedeutung |
|--|---------|-----------|
| **S** | Single Responsibility | jede Klasse/Modul = eine Verantwortung |
| **O** | Open / Closed | offen für Erweiterung, geschlossen für Änderung |
| **L** | Liskov Substitution | Subtyp ersetzbar durch Basistyp |
| **I** | Interface Segregation | kleine, fokussierte Interfaces |
| **D** | Dependency Inversion | abhängig von Abstraktionen |
Robert C. Martin („Uncle Bob"), 2000er.
---
# S — Single Responsibility
```javascript
// Schlecht — alles in einer Klasse
class UserManager {
validate() { /* ... */ }
saveToDb() { /* ... */ }
sendEmail() { /* ... */ }
generateReport() { /* ... */ }
}
// Besser — getrennte Verantwortlichkeiten
class UserValidator { /* ... */ }
class UserRepository { /* ... */ }
class EmailService { /* ... */ }
class ReportGenerator { /* ... */ }
D — Dependency Inversion
// Schlecht — direkt von konkreter Klasse
class OrderService {
charge(order) {
const stripe = new StripeClient();
stripe.charge(order.amount);
}
}
// Besser — Abhängigkeit injizieren
class OrderService {
constructor(paymentProvider) {
this.payment = paymentProvider;
}
charge(order) {
this.payment.charge(order.amount);
}
}
new OrderService(new StripeClient()); // im Production
new OrderService(new MockClient()); // im Test
12-Factor App
12-Factor — die wichtigsten
| # | Faktor | Was |
|---|---|---|
| 1 | Codebase | ein Repo pro App, mehrere Deploys |
| 2 | Dependencies | explizit deklariert (package.json) |
| 3 | Config | über Environment Variables, nicht im Code |
| 4 | Backing Services | als Resources behandeln (z.B. DB-URL) |
| 6 | Processes | stateless |
| 9 | Disposability | schnell startbar + stoppbar |
| 12 | Admin Processes | als One-Off im selben Stack |
Heroku, 2011. Heute Industrie-Standard für Cloud-Apps.
Factor 3 — Config in env
// SCHLECHT — Hardcoded
const db = new Pool({ host: 'localhost', user: 'dev' });
// GUT — aus env
const db = new Pool({
connectionString: process.env.DATABASE_URL,
});
.env lokal, Environment-Variablen auf Server. Gleicher Code überall.
Factor 6 — Stateless Processes
Schlecht: Session-State im RAM.
const sessions = new Map(); // pro Server-Instanz!
→ Load-Balancer mit 2 Servern: User-Session geht verloren beim 2. Request.
Gut: State in DB / Redis.
await redis.set(`session:${id}`, JSON.stringify(data));
Server-Restart → kein Datenverlust. Horizontale Skalierung möglich.
SemVer — semantisches Versioning
SemVer — Format
MAJOR.MINOR.PATCH
1 . 4 . 3
| Teil | Bump bei |
|---|---|
| MAJOR | breaking change (API-incompatible) |
| MINOR | neues Feature (rückwärts-kompatibel) |
| PATCH | Bugfix (rückwärts-kompatibel) |
Pre-Release: 1.0.0-beta.1, 1.0.0-rc.2.
SemVer in package.json
{
"dependencies": {
"express": "^5.0.0", // ≥ 5.0.0, < 6.0.0
"lodash": "~4.17.0", // ≥ 4.17.0, < 4.18.0
"react": "5.2.1", // exakt
"vite": "*" // jede (vermeiden)
}
}
Faustregel: ^ (Caret) ist Default — major-version-lock.
Code-Reviews
Constructive Code-Reviews
Geben:
- Konkret: Zeilennummern + Beispiel
- Wertschätzend: gut gemachte Stellen erwähnen
- Fragend statt fordernd: „Wäre
Xhier robuster?" - Klar zwischen MUST/SHOULD/CONSIDER unterscheiden
Nehmen:
- Egoless: Code ≠ Person
- Frage zurück bei Unklarheit
- Bedanken für detaillierte Feedback
Code-Review-Checkliste
| Bereich | Was prüfen |
|---|---|
| Correctness | macht's, was es soll? Edge-cases? |
| Readability | Namen, Struktur, Kommentare? |
| Tests | abgedeckt? Sinnvolle Assertions? |
| Security | Input-Validation, Secrets, Auth |
| Performance | N+1, Sync-IO, Memory-Leak |
| A11y (Frontend) | Semantik, Kontrast, Keyboard |
| Doku | README aktualisiert? CHANGELOG? |
Doku lesen lernen
Wo finde ich was?
| Ziel | Quelle |
|---|---|
| Web-APIs (HTML, CSS, JS) | MDN — developer.mozilla.org |
| Node-APIs | nodejs.org/docs |
| npm-Package | npmjs.com/package/<name> + GitHub README |
| Sprach-Standards (ES) | tc39.es |
| Browser-Kompatibilität | caniuse.com |
| Fehler-Suche | Stack Overflow + GitHub Issues |
Faustregel: offizielle Doku zuerst, dann Stack Overflow.
Stack Overflow gut nutzen
Bevor du fragst:
- Existiert die Frage schon? (Suche oben)
- Gibt es ein Minimal-Reproduction-Beispiel?
- Welche Versionen (Node, OS, Library)?
- Was hast du schon versucht?
Bei der Frage:
- Konkreter Titel (nicht "JavaScript Hilfe")
- Code-Block für Code
- Was war erwartet, was passiert
- Error-Message als Text (nicht Screenshot)
AI-Assistenten (ChatGPT, Claude, Copilot)
Pro:
- Schneller Antworten zu allgemeinen Fragen
- Boilerplate-Code in Sekunden
- Erklärung fremden Codes
Contra:
- Halluziniert APIs, die nicht existieren
- Verstärkt Anti-Patterns aus dem Training
- Lernkurve geht zurück, wenn nur kopiert wird
Faustregel: als Sparring-Partner, nicht als Wahrheitsquelle. Verstehen, nicht kopieren.
Selbstlernen — Projekt-Hygiene-Check
Geht euer Projekt durch:
- README: hat alle 6 Sektionen?
- .gitignore: komplett, keine Secrets im Repo?
- Conventional Commits: letzte 10 Commits durchgehen
- package.json:
version,description,scripts? - Tests: Coverage > 70 %?
- Dockerfile + compose.yml: funktionieren?
- Environment:
.env.examplevorhanden,.envgitignored?
Bonus: GitHub-Actions-Workflow für Tests + Build.
Abschluss
Über 8 Termine gelernt:
- Web Engineering — Foundation
- CSS Extended — Layout + Animation
- Node.js Basics — Runtime + REST
- Node.js Advanced — async + DB + Auth
- Testing — Unit + Integration + E2E
- TypeScript — Typen + Schemas
- Docker — Container + compose
- Best Practices — Git + README + SOLID + 12-Factor
Nächste Schritte: eigenes Projekt für die Prüfungsleistung. Code-Abgabe + Präsentation.