Spaces:
Build error
Build error
File size: 4,814 Bytes
55d48a7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | #!/usr/bin/env node
/**
* Electron Development Script
*
* This script provides hot-reload development mode for Electron applications.
* It automatically builds Electron dependencies, starts the Remix development server,
* and launches the Electron application with hot-reload capabilities.
*/
import { spawn, exec } from 'node:child_process';
import path from 'node:path';
import fs from 'node:fs';
import { fileURLToPath } from 'node:url';
// Get current file directory
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Constants
const REMIX_PORT = 5173;
const CHECK_INTERVAL = 1000;
const MAX_RETRIES = 30;
// Set environment variables
process.env.NODE_ENV = 'development';
console.log('🚀 Starting Electron hot-reload development mode...');
console.log('🔧 Environment:', process.env.NODE_ENV);
let electronProcess = null;
let remixProcess = null;
/**
* Cleanup function to gracefully shutdown all processes
*/
function cleanup() {
console.log('\n🛑 Shutting down all processes...');
if (electronProcess) {
electronProcess.kill('SIGTERM');
}
if (remixProcess) {
remixProcess.kill('SIGTERM');
}
process.exit(0);
}
// Handle process exit signals
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);
/**
* Wait for a server to start on the specified port
* @param {number} port - Port number to check
* @param {string} serverName - Name of the server for logging
* @returns {Promise<void>}
*/
async function waitForServer(port, serverName) {
return new Promise((resolve, reject) => {
let retries = 0;
const checkServer = () => {
exec(`lsof -i :${port}`, (error, stdout) => {
if (stdout) {
console.log(`✅ ${serverName} started`);
resolve();
} else if (retries >= MAX_RETRIES) {
reject(new Error(`Timeout waiting for ${serverName} to start`));
} else {
retries++;
setTimeout(checkServer, CHECK_INTERVAL);
}
});
};
checkServer();
});
}
/**
* Build Electron dependencies
* @returns {Promise<void>}
*/
async function buildElectronDeps() {
return new Promise((resolve, reject) => {
const buildProcess = spawn('pnpm', ['electron:build:deps'], {
stdio: 'inherit',
env: { ...process.env },
});
buildProcess.on('close', (code) => {
if (code === 0) {
console.log('✅ Electron dependencies built successfully');
resolve();
} else {
reject(new Error(`Build failed with exit code: ${code}`));
}
});
buildProcess.on('error', (error) => {
reject(new Error(`Build process error: ${error.message}`));
});
});
}
/**
* Main function to start Electron development mode
* @returns {Promise<void>}
*/
async function startElectronDev() {
try {
// 1. Build Electron dependencies first
console.log('📦 Building Electron dependencies...');
await buildElectronDeps();
// 2. Start Remix development server
console.log('🌐 Starting Remix development server...');
remixProcess = spawn('pnpm', ['dev'], {
stdio: 'pipe',
env: { ...process.env },
});
remixProcess.stdout.on('data', (data) => {
const output = data.toString();
console.log(`[Remix] ${output.trim()}`);
});
remixProcess.stderr.on('data', (data) => {
console.error(`[Remix Error] ${data.toString().trim()}`);
});
// Wait for Remix server to start
await waitForServer(REMIX_PORT, 'Remix development server');
// 3. Start Electron application
console.log('⚡ Starting Electron application...');
const electronPath = path.join(__dirname, '..', 'node_modules', '.bin', 'electron');
const mainPath = path.join(__dirname, '..', 'build', 'electron', 'main', 'index.mjs');
// Check if main process file exists
if (!fs.existsSync(mainPath)) {
throw new Error(`Main process file not found: ${mainPath}`);
}
electronProcess = spawn(electronPath, [mainPath], {
stdio: 'inherit',
env: {
...process.env,
NODE_ENV: 'development',
ELECTRON_IS_DEV: '1',
},
});
electronProcess.on('error', (error) => {
console.error('❌ Failed to start Electron:', error);
cleanup();
});
electronProcess.on('exit', (code) => {
console.log(`📱 Electron process exited with code: ${code}`);
if (code !== 0) {
cleanup();
}
});
console.log('🎉 Electron hot-reload development mode started!');
console.log('💡 Code changes will automatically reload');
console.log('🛑 Press Ctrl+C to exit');
} catch (error) {
console.error('❌ Startup failed:', error.message);
cleanup();
}
}
// Start development mode
startElectronDev();
|