Files
TrueGrowth/scripts/iframe-test-dev.js

165 lines
4.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const { spawn, spawnSync } = require('child_process');
const HOST = process.env.AITU_IFRAME_TEST_HOST || 'http://localhost:7201';
const TARGET = process.env.AITU_IFRAME_TEST_TARGET || 'http://localhost:7200';
const HEALTH_URL = `${HOST}/iframe-test.html`;
const PAGE_URL = `${HEALTH_URL}?target=${encodeURIComponent(TARGET)}`;
const START_TIMEOUT_MS = 60000;
const POLL_INTERVAL_MS = 500;
let serverProcess = null;
let appProcess = null;
let shuttingDown = false;
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function isUrlReady(url) {
try {
const response = await fetch(url, { method: 'GET' });
return response.ok;
} catch {
return false;
}
}
async function waitForUrl(url, timeoutMs) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
if (await isUrlReady(url)) {
return true;
}
await sleep(POLL_INTERVAL_MS);
}
return false;
}
function openBrowser(url) {
if (process.platform === 'darwin') {
return spawnSync('open', [url], { stdio: 'inherit' });
}
if (process.platform === 'win32') {
return spawnSync('cmd', ['/c', 'start', '', url], { stdio: 'inherit' });
}
return spawnSync('xdg-open', [url], { stdio: 'inherit' });
}
function isLocalTarget(url) {
try {
const parsed = new URL(url);
return (
(parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1') &&
parsed.port === '7200'
);
} catch {
return false;
}
}
function startAppServer() {
appProcess = spawn('pnpm', ['start'], {
stdio: 'inherit',
});
appProcess.on('exit', (code, signal) => {
appProcess = null;
if (shuttingDown) {
return;
}
if (signal) {
console.log(`[iframe:test] 主应用已退出signal=${signal}`);
} else {
console.log(`[iframe:test] 主应用已退出code=${code}`);
}
process.exit(code || 0);
});
}
function startStaticServer() {
serverProcess = spawn('python3', ['-m', 'http.server', '7201', '-d', 'apps/web/public'], {
stdio: 'inherit',
});
serverProcess.on('exit', (code, signal) => {
serverProcess = null;
if (shuttingDown) {
return;
}
if (signal) {
console.log(`[iframe:test] 静态服务已退出signal=${signal}`);
} else {
console.log(`[iframe:test] 静态服务已退出code=${code}`);
}
process.exit(code || 0);
});
}
function registerExitHooks() {
const shutdown = () => {
shuttingDown = true;
if (appProcess) {
appProcess.kill('SIGINT');
}
if (serverProcess) {
serverProcess.kill('SIGINT');
}
};
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
}
async function main() {
registerExitHooks();
const targetReady = await isUrlReady(TARGET);
if (!targetReady && isLocalTarget(TARGET)) {
console.log('[iframe:test] 启动 7200 主应用...');
startAppServer();
const appReady = await waitForUrl(TARGET, START_TIMEOUT_MS);
if (!appReady) {
console.error('[iframe:test] 7200 主应用启动超时');
process.exit(1);
}
} else if (targetReady) {
console.log('[iframe:test] 检测到 7200 目标已存在,直接复用');
} else {
console.log(`[iframe:test] 目标地址未就绪,但不是本地 7200跳过自动启动: ${TARGET}`);
}
const alreadyReady = await isUrlReady(HEALTH_URL);
if (!alreadyReady) {
console.log('[iframe:test] 启动 7201 父页面静态服务...');
startStaticServer();
const ready = await waitForUrl(HEALTH_URL, START_TIMEOUT_MS);
if (!ready) {
console.error('[iframe:test] 7201 父页面启动超时');
process.exit(1);
}
} else {
console.log('[iframe:test] 检测到 7201 父页面已存在,直接复用');
}
console.log(`[iframe:test] 打开页面: ${PAGE_URL}`);
const openResult = openBrowser(PAGE_URL);
if (openResult.status && openResult.status !== 0) {
process.exit(openResult.status);
}
if (!serverProcess) {
return;
}
console.log('[iframe:test] 开发服务运行中,按 Ctrl+C 退出');
}
main().catch((error) => {
console.error('[iframe:test] 启动失败:', error);
process.exit(1);
});