Files
uni/slides/dhbw/08_best_practices.md
T
libretech 4053185e74 dhbw phase 4: alle 8 kapitel slide-MD komplett (4176 zeilen → ~1100 zeilen, ~210 slides total)
kap1 web_eng (104 → 57 slides): kurs-intro + prüfungsleistung-übersicht, internet-timeline (4 milestones), URL→pixel-7-schritte, HTTP, onboarding (node 24 LTS via fnm, brew/winget paket-manager, VS Code/Chromium/Hoppscotch, git setup mit SSH-key, projekt-skeleton), HTML (anatomie, self-closing, grundgerüst, semantik-tabelle, native elemente details/dialog/input-types), A11y volle tiefe (BFSG+EAA 28.06.2025, WCAG-POUR, Perceivable/Operable/Understandable/Robust einzeln mit code, testen mit lighthouse/axe/manuell), CSS-vorschau (anatomie/selektoren/spezifizität/box-model/farben/einheiten/pseudos), JS-vorschau (ECMAScript-timeline/grundlagen/DOM/fetch), frameworks-übersicht (react/vue/svelte/astro counter-vergleich), build-tools/rendering-modi, selbstlernen erste-eigene-seite

kap2 css_extended (13 → 28 slides): box-model + box-sizing global, flexbox basics+achsen+item-properties+typische-patterns, grid basics+areas+auto-layout, flexbox-vs-grid tabelle, mobile-first media queries, viewport-meta, fluid sizing mit clamp(), transitions (was performant), keyframe-animationen, prefers-reduced-motion pflicht, CSS-variablen + dark-mode-pattern, CSS functions (calc/clamp/gradient/oklch/filter), CSS-frameworks tabelle + tailwind pro/contra, selbstlernen flexboxfroggy+cssgridgarden

kap3 nodejs_basics (~22 → 20 slides): was-ist-node + warum-node-tabelle, fnm versions-manager + node 24 LTS + .nvmrc, npm init + package.json (mit type:module), ESM modern + CJS legacy, built-in modules (node: prefix), HTTP-server eingebaut + express, REST mit express (GET/POST/PUT/DELETE-pattern), alternative frameworks tabelle (fastify/hono/koa), routing-pattern mit Router, fetch global ab node 18, error-handling res.ok, environment variables mit dotenv + niemals committen, selbstlernen mini-API

kap4 nodejs_advanced (~24 → 22 slides): synchron-vs-asynchron, promise then-vs-async/await, sequenziell-vs-parallel + Promise.all, promise-methoden tabelle (all/allSettled/race/any), fs/promises lesen+schreiben, streams pipeline für große dateien, DB-übersicht SQLite/Postgres/MongoDB/Redis, better-sqlite3 prepared statements, ORM-übersicht (drizzle/prisma/knex), CRUD-pattern express+sqlite, auth-strategien tabelle, bcrypt für passwörter, JWT-pattern mit httpOnly+secure cookie, try/catch + error-klassen, globaler express-error-handler, selbstlernen REST+DB+auth

kap5 testing (~23 → 23 slides): test-pyramide 70%/20%/10%, vitest setup + describe/it/expect, AAA-pattern, matchers tabelle, TDD red-green-refactor mit konkretem beispiel, supertest für API-integration, test-DB :memory: + lifecycle hooks, mocking mit vi.spyOn (sparsam), playwright E2E mit role-based-locators, E2E-vs-unit tradeoffs, coverage realistisch (80% gut), CI mit github-actions, selbstlernen tests-schreiben

kap6 typescript (~30 → 19 slides): was-ist-TS + warum-tabelle, setup mit tsx + tsconfig.json + strict:true, basis-typen + any vermeiden, object-typen + interfaces + type-aliases, function-typen (Promise<T>), union + discriminated union + intersection, generics + constraints, built-in generics (Partial/Omit/Record), typ-inference (nicht über-annotieren), typen für REST-API mit express, zod runtime-validation + z.infer, any-vs-unknown-vs-never, best practices, selbstlernen API-zu-TS-migration

kap7 docker (~24 → 24 slides): auf-meinem-rechner-läufts problem, container-vs-VM tabelle, docker basics (image/container/dockerfile/registry), dockerfile hallo-welt, schichten + cache-optimierung, multi-stage build, base-image-größen tabelle (alpine ~180MB vs node ~1.1GB), .dockerignore, compose.yml beispiel, compose-commands, networking (service-namen als hostnamen), volumes (named vs bind), env+secrets, github-actions docker-build, registry-übersicht, health-checks, best-practices, selbstlernen app-dockerizen

