Skip to content

Kapitel 4: Modularisierung

🎯 Lernziele

In diesem Kapitel lernen Sie:

  • ✅ Was Modularisierung ist und warum sie wichtig ist
  • ✅ CommonJS-Modulspezifikation (Node.js Standard)
  • ✅ ES Modules (ES6) in Node.js verwenden
  • ✅ Eigene Module erstellen
  • ✅ Modul-Suchmechanismus verstehen
  • ✅ Praxis: Modul erstellen und verwenden

4.1 Was ist Modularisierung?

📖 Definition

Modularisierung ist das Aufteilen von Code in wiederverwendbare, unabhängige Einheiten (Module).

🎨 Visuelle Erklärung

Ohne Modularisierung (Alles in einer Datei):
┌─────────────────────────────┐
│  app.js (1000 Zeilen!)     │
│  - Funktionen              │
│  - Variablen               │
│  - Konfiguration           │
│  (Unübersichtlich!)       │
└─────────────────────────────┘

Mit Modularisierung:
┌────────────┐  ┌────────────┐  ┌────────────┐
│  app.js    │  │  user.js   │  │  db.js     │
│  (Haupt)  │  │  (Nutzer) │  │  (Daten)  │
└────────────┘  └────────────┘  └────────────┘
     ↓              ↓               ↓
  Importiert     Exportiert    Exportiert
  Module         Funktionen    Datenbank-Logik

💡 Vorteile

  1. Code-Wiederverwendung - Module können in mehreren Projekten verwendet werden
  2. Bessere Wartbarkeit - Änderungen betreffen nur ein Modul
  3. Übersichtlichkeit - Jedes Modul hat eine klare Aufgabe
  4. Vermeidung von Namenskonflikten - Lokale Variablen bleiben lokal

4.2 CommonJS-Spezifikation

CommonJS ist die Standard-Modulspezifikation in Node.js.

📥 Modul exportieren (module.exports)

javascript
// math.js

// Methode 1: Einzelne Funktion exportieren
function addiere(a, b) {
  return a + b;
}

function subtrahiere(a, b) {
  return a - b;
}

// Exportiere als Objekt
module.exports = {
  addiere,
  subtrahiere
};

// Methode 2: Direkt exportieren (Shorthand)
module.exports = {
  addiere: (a, b) => a + b,
  subtrahiere: (a, b) => a - b,
  multipliziere: (a, b) => a * b
};

📤 Modul importieren (require())

javascript
// app.js
const math = require('./math');

console.log(math.addiere(5, 3));      // 8
console.log(math.subtrahiere(10, 4)); // 6
console.log(math.multipliziere(2, 3)); // 6

🔍 Verschiedene Export-Varianten

Variante 1: Alles als Objekt exportieren

javascript
// utils.js
function gruesse(name) {
  return `Hallo ${name}!`;
}

function berechneAlter(geburtsjahr) {
  return new Date().getFullYear() - geburtsjahr;
}

module.exports = {
  gruesse,
  berechneAlter
};

Variante 2: Nur eine Funktion/Variable exportieren

javascript
// PI.js
module.exports = 3.14159;

// app.js
const PI = require('./PI');
console.log(PI); // 3.14159

Variante 3: Nachträglich exportieren

javascript
// calculator.js
const addiere = (a, b) => a + b;
const subtrahiere = (a, b) => a - b;

// Nachträglich exportieren
module.exports.addiere = addiere;
module.exports.subtrahiere = subtrahiere;
module.exports.PI = 3.14159;

4.3 ES Modules in Node.js

ES Modules (ESM) ist der moderne Standard für JavaScript-Module.

🔧 ES Modules aktivieren

Methode 1: package.json ändern

json
{
  "type": "module",
  "name": "mein-projekt",
  "version": "1.0.0"
}

Methode 2: Dateiendung .mjs verwenden

math.mjs  (statt math.js)
app.mjs

📥 Modul exportieren (export)

javascript
// math.mjs (oder mit "type": "module" in package.json)

// Benannte Exporte (Named Exports)
export function addiere(a, b) {
  return a + b;
}

export function subtrahiere(a, b) {
  return a - b;
}

export const PI = 3.14159;

// Standard-Export (Default Export)
export default function multipliziere(a, b) {
  return a * b;
}

📤 Modul importieren (import)

javascript
// app.mjs (oder mit "type": "module" in package.json)

// Benannte Importe
import { addiere, subtrahiere, PI } from './math.mjs';

console.log(addiere(5, 3));      // 8
console.log(subtrahiere(10, 4)); // 6
console.log(PI);                  // 3.14159

// Standard-Import
import multipliziere from './math.mjs';
console.log(multipliziere(2, 3)); // 6

// Alles importieren
import * as math from './math.mjs';
console.log(math.addiere(5, 3)); // 8

4.4 Eigene Module erstellen

📝 Schritt-für-Schritt: Modul erstellen

Schritt 1: Modul-Datei erstellen (nutzer.js)

javascript
// nutzer.js

// Private Variable (nicht direkt zugänglich von außen)
let nutzerListe = [];

// Öffentliche Funktionen (exportiert)
function nutzerHinzufuegen(name, email) {
  const nutzer = {
    id: nutzerListe.length + 1,
    name,
    email
  };
  nutzerListe.push(nutzer);
  return nutzer;
}

function alleNutzerAbrufen() {
  return nutzerListe;
}

function nutzerSuchen(id) {
  return nutzerListe.find(n => n.id === id);
}

