Appearance
Kapitel 3: Electron-Kernarchitektur und Prozesse
In diesem Kapitel lernen Sie die Architektur von Electron kennen - das wichtigste Konzept für Einsteiger.
3.1 Electron-Kernarchitektur
Architektur-Überblick
Electron besteht aus zwei Hauptprozessen:
┌─────────────────────────────────────────┐
│ Electron App │
│ │
│ ┌─────────────────────────────────┐ │
│ │ Hauptprozess (Main) │ │
│ │ - App-Lebenszyklus │ │
│ │ - Fensterverwaltung │ │
│ │ - Native APIs │ │
│ │ - Node.js Zugriff │ │
│ └──────────┬──────────────────────┘ │
│ │ IPC │
│ ┌──────────▼──────────────────────┐ │
│ │ Renderer-Prozess (Renderer) │ │
│ │ - UI-Rendering (Chromium) │ │
│ │ - Web-Seiten │ │
│ │ - Frontend-Interaktion │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘Hauptkomponenten
| Komponente | Beschreibung |
|---|---|
| Hauptprozess (Main Process) | Verwaltet die App und erstellt Fenster |
| Renderer-Prozess (Renderer Process) | Rendert die Web-Seiten in den Fenstern |
| IPC (Inter-Process Communication) | Kommunikation zwischen den Prozessen |
3.2 Hauptprozess (Main Process)
Aufgaben und Verantwortlichkeiten
Der Hauptprozess ist das Herzstück der Electron-App.
Hauptaufgaben
App-Lebenszyklus verwalten
- App starten, beenden, in den Hintergrund
Fenster erstellen und verwalten
BrowserWindowinstanziieren- Fenstereigenschaften festlegen
Native APIs aufrufen
- Menüs, Tray-Icons, Dialoge
Node.js-Funktionen nutzen
- Dateisystem, Netzwerk, Datenbanken
Beispiel: Hauptprozess (main.js)
javascript
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
// Fenster erstellen
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
});
win.loadFile('index.html');
}
// App bereit
app.whenReady().then(() => {
createWindow();
});
// Alle Fenster geschlossen
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});Wichtige Module im Hauptprozess
| Modul | Funktion |
|---|---|
app | App-Lebenszyklus steuern |
BrowserWindow | Fenster erstellen |
ipcMain | IPC-Nachrichten empfangen |
Menu | App-Menüs erstellen |
Tray | Tray-Icons erstellen |
dialog | System-Dialoge anzeigen |
3.3 Renderer-Prozess (Renderer Process)
Aufgaben und Verantwortlichkeiten
Der Renderer-Prozess ist für die Anzeige der Benutzeroberfläche zuständig.
Hauptaufgaben
UI rendern
- HTML/CSS/JavaScript ausführen
- Web-Seiten anzeigen
Frontend-Interaktion verarbeiten
- Button-Klicks, Formulareingaben
- DOM-Manipulation
Mit Hauptprozess kommunizieren
- Über IPC Nachrichten senden
- Daten anfordern
Beispiel: Renderer-Prozess (renderer.js)
javascript
// renderer.js
console.log('Renderer-Prozess gestartet');
// DOM-Elemente
const button = document.getElementById('myButton');
const output = document.getElementById('output');
// Button-Klick
button.addEventListener('click', () => {
output.textContent = 'Button geklickt!';
// Nachricht an Hauptprozess senden
window.api.sendMessage('Hallo vom Renderer!');
});
// Nachricht vom Hauptprozess empfangen
window.api.onMessage((event, data) => {
console.log('Vom Hauptprozess:', data);
});Wichtige Punkte zum Renderer-Prozess
☑ Jedes Fenster hat einen eigenen Renderer-Prozess
☑ Mehrere Fenster = Mehrere Renderer-Prozesse
☑ Jeder Renderer-Prozess ist isoliert (Sicherheit)
☑ Standardmäßig kein direkter Node.js-Zugriff (contextIsolation)3.4 Unterschiede zwischen Haupt- und Renderer-Prozess
Vergleichstabelle
| Aspekt | Hauptprozess | Renderer-Prozess |
|---|---|---|
| Laufzeitumgebung | Node.js | Chromium (Browser) |
| Zugriff auf Node.js | Ja (vollständig) | Nein (bei contextIsolation) |
| Fenster erstellen | Ja | Nein |
| Native APIs | Ja | Nein (nur über IPC) |
| App-Lebenszyklus | Ja | Nein |
| UI-Rendering | Nein | Ja |
| IPC-Rolle | Empfänger/Sender | Sender/Empfänger |
Berechtigungsunterschiede
Hauptprozess:
✓ Vollständiger Zugriff auf Node.js
✓ Native Betriebssystem-APIs
✓ Fensterverwaltung
✓ App-Lebenszyklus
Renderer-Prozess:
✓ Web-APIs (DOM, fetch, localStorage)
✗ Kein direkter Node.js-Zugriff (sicherheitshalber)
✗ Keine nativen APIs (nur über IPC)Kommunikationsweise
Renderer-Prozess → IPC → Hauptprozess
↓
Hauptprozess → IPC → Renderer-Prozess3.5 Prozesskommunikation (IPC) Grundlagen
Was ist IPC?
IPC (Inter-Process Communication) ist der Mechanismus, mit dem Haupt- und Renderer-Prozesse Daten austauschen.
Grundlegende IPC-Konzepte
Renderer-Prozess Hauptprozess
│ │
│ ipcRenderer.send() │
│───────────────────────────────────>│
│ │ ipcMain.on()
│ │
│ ipcRenderer.on() │
│<───────────────────────────────────│
│ │ event.reply()Kernmodule
| Modul | Prozess | Funktion |
|---|---|---|
ipcMain | Hauptprozess | Nachrichten vom Renderer empfangen |
ipcRenderer | Renderer-Prozess | Nachrichten an Hauptprozess senden |
3.6 Praxisbeispiel: Einfache IPC-Kommunikation
Projektstruktur
ipc-beispiel/
├── main.js # Hauptprozess
├── preload.js # Preload-Skript (IPC-Brücke)
├── index.html # UI
└── package.jsonSchritt 1: preload.js erstellen (IPC-Brücke)
javascript
// preload.js - Sichere IPC-Brücke
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('api', {
// Nachricht an Hauptprozess senden
sendMessage: (message) => {
ipcRenderer.send('message-from-renderer', message);
},
// Auf Nachrichten vom Hauptprozess hören
onMessage: (callback) => {
ipcRenderer.on('message-from-main', (event, data) => {
callback(event, data);
});
}
});Schritt 2: main.js konfigurieren
javascript
// main.js
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true, // Sicherheit: isoliert
nodeIntegration: false // Sicherheit: kein Node.js im Renderer
}
});
win.loadFile('index.html');
}
// Nachricht vom Renderer empfangen
ipcMain.on('message-from-renderer', (event, message) => {
console.log('Vom Renderer:', message);
// Antwort an Renderer senden
event.reply('message-from-main', `Antwort: ${message.toUpperCase()}`);
});
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});Schritt 3: index.html erstellen
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>IPC Beispiel</title>
<style>
body { font-family: Arial; padding: 20px; }
button { padding: 10px 20px; margin: 10px; }
#output { margin-top: 20px; padding: 10px; background: #f0f0f0; }
</style>
</head>
<body>
<h1>IPC Kommunikation Beispiel</h1>
<input type="text" id="messageInput" placeholder="Nachricht eingeben">
<button id="sendButton">Senden</button>
<div id="output"></div>
<script>
const input = document.getElementById('messageInput');
const button = document.getElementById('sendButton');
const output = document.getElementById('output');
// Button-Klick: Nachricht senden
button.addEventListener('click', () => {
const message = input.value;
window.api.sendMessage(message);
output.innerHTML += `<p>Gesendet: ${message}</p>`;
input.value = '';
});
// Auf Antwort vom Hauptprozess hören
window.api.onMessage((event, data) => {
output.innerHTML += `<p><strong>Antwort:</strong> ${data}</p>`;
});
</script>
</body>
</html>Schritt 4: Anwendung testen
bash
npm startErwartetes Ergebnis:
1. Eingabefeld und Button werden angezeigt
2. Nachricht eingeben und "Senden" klicken
3. Konsole im Hauptprozess zeigt: "Vom Renderer: [Nachricht]"
4. UI zeigt die Antwort vom Hauptprozess3.7 Häufige Anfängerfehler
Fehler 1: Haupt- und Renderer-Prozess verwechseln
Symptom: Funktionen funktionieren nicht wie erwartet.
Lösung:
☑ Prüfen: Ist der Code im Haupt- oder Renderer-Prozess?
☑ Hauptprozess: Node.js-Module verwenden
☑ Renderer-Prozess: Web-APIs verwendenFehler 2: IPC-Kommunikation schlägt fehl
Ursachen und Lösungen:
| Problem | Ursache | Lösung |
|---|---|---|
| Nachricht kommt nicht an | Falscher Kanalname | Kanalnamen exakt gleich schreiben |
ipcRenderer nicht gefunden | nodeIntegration: false | Preload-Skript verwenden |
| Sicherheitswarnung | contextIsolation: false | contextIsolation: true + Preload |
Fehler 3: Preload-Skript nicht korrekt konfiguriert
Richtige Konfiguration in main.js:
javascript
const win = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js'), // WICHTIG!
contextIsolation: true,
nodeIntegration: false
}
});Fehler 4: IPC-Listener mehrfach registriert
Fehler:
javascript
// FALSCH: Jedes Mal wenn die Komponente gerendert wird
ipcRenderer.on('channel', callback);Richtig:
javascript
// RICHTIG: Einmal registrieren oder vorher entfernen
ipcRenderer.removeAllListeners('channel');
ipcRenderer.on('channel', callback);Zusammenfassung
In diesem Kapitel haben Sie gelernt:
- Die Electron-Architektur (Haupt- und Renderer-Prozess)
- Aufgaben und Verantwortlichkeiten beider Prozesse
- Unterschiede in Berechtigungen und Laufzeitumgebung
- Grundlagen der IPC-Kommunikation
- Ein praktisches IPC-Beispiel zu implementieren
- Häufige Anfängerfehler zu vermeiden
Im nächsten Kapitel werden wir die Electron-Kern dateien im Detail analysieren.
