Appearance
Kapitel 4: Electron-Kern dateien analysieren
In diesem Kapitel analysieren wir die wichtigsten Dateien einer Electron-App im Detail.
4.1 package.json (Electron-Projektkonfiguration)
Die package.json ist das Herzstück der Projektkonfiguration.
Grundlegende Struktur
json
{
"name": "meine-electron-app",
"version": "1.0.0",
"description": "Meine erste Electron-App",
"main": "main.js",
"scripts": {
"start": "electron .",
"build": "electron-builder"
},
"keywords": ["electron", "desktop"],
"author": "Ihr Name",
"license": "MIT",
"devDependencies": {
"electron": "^31.0.0",
"electron-builder": "^24.0.0"
},
"dependencies": {
"electron-store": "^8.1.0"
}
}Wichtige Felder im Detail
main-Feld: Hauptprozess-Einstiegsdatei
json
{
"main": "main.js"
}| Aspekt | Erklärung |
|---|---|
| Funktion | Legt fest, welche Datei als Hauptprozess ausgeführt wird |
| Standard | main.js (falls nicht angegeben) |
| Wichtig | Muss existieren und korrekten Pfad haben |
scripts-Feld: Start- und Build-Skripte
json
{
"scripts": {
"start": "electron .",
"dev": "electron . --dev",
"build:win": "electron-builder --win",
"build:mac": "electron-builder --mac",
"build:linux": "electron-builder --linux"
}
}| Skript | Befehl | Funktion |
|---|---|---|
start | npm start | App im Entwicklungsmodus starten |
dev | npm run dev | App mit DevTools starten |
build:win | npm run build:win | Windows-Installer erstellen |
build:mac | npm run build:mac | macOS-Installer erstellen |
devDependencies vs. dependencies
json
{
"devDependencies": {
"electron": "^31.0.0",
"electron-builder": "^24.0.0"
},
"dependencies": {
"electron-store": "^8.1.0",
"axios": "^1.6.0"
}
}| Typ | Erklärung | Beispiel |
|---|---|---|
devDependencies | Nur für Entwicklung | electron, electron-builder |
dependencies | Zur Laufzeit benötigt | electron-store, axios |
Electron-spezifische Konfiguration
json
{
"name": "meine-app",
"version": "1.0.0",
"main": "main.js",
"build": {
"appId": "com.beispiel.meineapp",
"productName": "Meine App",
"directories": {
"output": "dist"
},
"win": {
"target": "nsis",
"icon": "assets/icon.ico"
},
"mac": {
"target": "dmg",
"icon": "assets/icon.icns"
}
}
}4.2 Hauptprozess-Einstiegsdatei (main.js)
Die main.js ist die wichtigste Datei im Hauptprozess.
Grundgerüst
javascript
// main.js
const { app, BrowserWindow } = 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'),
contextIsolation: true,
nodeIntegration: false
}
});
// HTML-Datei laden
win.loadFile('index.html');
// DevTools öffnen (nur in Entwicklung)
// win.webContents.openDevTools();
}
// App bereit
app.whenReady().then(() => {
createWindow();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
// Alle Fenster geschlossen
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});app-Modul: App-Lebenszyklus steuern
Wichtige App-Ereignisse
javascript
// App startet
app.on('ready', () => {
console.log('App bereit');
});
// App wird aktiviert (macOS)
app.on('activate', () => {
console.log('App aktiviert');
});
// App wird beendet
app.on('before-quit', (event) => {
console.log('App wird beendet');
});
// Alle Fenster geschlossen
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});| Ereignis | Beschreibung |
|---|---|
ready | App ist bereit (veraltet, nutze whenReady()) |
whenReady() | Promise, wenn App bereit ist |
activate | App wird aktiviert (macOS Dock-Klick) |
before-quit | Bevor App beendet wird |
will-quit | App wird beendet |
window-all-closed | Alle Fenster geschlossen |
BrowserWindow: Anwendungsfenster erstellen
Grundlegende Konfiguration
javascript
const win = new BrowserWindow({
width: 1200, // Breite
height: 800, // Höhe
x: 100, // X-Position
y: 100, // Y-Position
title: 'Meine App', // Fenstertitel
icon: 'icon.png', // Fenstericon
show: false, // Fenster erst anzeigen, wenn bereit
frame: true, // Fensterrahmen (false = frameless)
resizable: true, // Größe änderbar
minimizable: true, // Minimierbar
maximizable: true, // Maximierbar
closable: true, // Schließbar
alwaysOnTop: false, // Immer im Vordergrund
fullscreen: false, // Vollbildmodus
transparent: false, // Transparenter Hintergrund
backgroundColor: '#fff', // Hintergrundfarbe
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
webSecurity: true
}
});Fenster laden: loadFile und loadURL
javascript
// Lokale HTML-Datei laden
win.loadFile('index.html');
// Absolute Pfad
win.loadFile(path.join(__dirname, 'renderer', 'index.html'));
// Remote-URL laden
win.loadURL('https://example.com');
// Mit zusätzlichen Optionen
win.loadURL('https://example.com', {
extraHeaders: 'Authorization: Bearer token'
});| Methode | Verwendung | Beispiel |
|---|---|---|
loadFile() | Lokale HTML-Datei laden | win.loadFile('index.html') |
loadURL() | Remote-URL oder lokaler Server | win.loadURL('http://localhost:3000') |
4.3 Renderer-Prozess-Seiten (index.html / renderer.js)
HTML-Seite (index.html)
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' 'unsafe-inline';">
<title>Meine Electron-App</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="app">
<h1>Willkommen in meiner App!</h1>
<button id="myButton">Klick mich</button>
<div id="output"></div>
</div>
<script src="renderer.js"></script>
</body>
</html>Renderer-Skript (renderer.js)
javascript
// renderer.js
console.log('Renderer-Prozess gestartet');
// DOM-Elemente
const button = document.getElementById('myButton');
const output = document.getElementById('output');
// Event-Listener
button.addEventListener('click', () => {
output.textContent = 'Button wurde geklickt!';
// Nachricht an Hauptprozess senden (über Preload)
window.api.sendMessage('Button geklickt');
});
// Nachricht vom Hauptprozess empfangen
window.api.onMessage((event, data) => {
console.log('Vom Hauptprozess:', data);
output.textContent += `\nAntwort: ${data}`;
});Content Security Policy (CSP)
html
<!-- WICHTIG für Sicherheit -->
<meta http-equiv="Content-Security-Policy"
content="
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
connect-src 'self';
">4.4 Praxisbeispiel: Kernkonfiguration ändern
Ziel: Anwendungsfenster und Startverhalten anpassen
Schritt 1: Benutzerdefinierte Fenstergröße und Position
javascript
// main.js
function createWindow() {
const win = new BrowserWindow({
width: 1400,
height: 900,
minWidth: 800,
minHeight: 600,
x: 50,
y: 50,
title: 'Meine Angepasste App',
icon: path.join(__dirname, 'assets', 'icon.png'),
show: false, // Erst anzeigen, wenn bereit
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
});
// Fenster erst anzeigen, wenn Inhalt geladen ist
win.once('ready-to-show', () => {
win.show();
});
win.loadFile('index.html');
}Schritt 2: Startverhalten anpassen
javascript
// Splash-Screen anzeigen
app.whenReady().then(() => {
// Splash-Screen
const splash = new BrowserWindow({
width: 400,
height: 300,
frame: false,
transparent: true,
alwaysOnTop: true,
center: true
});
splash.loadFile('splash.html');
// Hauptfenster erstellen
const mainWin = new BrowserWindow({
width: 1200,
height: 800,
show: false
});
mainWin.loadFile('index.html');
// Nach 2 Sekunden Splash schließen und Hauptfenster zeigen
setTimeout(() => {
splash.destroy();
mainWin.show();
}, 2000);
});Schritt 3: Zweites Fenster öffnen
javascript
// In main.js
let secondWin;
function createSecondWindow() {
secondWin = new BrowserWindow({
width: 600,
height: 400,
parent: mainWin, // Übergeordnetes Fenster
modal: true, // Modales Fenster
show: false
});
secondWin.loadFile('second.html');
secondWin.once('ready-to-show', () => {
secondWin.show();
});
}
// IPC-Handler für zweites Fenster
ipcMain.on('open-second-window', () => {
createSecondWindow();
});Zusammenfassung
In diesem Kapitel haben Sie gelernt:
- Die
package.jsonfür Electron zu konfigurieren - Die
main.js(Hauptprozess) im Detail zu verstehen app- undBrowserWindow-Module zu nutzen- Renderer-Prozess-Seiten zu erstellen
- Konfigurationen anzupassen
Im nächsten Kapitel werden wir Fensteroperationen im Detail behandeln.