// Exportieren
module.exports = {
  nutzerHinzufuegen,
  alleNutzerAbrufen,
  nutzerSuchen
};

Schritt 2: Modul verwenden (app.js)

javascript
// app.js
const nutzerModul = require('./nutzer');

// Nutzer hinzufügen
nutzerModul.nutzerHinzufuegen('Max Mustermann', 'max@example.com');
nutzerModul.nutzerHinzufuegen('Anna Schmidt', 'anna@example.com');

// Alle Nutzer anzeigen
console.log(nutzerModul.alleNutzerAbrufen());
// [
//   { id: 1, name: 'Max Mustermann', email: 'max@example.com' },
//   { id: 2, name: 'Anna Schmidt', email: 'anna@example.com' }
// ]

// Nutzer suchen
console.log(nutzerModul.nutzerSuchen(1));
// { id: 1, name: 'Max Mustermann', email: 'max@example.com' }

4.5 Modul-Suchmechanismus

Wenn Sie require() verwenden, sucht Node.js das Modul in einer bestimmten Reihenfolge.

🔍 Suchreihenfolge

require('modul-name')

  1. Core-Modul? (fs, path, http...)
     ↓ (Nein)
  2. Relative/absolute Pfad? (./modul, /pfad/modul)
     ↓ (Nein)
  3. node_modules suchen (aktuelle Verzeichnis)
     ↓ (Nicht gefunden)
  4. node_modules suchen (übergeordnete Verzeichnisse)
     ↓ (Nicht gefunden)
  5. Globales node_modules (nur bei global installierten Paketen)
     ↓ (Nicht gefunden)
  FEHLER: Cannot find module

📂 Detaillierte Suche

javascript
// require('./math')
// Sucht in dieser Reihenfolge:
// 1. math.js
// 2. math.json
// 3. math.node (C++ Addon)
// 4. math/index.js (wenn math ein Ordner ist)

// require('express')
// Sucht in:
// 1. ./node_modules/express
// 2. ../node_modules/express
// 3. ../../node_modules/express
// 4. ... (bis zum Root-Verzeichnis)

📦 package.json und Modul-Einstiegspunkt

Wenn ein Ordner importiert wird, sucht Node.js nach package.json:

json
// node_modules/mein-modul/package.json
{
  "name": "mein-modul",
  "main": "index.js"  // ← Einstiegspunkt
}

Wenn main nicht angegeben ist, sucht Node.js nach index.js.


4.6 Praxis: Modul erstellen

🛠️ Fallstudie: Logger-Modul erstellen

Schritt 1: Logger-Modul erstellen (logger.js)

javascript
// logger.js
const fs = require('fs');
const path = require('path');

// Log-Level
const LOG_LEVEL = {
  INFO: 'INFO',
  WARN: 'WARN',
  ERROR: 'ERROR'
};

// Aktuelles Datum formatieren
function datumFormatieren() {
  const jetzt = new Date();
  return jetzt.toISOString().replace('T', ' ').slice(0, 19);
}

// Log-Nachricht schreiben
function logNachricht(level, nachricht) {
  const zeitstempel = datumFormatieren();
  const logNachricht = `[${zeitstempel}] [${level}] ${nachricht}\n`;
  
  // In Konsole ausgeben
  console.log(logNachricht.trim());
  
  // In Datei schreiben
  const logDatei = path.join(__dirname, 'app.log');
  fs.appendFileSync(logDatei, logNachricht, 'utf8');
}

// Öffentliche API
module.exports = {
  info: (nachricht) => logNachricht(LOG_LEVEL.INFO, nachricht),
  warn: (nachricht) => logNachricht(LOG_LEVEL.WARN, nachricht),
  error: (nachricht) => logNachricht(LOG_LEVEL.ERROR, nachricht)
};

Schritt 2: Logger-Modul verwenden (app.js)

javascript
// app.js
const logger = require('./logger');

logger.info('Anwendung gestartet');
logger.info('Verbindung zur Datenbank hergestellt');

// Etwas schiefgegangen
logger.warn('Warnung: Langsame Antwortzeit');

// Fehler aufgetreten
logger.error('Fehler: Datenbankverbindung fehlgeschlagen');

console.log('Log-Datei wurde erstellt: app.log');

Ausgabe in app.log:

[2024-01-15 10:30:15] [INFO] Anwendung gestartet
[2024-01-15 10:30:16] [INFO] Verbindung zur Datenbank hergestellt
[2024-01-15 10:30:17] [WARN] Warnung: Langsame Antwortzeit
[2024-01-15 10:30:18] [ERROR] Fehler: Datenbankverbindung fehlgeschlagen

📝 Zusammenfassung

In diesem Kapitel haben Sie gelernt:

  • ✅ Modularisierung = Code in wiederverwendbare Einheiten aufteilen
  • ✅ CommonJS: module.exports und require()
  • ✅ ES Modules: export und import (mit "type": "module")
  • ✅ Eigene Module erstellen und exportieren
  • ✅ Modul-Suchmechanismus verstehen
  • ✅ Praxis: Logger-Modul erstellt

🎯 Nächste Schritte

Im nächsten Kapitel werden wir:

  • npm (Node Package Manager) im Detail lernen
  • Pakete installieren, aktualisieren, deinstallieren
  • package.json und package-lock.json verstehen

📚 Weiterführende Ressourcen


🎉 Kapitel 4 abgeschlossen! Weiter zu Kapitel 5: npm Paketverwaltung

Frei für alle Anfänger