Files
uni/slides/dhbw/03_nodejs_basics.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

362 lines
7.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"
---
<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; }
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 3 — Node.js Basics
## JavaScript außerhalb des Browsers
---
# Was ist Node.js?
**Ryan Dahl, 2009.** JavaScript-Runtime auf V8 (Chrome's JS-Engine).
Vorher: JS war Browser-only.
Mit Node: JS auch als Server, CLI-Tools, Build-Skripte.
**Heute:** Node ist Standard-Backend für viele Web-Apps. Netflix, LinkedIn, NASA, Walmart.
---
# Warum Node?
| Vorteil | Was bedeutet das |
|---------|------------------|
| **JS überall** | gleiche Sprache Frontend + Backend |
| **NPM** | größtes Package-Ökosystem (~3 Mio Packages) |
| **Non-blocking I/O** | viele Verbindungen gleichzeitig |
| **Schnell genug** | V8 optimiert JS aggressiv |
| **Cross-platform** | Linux, macOS, Windows |
---
# Node Versions-Manager
**fnm** (oder `nvm`, `volta`) — pro Projekt Node-Version.
```sh
# Installieren (macOS/Linux)
brew install fnm # oder curl-script
# Aktuelle LTS
fnm install --lts
fnm use lts-latest # 24.x
# Pro Projekt
echo "24" > .nvmrc
fnm use # liest .nvmrc
```
**Aktuell:** Node 24 LTS.
---
# Projekt initialisieren
```sh
mkdir mein-projekt && cd mein-projekt
npm init -y # erzeugt package.json
# Abhängigkeiten installieren
npm install express # → dependencies
npm install -D vitest # → devDependencies (nur dev)
# Skripte ausführen
npm run start
npm test
```
`-y` = alle Defaults akzeptieren.
---
# package.json
```json
{
"name": "mein-projekt",
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "node --watch src/server.js",
"start": "node src/server.js",
"test": "vitest"
},
"dependencies": {
"express": "^5.0.0"
},
"devDependencies": {
"vitest": "^2.0.0"
}
}
```
`"type": "module"` aktiviert ESM.
---
# ESM — modern
```javascript
// utils.js
export function greet(name) {
return `Hallo ${name}`;
}
export const VERSION = "1.0";
// main.js
import { greet, VERSION } from './utils.js';
console.log(greet('Ada'), VERSION);
```
**Pflicht:** `.js`-Endung in import-Pfad.
---
# CommonJS — Legacy
```javascript
// utils.cjs
function greet(name) {
return `Hallo ${name}`;
}
module.exports = { greet };
// main.cjs
const { greet } = require('./utils.cjs');
```
**Wann CJS?** Alte Codebases, npm-Packages, die nicht migriert sind. **Default heute:** ESM.
---
# Built-in Modules
```javascript
import { readFile } from 'node:fs/promises';
import { createServer } from 'node:http';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
```
`node:` Prefix macht explizit klar — kein npm-Package.
---
<!-- _class: lead -->
# HTTP-Server
---
# Eingebauter HTTP-Server
```javascript
import { createServer } from 'node:http';
const server = createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hallo Welt');
});
server.listen(3000, () => {
console.log('Server läuft auf :3000');
});
```
Nackt — ohne Framework. **Funktioniert.**
---
# Express — der Klassiker
```javascript
import express from 'express';
const app = express();
app.use(express.json()); // parsed JSON-Body
app.use(express.static('public')); // statische Dateien
app.get('/', (req, res) => {
res.send('Hallo Welt');
});
app.post('/api/echo', (req, res) => {
res.json({ youSent: req.body });
});
app.listen(3000);
```
---
# REST mit Express
```javascript
const users = [{ id: 1, name: 'Ada' }];
app.get('/users', (req, res) => res.json(users));
app.get('/users/:id', (req, res) => {
const user = users.find(u => u.id == req.params.id);
user ? res.json(user) : res.sendStatus(404);
});
app.post('/users', (req, res) => {
const user = { id: users.length + 1, ...req.body };
users.push(user);
res.status(201).json(user);
});
```
---
# Alternative Frameworks
| Framework | Stärke |
|-----------|--------|
| **Express** | etabliert, größte Community |
| **Fastify** | schneller, schemas eingebaut |
| **Hono** | leichtgewichtig, Edge-deployable |
| **Koa** | von Express-Autoren, modern |
Für DHBW: **Express** oder **Hono**.
---
# Routing-Pattern
```javascript
import { Router } from 'express';
const userRouter = Router();
userRouter.get('/', (req, res) => { /* alle Users */ });
userRouter.get('/:id', (req, res) => { /* ein User */ });
userRouter.post('/', (req, res) => { /* User anlegen */ });
userRouter.put('/:id', (req, res) => { /* User update */ });
userRouter.delete('/:id', (req, res) => { /* User löschen */ });
app.use('/users', userRouter); // mountet unter /users/*
```
---
<!-- _class: lead -->
# Fetch in Node
---
# fetch — global ab Node 18
```javascript
// GET
const res = await fetch('https://api.github.com/users/torvalds');
const data = await res.json();
console.log(data.public_repos);
// POST
const post = await fetch('https://api.example.com/posts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'Hallo' })
});
```
Genau wie im Browser. **Kein extra Package** (vorher: `node-fetch`, `axios`).
---
# Error-Handling
```javascript
try {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`HTTP ${res.status}`);
}
const data = await res.json();
return data;
} catch (error) {
console.error('API call failed:', error.message);
throw error; // re-throw für caller
}
```
`res.ok` ist `true` für 2xx-Statuscodes.
---
# Environment Variables
```javascript
// .env (gitignored!)
DATABASE_URL=postgres://...
API_KEY=sk-...
PORT=3000
// src/config.js
import 'dotenv/config';
export const config = {
port: process.env.PORT || 3000,
dbUrl: process.env.DATABASE_URL,
apiKey: process.env.API_KEY,
};
```
**Niemals** API-Keys ins Repo committen.
---
<!-- _class: aufgabe -->
# Selbstlernen — Mini-API
1. **Projekt initialisieren:** `npm init -y`, ESM aktivieren
2. **Express installieren**
3. **REST-API** für eine Ressource (Books / Movies / TODO)
- `GET /items`, `GET /items/:id`, `POST /items`, `DELETE /items/:id`
4. **In-Memory-Store** als Array (echte DB kommt Kap 4)
5. **Mit Hoppscotch oder curl** testen
**Bonus:** `npm run dev` mit `--watch`-Flag.
---
# Zusammenfassung
**Heute gelernt:**
- Node.js als JS-Runtime außerhalb Browser
- **fnm + Node 24 LTS** als Versions-Setup
- **npm init**, package.json, scripts, dependencies
- **ESM** (import/export) als modernes Modul-System
- Built-in HTTP-Server + **Express** für REST
- **fetch** global ab Node 18
- **.env + dotenv** für Secrets
**Nächste Stunde:** async/await, Filesystem, Datenbank, Auth.