kap8 best_practices (~30 → 28 slides): sinnvolle commits + conventional commits format, .gitignore template, branches+PRs workflow, README-template mit 6 sektionen, SOLID 5 prinzipien tabelle, S-single-responsibility + D-dependency-inversion mit code, 12-factor wichtigste (codebase/deps/config/processes/disposability), factor 3 config-in-env, factor 6 stateless-processes, SemVer MAJOR.MINOR.PATCH, package.json caret/tilde/exakt, code-reviews geben+nehmen + checkliste, doku-quellen tabelle (MDN/nodejs/npm/tc39/caniuse), stack-overflow gut-nutzen, AI-assistenten pro/contra (verstehen-nicht-kopieren), selbstlernen projekt-hygiene-check

build geht durch alle 8 kapitel-html+pdf
render-spot-check: cover-slide-dark-mode-invert, git-setup code-syntax-highlight, css-anatomie code-blocks — alle sauber

kein deploy, nur build+verify
2026-05-14 17:14:02 +02:00

486 lines
9.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
marp: true
theme: gaia
paginate: true
backgroundColor: #fff
header: "Web Engineering – DHBW Stuttgart"
footer: "Michael Czechowski – SoSe 2026"
title: Best Practices
---
<style>
:root { --color-foreground: #1a1a2e; --color-highlight: #d63384; }
section.invert { --color-foreground: #fff; }
section { font-size: 1.4rem; }
h1 { color: #a02060; }
section.invert h1 { color: #fff; }
h2 { color: #1f2937; }
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: lead -->
# Kapitel 8 — Best Practices
## Git · README · SOLID · 12-Factor · SemVer
---
<!-- _class: lead -->
# 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 Funktion
- `fix:` Bugfix
- `docs:` Doku
- `refactor:` Code-Restrukturierung
- `test:` Tests
- `chore:` Build/Tools
- `perf:` Performance
- `style:` Formatierung
Automatisches Changelog + SemVer-Bump möglich.
---
# .gitignore — was nie rein gehört
```
# Dependencies
node_modules/
.pnpm-store/
# Build outputs
dist/
build/
.next/
.cache/
# Secrets
.env
.env.local
*.pem
*.key
# Editor + OS
.vscode/
.idea/
.DS_Store
Thumbs.db
# Logs
*.log
npm-debug.log*
```
Vorlagen: github.com/github/gitignore
---
# Branches + PRs
```sh
# 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).
---
<!-- _class: lead -->
# 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:**
1. Was tut das Projekt?
2. Wie installiere ich es?
3. Wie starte ich es?
4. Wie teste ich es?
5. Wie deploye ich es?
6. Lizenz?
---
# README-Template
```markdown
# 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
```sh
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
```javascript
// 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
```
---
<!-- _class: lead -->
# 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
```javascript
// 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.
```javascript
const sessions = new Map(); // pro Server-Instanz!
```
→ Load-Balancer mit 2 Servern: User-Session geht verloren beim 2. Request.
**Gut:** State in DB / Redis.
```javascript
await redis.set(`session:${id}`, JSON.stringify(data));
```
Server-Restart → kein Datenverlust. Horizontale Skalierung möglich.
---
<!-- _class: lead -->
# 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
```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.
---
<!-- _class: lead -->
# Code-Reviews
---
# Constructive Code-Reviews
**Geben:**
- Konkret: Zeilennummern + Beispiel
- Wertschätzend: gut gemachte Stellen erwähnen
- Fragend statt fordernd: „Wäre `X` hier 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? |
---
<!-- _class: lead -->
# 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.**
---
<!-- _class: aufgabe -->
# Selbstlernen — Projekt-Hygiene-Check
Geht euer Projekt durch:
1. **README:** hat alle 6 Sektionen?
2. **.gitignore:** komplett, keine Secrets im Repo?
3. **Conventional Commits:** letzte 10 Commits durchgehen
4. **package.json:** `version`, `description`, `scripts`?
5. **Tests:** Coverage > 70 %?
6. **Dockerfile + compose.yml:** funktionieren?
7. **Environment:** `.env.example` vorhanden, `.env` gitignored?
**Bonus:** GitHub-Actions-Workflow für Tests + Build.
---
# Abschluss
**Über 8 Termine gelernt:**
1. Web Engineering — Foundation
2. CSS Extended — Layout + Animation
3. Node.js Basics — Runtime + REST
4. Node.js Advanced — async + DB + Auth
5. Testing — Unit + Integration + E2E
6. TypeScript — Typen + Schemas
7. Docker — Container + compose
8. Best Practices — Git + README + SOLID + 12-Factor
**Nächste Schritte:** eigenes Projekt für die Prüfungsleistung. Code-Abgabe + Präsentation.