UNPKG

debug-time-machine-cli

Version:

πŸš€ Debug Time Machine CLI - μ™„μ „ μžλ™ν™”λœ React 디버깅 도ꡬ

171 lines (152 loc) β€’ 6.06 kB
#!/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()}`); } });