import { context } from 'esbuild'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { spawn } from 'node:child_process'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const root = path.resolve(__dirname, '..'); function spawnShell(command, opts = {}) { const child = spawn(command, { cwd: root, stdio: 'inherit', shell: true, ...opts, }); child.on('exit', (code) => { if (code !== 0 && code !== null) { process.exitCode = code; } }); return child; } /** Убивает дерево процессов (на Windows `child.kill()` часто не гасит Vite на 5173). */ function killTree(child) { if (!child || child.killed) return; if (typeof child.exitCode === 'number' && child.exitCode !== null) return; if (process.platform === 'win32' && child.pid) { spawn('taskkill', ['/PID', String(child.pid), '/T', '/F'], { stdio: 'ignore', windowsHide: true, detached: true, }); } else { try { child.kill('SIGTERM'); } catch { /* ignore */ } } } async function watchMainAndPreload() { const main = await context({ entryPoints: [path.join(root, 'app/main/index.ts')], outfile: path.join(root, 'dist/main/index.cjs'), platform: 'node', target: 'node22', format: 'cjs', bundle: true, sourcemap: true, external: ['electron'], define: { 'process.env.NODE_ENV': JSON.stringify('development') }, }); await main.rebuild(); await main.watch(); const preload = await context({ entryPoints: [path.join(root, 'app/preload/index.ts')], outfile: path.join(root, 'dist/preload/index.cjs'), platform: 'node', target: 'node22', format: 'cjs', bundle: true, sourcemap: true, external: ['electron'], define: { 'process.env.NODE_ENV': JSON.stringify('development') }, }); await preload.rebuild(); await preload.watch(); return async () => { await Promise.all([main.dispose(), preload.dispose()]); }; } const dispose = await watchMainAndPreload(); const vite = spawnShell('npx vite dev --strictPort', { env: { ...process.env, NODE_ENV: 'development', DND_SKIP_LICENSE: process.env.DND_SKIP_LICENSE ?? '1', VITE_DEV_SERVER_URL: 'http://localhost:5173/', }, }); const electron = spawnShell('npx electron .', { env: { ...process.env, NODE_ENV: 'development', DND_SKIP_LICENSE: process.env.DND_SKIP_LICENSE ?? '1', VITE_DEV_SERVER_URL: 'http://localhost:5173/', }, }); let shuttingDown = false; const shutdown = async () => { if (shuttingDown) return; shuttingDown = true; killTree(vite); killTree(electron); await dispose(); process.exit(0); }; process.on('SIGINT', () => void shutdown()); process.on('SIGTERM', () => void shutdown()); electron.once('exit', () => { void shutdown(); }); vite.once('exit', (code) => { if (code !== 0 && code !== null && !shuttingDown) { void shutdown(); } });