Skip to content

Commit 32e8638

Browse files
committed
fix: support electron development window
1 parent 4932b6f commit 32e8638

2 files changed

Lines changed: 79 additions & 66 deletions

File tree

electron/main.cjs

Lines changed: 77 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,101 +2,113 @@ const { app, BrowserWindow } = require('electron');
22
const path = require('path');
33
const { spawn } = require('child_process');
44
const http = require('http');
5-
const fs = require('fs');
65

76
let mainWindow;
87
let serverProcess;
9-
let serverHost = '0.0.0.0';
10-
let serverPort = 3000;
11-
12-
try {
13-
const configPath = './src/server-config.json';
14-
if (fs.existsSync(configPath)) {
15-
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
16-
if (config.host) serverHost = config.host;
17-
if (config.frontendPort) serverPort = config.frontendPort;
18-
}
19-
} catch (e) {
20-
console.warn('Failed to load server config:', e);
21-
}
8+
const isDev = !app.isPackaged;
229

23-
// Prevent multiple instances
24-
const gotLock = app.requestSingleInstanceLock();
25-
if (!gotLock) {
26-
app.quit();
27-
process.exit(0);
28-
}
10+
const DEV_URL = process.env.VITE_DEV_SERVER_URL || 'http://localhost:3000';
2911

30-
// Wait until server is ready
12+
// Wait for server
3113
function waitForServer(url) {
3214
return new Promise((resolve) => {
3315
const check = () => {
3416
http
3517
.get(url, () => resolve())
3618
.on('error', () => setTimeout(check, 500));
3719
};
20+
3821
check();
3922
});
4023
}
4124

42-
// Start Nitro server (production)
43-
function startServer() {
44-
return new Promise((resolve) => {
45-
const serverPath = path.join(
46-
process.resourcesPath,
47-
'app.asar.unpacked',
48-
'.output',
49-
'server',
50-
'index.mjs'
51-
);
52-
53-
console.log("Starting server from:", serverPath);
54-
55-
serverProcess = spawn('node', [serverPath], {
56-
stdio: 'ignore', // no terminal
57-
windowsHide: true, // hide CMD
58-
env: {
59-
...process.env,
60-
HOST: serverHost,
61-
PORT: serverPort.toString(),
62-
},
63-
});
64-
65-
waitForServer(`http://localhost:${serverPort}`).then(resolve);
25+
// Start production Nitro server
26+
async function startProductionServer() {
27+
const serverPath = path.join(
28+
process.resourcesPath,
29+
'app.asar.unpacked',
30+
'.output',
31+
'server',
32+
'index.mjs'
33+
);
34+
35+
console.log('Starting production server:', serverPath);
36+
37+
serverProcess = spawn('node', [serverPath], {
38+
stdio: 'inherit',
39+
windowsHide: true,
40+
env: {
41+
...process.env,
42+
HOST: '0.0.0.0',
43+
PORT: '3000',
44+
},
6645
});
67-
}
6846

69-
// Create window
70-
function createWindow() {
71-
if (mainWindow) return;
47+
await waitForServer('http://localhost:3000');
48+
}
7249

50+
// Create Electron window
51+
async function createWindow() {
7352
mainWindow = new BrowserWindow({
7453
width: 1200,
7554
height: 800,
76-
show: false,
77-
});
7855

79-
mainWindow.loadURL(`http://localhost:${serverPort}`);
56+
// IMPORTANT
57+
show: true,
8058

81-
// Show when ready
82-
mainWindow.once('ready-to-show', () => {
83-
mainWindow.show();
59+
webPreferences: {
60+
nodeIntegration: true,
61+
contextIsolation: false,
62+
},
8463
});
8564

86-
// Debug only if needed
87-
mainWindow.webContents.on('did-fail-load', (e, code, desc) => {
88-
console.log("LOAD FAILED:", code, desc);
65+
mainWindow.webContents.openDevTools();
66+
67+
try {
68+
if (isDev) {
69+
console.log("Loading DEV URL:", DEV_URL);
70+
71+
await waitForServer(DEV_URL);
72+
73+
await mainWindow.loadURL(DEV_URL);
74+
} else {
75+
console.log("Loading PROD URL");
76+
77+
await startProductionServer();
78+
79+
await mainWindow.loadURL("http://localhost:3000");
80+
}
81+
82+
console.log("WINDOW LOADED");
83+
} catch (err) {
84+
console.error("LOAD ERROR:", err);
85+
}
86+
87+
mainWindow.on("closed", () => {
88+
mainWindow = null;
8989
});
90+
91+
mainWindow.webContents.on(
92+
"did-fail-load",
93+
(_, code, desc) => {
94+
console.log("FAILED LOAD:", code, desc);
95+
}
96+
);
97+
98+
mainWindow.webContents.on(
99+
"render-process-gone",
100+
(_, details) => {
101+
console.log("RENDER GONE:", details);
102+
}
103+
);
90104
}
91105

92-
// App start
93-
app.whenReady().then(async () => {
94-
await startServer();
95-
createWindow();
96-
});
106+
app.whenReady().then(createWindow);
97107

98-
// Cleanup
99108
app.on('window-all-closed', () => {
100109
if (serverProcess) serverProcess.kill();
101-
if (process.platform !== 'darwin') app.quit();
110+
111+
if (process.platform !== 'darwin') {
112+
app.quit();
113+
}
102114
});

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"start": "vite preview --host --open",
1111
"build": "vite build",
1212
"electron": "npx electron .",
13-
"electron-dev": "concurrently \"vite\" \"wait-on http://localhost:3000 && VITE_DEV_SERVER_URL=http://localhost:3000 electron .\"",
13+
"electron-dev": "concurrently \"vite\" \"wait-on http://localhost:3000 && cross-env VITE_DEV_SERVER_URL=http://localhost:3000 electron .\"",
1414
"dist": "electron-builder",
1515
"preview": "vite preview",
1616
"test": "vitest run",
@@ -50,6 +50,7 @@
5050
"@vitejs/plugin-react": "^5.2.0",
5151
"autoprefixer": "^10.4.23",
5252
"concurrently": "^9.2.1",
53+
"cross-env": "^10.1.0",
5354
"daisyui": "^5.5.14",
5455
"electron": "^40.6.1",
5556
"electron-builder": "^26.8.1",

0 commit comments

Comments
 (0)