feat: add headless mode support for electron
- Add --headless flag to run electron without GUI - Add startup logging for debugging - Improve headless mode exit handling (auto-exit after 5s) - Refactor args variable to argsGlobal for clarity Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,31 @@ import { fileURLToPath } from 'url';
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
|
|
||||||
|
function parseArgs() {
|
||||||
|
const args = { docs: null, headless: false, port: null };
|
||||||
|
const docsIndex = process.argv.indexOf('--docs');
|
||||||
|
if (docsIndex !== -1 && process.argv[docsIndex + 1]) {
|
||||||
|
args.docs = process.argv[docsIndex + 1];
|
||||||
|
}
|
||||||
|
if (process.argv.includes('--headless')) {
|
||||||
|
args.headless = true;
|
||||||
|
}
|
||||||
|
const portIndex = process.argv.indexOf('--port');
|
||||||
|
if (portIndex !== -1 && process.argv[portIndex + 1]) {
|
||||||
|
args.port = parseInt(process.argv[portIndex + 1], 10);
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
const argsGlobal = parseArgs();
|
||||||
|
|
||||||
|
if (argsGlobal.headless) {
|
||||||
|
app.commandLine.appendSwitch('disable-gpu');
|
||||||
|
app.commandLine.appendSwitch('disable-software-rasterizer');
|
||||||
|
app.commandLine.appendSwitch('no-sandbox');
|
||||||
|
app.disableHardwareAcceleration();
|
||||||
|
}
|
||||||
|
|
||||||
app.commandLine.appendSwitch('disable-gpu-shader-disk-cache');
|
app.commandLine.appendSwitch('disable-gpu-shader-disk-cache');
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
@@ -23,23 +48,8 @@ function log(...args) {
|
|||||||
console.log(line.trim());
|
console.log(line.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseArgs() {
|
process.stdout.write(`[${new Date().toISOString()}] [main] XCSDD starting in ${argsGlobal.headless ? 'HEADLESS' : 'normal'} mode\n`);
|
||||||
const args = { docs: null, headless: false, port: null };
|
process.stdout.write(`[${new Date().toISOString()}] [main] Args: docs=${argsGlobal.docs}, headless=${argsGlobal.headless}, port=${argsGlobal.port}\n`);
|
||||||
const docsIndex = process.argv.indexOf('--docs');
|
|
||||||
if (docsIndex !== -1 && process.argv[docsIndex + 1]) {
|
|
||||||
args.docs = process.argv[docsIndex + 1];
|
|
||||||
}
|
|
||||||
if (process.argv.includes('--headless')) {
|
|
||||||
args.headless = true;
|
|
||||||
}
|
|
||||||
const portIndex = process.argv.indexOf('--port');
|
|
||||||
if (portIndex !== -1 && process.argv[portIndex + 1]) {
|
|
||||||
args.port = parseInt(process.argv[portIndex + 1], 10);
|
|
||||||
}
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
const args = parseArgs();
|
|
||||||
|
|
||||||
function getIndexPath() {
|
function getIndexPath() {
|
||||||
if (app.isPackaged) {
|
if (app.isPackaged) {
|
||||||
@@ -125,14 +135,14 @@ function createWindow() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (args.port) {
|
if (argsGlobal.port) {
|
||||||
mainWindow.loadURL(`http://localhost:${args.port}/`);
|
mainWindow.loadURL(`http://localhost:${argsGlobal.port}/`);
|
||||||
} else {
|
} else {
|
||||||
mainWindow.loadFile(indexPath);
|
mainWindow.loadFile(indexPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
mainWindow.on('ready-to-show', () => {
|
mainWindow.on('ready-to-show', () => {
|
||||||
if (!args.headless) {
|
if (!argsGlobal.headless) {
|
||||||
mainWindow.show();
|
mainWindow.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -145,10 +155,10 @@ function createWindow() {
|
|||||||
log('Page finished loading');
|
log('Page finished loading');
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!app.isPackaged && !args.headless) {
|
if (!app.isPackaged && !argsGlobal.headless) {
|
||||||
mainWindow.webContents.openDevTools();
|
mainWindow.webContents.openDevTools();
|
||||||
}
|
}
|
||||||
|
|
||||||
mainWindow.on('closed', () => {
|
mainWindow.on('closed', () => {
|
||||||
mainWindow = null;
|
mainWindow = null;
|
||||||
});
|
});
|
||||||
@@ -195,11 +205,11 @@ ipcMain.on('renderer-log', (_event, level, ...args) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
log('App ready, parsing args:', args);
|
log('App ready, parsing args:', argsGlobal);
|
||||||
|
|
||||||
if (args.port) {
|
if (argsGlobal.port) {
|
||||||
log('Starting HTTP server on port', args.port);
|
log('Starting HTTP server on port', argsGlobal.port);
|
||||||
httpServer = startHttpServer(args.port);
|
httpServer = startHttpServer(argsGlobal.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
createWindow();
|
createWindow();
|
||||||
@@ -218,7 +228,13 @@ app.on('window-all-closed', () => {
|
|||||||
if (httpServer) {
|
if (httpServer) {
|
||||||
httpServer.close();
|
httpServer.close();
|
||||||
}
|
}
|
||||||
if (process.platform !== 'darwin') {
|
if (argsGlobal.headless) {
|
||||||
|
log('Headless mode: window closed, keeping process alive for 5 seconds...');
|
||||||
|
setTimeout(() => {
|
||||||
|
log('Headless mode: exiting now');
|
||||||
|
process.exit(0);
|
||||||
|
}, 5000);
|
||||||
|
} else if (process.platform !== 'darwin') {
|
||||||
app.quit();
|
app.quit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user