Skip to content

Kapitel 14: Häufige Anfängerfehler und Fallen

In diesem Kapitel behandeln wir die häufigsten Fehler, die Anfänger bei der Electron-Entwicklung machen.

14.1 Häufiger Fehler 1: Anwendung startet nicht

Symptome

Fehler: Cannot find module 'electron'
Fehler: main.js not found
Fenster öffnet sich nicht

Ursachen und Lösungen

1. Abhängigkeiten nicht installiert

Fehler:

bash
npm start
# Fehler: electron ist nicht installiert

Lösung:

bash
# Electron installieren
npm install electron --save-dev

# Oder neu installieren
rm -rf node_modules
rm package-lock.json
npm install

2. Falscher Pfad in package.json

Fehler:

json
{
  "main": "main.js"  // Datei existiert nicht!
}

Lösung:

json
{
  "main": "src/main.js"  // Richtiger Pfad
}

3. Node.js/npm nicht korrekt installiert

Überprüfung:

bash
node --version
npm --version

Lösung:

14.2 Häufiger Fehler 2: IPC-Kommunikation schlägt fehl

Symptome

Fehler: ipcRenderer is not defined
Nachrichten kommen nicht an
Antworten bleiben aus

Ursachen und Lösungen

1. Context Isolation nicht beachtet

Fehler (veraltet):

javascript
// renderer.js - Funktioniert nicht mit contextIsolation: true!
const { ipcRenderer } = require('electron');
ipcRenderer.send('message', data);

Lösung (mit Preload):

javascript
// preload.js
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('api', {
  send: (channel, data) => ipcRenderer.send(channel, data),
  receive: (channel, func) => {
    ipcRenderer.on(channel, (event, ...args) => func(...args));
  }
});

// renderer.js
window.api.send('message', data);

2. Kanalnamen vertippt

Fehler:

javascript
// Main
ipcMain.on('get-data', ...);

// Renderer
ipcRenderer.send('getdata', ...);  // Falsch!

Lösung:

javascript
// channels.js - Konstanten verwenden
export const Channels = {
  GET_DATA: 'get-data',
  SAVE_DATA: 'save-data'
};

// In Main und Renderer importieren
import { Channels } from './channels';

3. IPC-Listener mehrfach registriert

Fehler:

javascript
// Jedes Mal wenn Komponente gemountet wird
useEffect(() => {
  ipcRenderer.on('channel', handler);  // Mehrmals registriert!
}, []);

Lösung:

javascript
useEffect(() => {
  const handler = (event, data) => { /* ... */ };
  ipcRenderer.on('channel', handler);
  
  // Cleanup: Listener entfernen
  return () => {
    ipcRenderer.removeListener('channel', handler);
  };
}, []);

14.3 Häufiger Fehler 3: Native API-Aufrufe schlagen fehl

Symptome

Fehler: Notification is not a constructor
Fehler: dialog is not defined

Ursachen und Lösungen

1. Native Module im Renderer verwenden

Fehler:

javascript
// renderer.js - Funktioniert nicht!
const { Notification } = require('electron');
new Notification({ title: 'Hallo' }).show();

Lösung (über IPC):

javascript
// main.js
ipcMain.handle('show-notification', (event, { title, body }) => {
  new Notification({ title, body }).show();
});

// preload.js
contextBridge.exposeInMainWorld('api', {
  showNotification: (title, body) => 
    ipcRenderer.invoke('show-notification', { title, body })
});

// renderer.js
window.api.showNotification('Titel', 'Nachricht');

2. Module falsch importiert

Fehler:

javascript
// Falsch: Alles aus electron importieren
const electron = require('electron');
electron.Notification.show();  // Funktioniert nicht!

Lösung:

javascript
// Richtig: Spezifische Module importieren
const { Notification, ipcMain } = require('electron');

14.4 Häufiger Fehler 4: Anwendung lässt sich nach Paketierung nicht ausführen

Symptome

Fehler: Cannot find module './config.json'
App stürzt nach Installation ab

