debug-time-machine-cli
Version:
π Debug Time Machine CLI - μμ μλνλ React λλ²κΉ λꡬ
171 lines (152 loc) β’ 6.06 kB
JavaScript
#!/usr/bin/env node
// λ²λ€λ νλ‘ νΈμλ μλ² - React Debug UI μλΉ
const express = require('express');
const path = require('path');
const fs = require('fs');
const app = express();
const port = process.env.PORT || 8080;
// CORS νμ©
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
if (req.method === 'OPTIONS') {
res.sendStatus(200);
} else {
next();
}
});
// Static ν΄λ κ²½λ‘
const staticPath = path.join(__dirname, '../static');
const fallbackHtmlPath = path.join(__dirname, 'debug-ui.html');
console.log('π Static κ²½λ‘ νμΈ:', {
staticPath,
exists: fs.existsSync(staticPath),
indexExists: fs.existsSync(path.join(staticPath, 'index.html')),
files: fs.existsSync(staticPath) ? fs.readdirSync(staticPath) : 'Directory not found'
});
// μ μ νμΌ μ 곡 (React λΉλ κ²°κ³Όλ¬Ό)
app.use(express.static(staticPath, {
maxAge: '1d',
etag: false
}));
// API λΌμ°νΈλ€
app.get('/health', (req, res) => {
res.json({
status: 'ok',
service: 'debug-time-machine-frontend',
timestamp: Date.now(),
uptime: process.uptime(),
staticPath: staticPath,
staticExists: fs.existsSync(staticPath),
indexExists: fs.existsSync(path.join(staticPath, 'index.html')),
files: fs.existsSync(staticPath) ? fs.readdirSync(staticPath) : []
});
});
// React μ± λΌμ°ν
μ μν fallback
app.get('*', (req, res) => {
const indexPath = path.join(staticPath, 'index.html');
console.log('π μμ²:', req.path);
console.log('π Index κ²½λ‘:', indexPath);
console.log('β
Index μ‘΄μ¬:', fs.existsSync(indexPath));
// React λΉλ νμΌμ΄ μμΌλ©΄ μ¬μ©
if (fs.existsSync(indexPath)) {
console.log('β
React λΉλ νμΌ μ¬μ©');
// HTML νμΌμ μ½μ΄μ auto-injector μ€ν¬λ¦½νΈ μ£Όμ
let htmlContent = fs.readFileSync(indexPath, 'utf8');
// Auto-injector μ€ν¬λ¦½νΈ κ²½λ‘
const autoInjectorPath = path.join(__dirname, 'auto-injector.js');
if (fs.existsSync(autoInjectorPath)) {
const injectorScript = fs.readFileSync(autoInjectorPath, 'utf8');
// <head> νκ·Έ μ§νμ μ€ν¬λ¦½νΈ μ£Όμ
const injectedHtml = htmlContent.replace(
'<head>',
`<head>
<script>
console.log('π Debug Time Machine Auto-Injector λ‘λ©...');
${injectorScript}
</script>`
);
console.log('π― Auto-Injector μ€ν¬λ¦½νΈκ° μ£Όμ
λμμ΅λλ€');
res.send(injectedHtml);
} else {
console.log('β οΈ Auto-Injector μ€ν¬λ¦½νΈλ₯Ό μ°Ύμ μ μμ΅λλ€:', autoInjectorPath);
res.sendFile(indexPath);
}
} else {
// μμΌλ©΄ ν΄λ°± HTML μ¬μ©
console.log('β οΈ React λΉλ νμΌμ μ°Ύμ μ μμ΅λλ€. ν΄λ°± HTMLμ μ¬μ©ν©λλ€.');
console.log(`μλν κ²½λ‘: ${indexPath}`);
if (fs.existsSync(fallbackHtmlPath)) {
const fallbackHtml = fs.readFileSync(fallbackHtmlPath, 'utf8');
res.send(fallbackHtml);
} else {
// μ΅νμ μλ¨
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>Debug Time Machine</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; padding: 2rem; background: #f5f5f5; }
.container { max-width: 600px; margin: 0 auto; background: white; padding: 2rem; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
.error { color: #e74c3c; background: #fee; padding: 1rem; border-radius: 5px; margin: 1rem 0; }
.info { color: #3498db; background: #eff8ff; padding: 1rem; border-radius: 5px; margin: 1rem 0; }
</style>
</head>
<body>
<div class="container">
<h1>π°οΈ Debug Time Machine</h1>
<div class="error">
<h3>React UIλ₯Ό λ‘λν μ μμ΅λλ€</h3>
<p>Debug UI λΉλ νμΌμ μ°Ύμ μ μμ΅λλ€.</p>
<p><strong>μλν κ²½λ‘:</strong> ${indexPath}</p>
</div>
<div class="info">
<h3>π§ ν΄κ²° λ°©λ²</h3>
<p>1. Debug Time Machineμ μ΅μ λ²μ μΌλ‘ μ
λ°μ΄νΈνμΈμ</p>
<p>2. λλ μλμΌλ‘ λ°±μλμ μ°κ²°νμΈμ: <a href="http://localhost:4000/health" target="_blank">http://localhost:4000/health</a></p>
</div>
<script>
// λ°±μλ μ°κ²° μλ
fetch('http://localhost:4000/health')
.then(response => response.json())
.then(data => {
document.body.innerHTML += '<div class="info"><h3>β
λ°±μλ μ°κ²°λ¨</h3><p>ν΄λΌμ΄μΈνΈ: ' + (data.clients || 0) + 'κ°</p></div>';
})
.catch(() => {
document.body.innerHTML += '<div class="error"><h3>β λ°±μλ μ°κ²° μ€ν¨</h3><p>ν¬νΈ 4000μμ μλ²λ₯Ό μ°Ύμ μ μμ΅λλ€.</p></div>';
});
</script>
</div>
</body>
</html>`);
}
}
});
// ν¬νΈ μΆ©λ μ²λ¦¬
const server = app.listen(port, (error) => {
if (error) {
if (error.code === 'EADDRINUSE') {
console.log(`β οΈ ν¬νΈ ${port}κ° μ΄λ―Έ μ¬μ© μ€μ
λλ€. λ€λ₯Έ ν¬νΈλ₯Ό μλν©λλ€...`);
// ν¬νΈλ₯Ό 8081λ‘ λ³κ²½νμ¬ μ¬μλ
const newPort = port + 1;
app.listen(newPort, () => {
console.log('π¨ Debug Time Machine Frontend');
console.log(`π URL: http://localhost:${newPort}`);
console.log(`π Static: ${staticPath}`);
console.log(`π Index: ${path.join(staticPath, 'index.html')}`);
console.log(`π Started: ${new Date().toISOString()}`);
});
} else {
console.error('β μλ² μμ μ€ν¨:', error);
process.exit(1);
}
} else {
console.log('π¨ Debug Time Machine Frontend');
console.log(`π URL: http://localhost:${port}`);
console.log(`π Static: ${staticPath}`);
console.log(`π Index: ${path.join(staticPath, 'index.html')}`);
console.log(`π Started: ${new Date().toISOString()}`);
}
});