Files
uni/slides/dhbw/01_web_eng.md

11 KiB
Raw Permalink Blame History

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 Web Engineering
<style> :root { --color-foreground: #1a1a2e; --color-highlight: #005f8a; --color-dimmed: #4a6a7a; } section.invert { --color-foreground: #fff; } section { font-size: 1.7rem; } h1 { color: #005f8a; } section.invert h1 { color: #fff; } pre { background: #0f1e2e; color: #00b4d8; border-radius: 8px; border-left: 3px solid #005f8a; } pre code { background: transparent; color: inherit; } code { background: #1a3a4a; color: #00b4d8; padding: 0.15em 0.4em; border-radius: 4px; } a { color: var(--color-highlight); } </style>

bg cover opacity:0.2

Web Engineering

DHBW Stuttgart · Informatik / Wirtschaftsinformatik

Sommersemester 2026


Willkommen!

1. Sitzung: 08.05.2026


Wer bist du, was machst du?

  • B.Sc. Wirtschaftsinformatik (Leibniz-FH Hannover)
  • Angestellt bei PONS Langenscheidt GmbH in Stuttgart
  • Honorardozent und Berater

Bisherige Vorlesungen (DHBW/Leibniz-FH):

  • Social Engineering, Mobile Medien, Web Eng

Vorlesungsplan

Sitzung Datum Thema
1 08.05. Intro, Projektgruppen, Internet 101
2 15.05. HTML und CSS (Frameworks)
3 22.05. JS (Frameworks) und npm
4 29.05. nodeJS: Scripting, Running and Building
5 05.06. Express API, CRUD und "Middlewares"
6 12.06. Projektwerkstattbericht
7 19.06. Testing (unit, integration, end-to-end)
8 26.06. TypeScript
9 03.07. Docker, Proxies and DBs
10 10.07. Wrap-up & Projektsupport
11 17.07. Präsentation

Prüfungsleistung Übersicht

Eigenes Projekt: Web-App ODER Backend (API/CLI).

Grundanforderungen (75 Punkte)

Punkte Bereich
20 Idee, Konzeption, Planung
5 Plattformunabhängigkeit
25 Clean Code (KISS, SOLID, DI, Testing, Error Handling)
15 Präsentation
10 Dokumentation

Zusatzpunkte (max. 10): TypeScript, Docker, Dev/Prod-Parity, .env, npm-Publish, Domain, HTTPS, Responsive Design.


Prüfungsleistung Idee & Konzeption (20 P.)

  • "Powerpoint"-Präsentation + Folien
  • Aussagekräftiger Arbeitstitel + Beschreibung
  • Elevator Pitch (max. 1 Min.)
  • Repo-Link (GitHub / GitLab / Codeberg / BitBucket)
  • Logs: wie hat sich Projekt verändert vs. Ursprungsidee?
  • Schematischer Projektaufbau (UML o. Ä.)

Prüfungsleistung Clean Code (25 P.)

  • README.md (clone, start, contribute)
  • KISS Keep It Simple, Stupid
  • SOLID SRP, OCP, LSP, ISP, DIP
  • DI Dependency Injection
  • Testing-Pyramide (Unit, Integration, E2E)
  • Exception/Error Handling

Prüfungsleistung Abgabe & Termine

  • Code-Upload: bis 27.07.
  • Präsentation: 17.07. (Gruppen, ~10 Min.)

Details: https://git.dailysh.it/DHBW/pruefungsleistung


Internet 101 Zeitleiste

Jahr Ereignis
1966 ARPANET
1969 RFCs
1986 IETF
1992 Internet Society
1974 TCP/IP und HTTP(S)
1987 Domain Names und DNS
1993 "Erster" Browser: Mosaic
1994 W3C (HTML, XML, CSS, SVG, WCAG etc.)
1995 ECMAScript (JS)
2006/08 V8 JS Runtime Engine
Heute 1,3 Mio. km Unterseekabel

Internet 101 Browser Request

Browser                          Server
  |                                |
  |-- GET /products -------------->|
  |<-- HTTP 200 + index.html -----|
  |                                |
  |-- GET /script.js ------------->|
  |<-- HTTP 200 + script.js ------|
  |                                |
  |-- GET /api/products ---------->|
  |<-- HTTP 200 + JSON ------------|

bg fit


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"}, ...]

Entwicklungsumgebung

Tools:

  • Node.js + npm
  • VS Code
  • Git
  • Chrome DevTools

Versionierung mit Git

git init
git add .
git commit -m "initial commit"
git remote add origin https://github.com/user/repo.git
git push -u origin main

HTML Hypertext Markup Language


HTML Grundlagen

<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <title>Meine Seite</title>
</head>
<body>
  <h1>Überschrift</h1>
  <p>Textabsatz</p>
</body>
</html>

Semantisches HTML

<header>Navigationsbereich</header>
<nav>Navigation</nav>
<main>
  <article>
    <section>
      <h2>Überschrift</h2>
      <p>Inhalt</p>
    </section>
  </article>
</main>
<footer>Fußzeile</footer>

HTML Tabellen und Listen

<table>
  <thead>
    <tr><th>Name</th><th>Preis</th></tr>
  </thead>
  <tbody>
    <tr><td>Produkt A</td><td>29,99 €</td></tr>
  </tbody>
</table>

<ul>
  <li>Punkt 1</li>
  <li>Punkt 2</li>
</ul>

CSS Cascading Style Sheets


CSS Grundlagen

/* Element */
body { font-family: Arial, sans-serif; }

/* Klasse */
.button { background: #005f8a; color: white; }

/* ID */
#header { height: 60px; }

/* Attribut */
input[type="text"] { border: 1px solid #ccc; }

CSS Layout Flexbox

.container {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

CSS Layout Grid

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

CSS Box Model

.box {
  margin: 10px;
  border: 2px solid #005f8a;
  padding: 20px;
  width: 200px;
  box-sizing: border-box;
}

CSS Responsive

@media (max-width: 768px) {
  .grid {
    grid-template-columns: 1fr;
  }
}

JavaScript


JavaScript Grundlagen

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

// Element auswählen
const title = document.querySelector('h1');

// Inhalt ändern
title.textContent = 'Neue Überschrift';

// Event Listener
button.addEventListener('click', () => {
  alert('Geklickt!');
});

Fetch API

fetch('/api/products')
  .then(res => res.json())
  .then(data => {
    console.log(data);
  })
  .catch(err => console.error(err));

Async/Await

async function loadProducts() {
  try {
    const res = await fetch('/api/products');
    const data = await res.json();
    return data;
  } catch (err) {
    console.error('Fehler:', err);
  }
}

bg fit


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

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

✓ hohe Kompatibilität, simpel ✗ State-Management, Re-Rendering wird schnell komplex


React Counter (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

<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

<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

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

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

{
  "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


Fragen?

  1. Was ist der Unterschied zwischen let und const?
  2. Wie funktioniert fetch()?
  3. Was macht box-sizing: border-box?