Ursachen und Lösungen

1. Falsche Pfade nach Paketierung

Fehler:

javascript
// Funktioniert in Entwicklung, aber nicht nach Paketierung
const config = require('./config.json');

Lösung:

javascript
const { app } = require('electron');
const path = require('path');
const fs = require('fs');

function loadConfig() {
  let configPath;
  
  if (app.isPackaged) {
    // In gepackter App: resources/path
    configPath = path.join(process.resourcesPath, 'app.asar', 'config.json');
  } else {
    // In Entwicklung: projektverzeichnis
    configPath = path.join(__dirname, 'config.json');
  }
  
  return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
}

2. Abhängigkeiten in devDependencies statt dependencies

Fehler:

json
{
  "devDependencies": {
    "electron-store": "^8.1.0"  // Falsch!
  }
}

Lösung:

json
{
  "dependencies": {
    "electron-store": "^8.1.0"  // Richtig!
  },
  "devDependencies": {
    "electron": "^31.0.0"
  }
}

3. Native Module nicht neu kompiliert

Fehler:

Fehler: The module was compiled against a different Node.js version

Lösung:

bash
# Native Module für Electron neu kompilieren
npx electron-rebuild

# Oder in package.json
{
  "scripts": {
    "rebuild": "electron-rebuild"
  }
}

14.5 Häufiger Fehler 5: CORS-Probleme

Symptome

Fehler: Access to fetch blocked by CORS policy
Fehler: No 'Access-Control-Allow-Origin' header

Ursachen und Lösungen

1. CORS in Renderer-Prozess

Fehler:

javascript
// Renderer - CORS-Beschränkungen
fetch('https://api.example.com/data')
  .then(response => response.json())
  .catch(error => console.error('CORS Fehler:', error));

Lösung 1: Anfrage über Hauptprozess

javascript
// main.js
const axios = require('axios');

ipcMain.handle('fetch-data', async (event, url) => {
  // Keine CORS-Beschränkungen im Hauptprozess!
  const response = await axios.get(url);
  return response.data;
});

// preload.js
contextBridge.exposeInMainWorld('api', {
  fetchData: (url) => ipcRenderer.invoke('fetch-data', url)
});

Lösung 2: WebSecurity deaktivieren (nur Entwicklung!)

javascript
// main.js - Nicht für Produktion!
const win = new BrowserWindow({
  webPreferences: {
    webSecurity: false  // UNSICHER!
  }
});

14.6 Performance-Optimierung Grundlagen

Hauptprozess nicht blockieren

Fehler:

javascript
// Blockiert den Hauptprozess!
ipcMain.handle('heavy-operation', (event, data) => {
  const result = heavyCPUOperation(data);  // Blockiert UI!
  return result;
});

Lösung:

javascript
// Asynchrone Verarbeitung
ipcMain.handle('heavy-operation', async (event, data) => {
  // In separatem Thread ausführen
  const { Worker } = require('worker_threads');
  return new Promise((resolve, reject) => {
    const worker = new Worker('./worker.js');
    worker.postMessage(data);
    worker.on('message', resolve);
    worker.on('error', reject);
  });
});

Renderer-Prozess optimieren

javascript
// DOM-Operationen minimieren
// FALSCH:
for (let i = 0; i < 1000; i++) {
  document.body.appendChild(document.createElement('div'));
}

// RICHTIG:
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
  fragment.appendChild(document.createElement('div'));
}
document.body.appendChild(fragment);

Zusammenfassung

In diesem Kapitel haben Sie gelernt:

  • Anwendungsstartfehler zu diagnostizieren und zu beheben
  • IPC-Kommunikationsfehler zu vermeiden
  • Native API-Aufrufe korrekt durchzuführen
  • Paketierungsprobleme zu lösen
  • CORS-Probleme zu behandeln
  • Grundlegende Performance-Optimierungen vorzunehmen

Im nächsten Kapitel werden wir fortgeschrittene Techniken behandeln.

Frei für alle Anfänger