import { createServer } from 'vite'; import { loadConfig } from '../apps/server/src/config.ts'; import { createApp } from '../apps/server/src/app.ts'; const cfg = loadConfig({ ...process.env, NODE_ENV: 'development', SAME_NETWORK_DISCOVERY_ENABLED: 'true', PAIR_REQUESTS_PER_MINUTE: '20', GUEST_REQUESTS_PER_MINUTE: '60', IP_REQUESTS_PER_MINUTE: '120', PORT: process.env.HOP_DEV_API_PORT, DATABASE_PATH: process.env.HOP_DEV_DATABASE_PATH ?? '.data/hop.sqlite', UPLOAD_DIR: process.env.HOP_DEV_UPLOAD_DIR ?? '.data/uploads', }); const runtime = await createApp(cfg); await runtime.app.listen({ port: cfg.port, host: '127.0.0.1' }); process.env.HOP_API_URL = `http://127.0.0.1:${cfg.port}`; const vite = await createServer({ root: 'apps/web', configFile: 'apps/web/vite.config.js', server: { port: Number(process.env.HOP_DEV_WEB_PORT), strictPort: true, host: '127.0.0.1' }, }); await vite.listen(); const url = vite.resolvedUrls.local[0]; runtime.setDevOrigin(new URL(url).origin); cfg.appUrl = new URL(url).origin; process.stdout.write( `\nhop. 개발 화면: ${url}\nAPI: ${process.env.HOP_API_URL}\n휴대폰 접속은 아직 설정하지 않았습니다. QR 대신 같은 PC의 다른 브라우저에서 코드를 입력해 주세요.\n`, ); for (const signal of ['SIGINT', 'SIGTERM']) process.on(signal, async () => { await vite.close(); await runtime.app.close(); process.exit(0); });