#!/usr/bin/env node /** * 批量检查所有组件和页面 */ import http from 'http'; import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const HOST = 'localhost'; const PORT = 51720; function reviewCode(targetPath) { return new Promise((resolve, reject) => { const postData = JSON.stringify({ path: targetPath }); const options = { hostname: HOST, port: PORT, path: '/api/code-review', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) }, timeout: 5000 }; const req = http.request(options, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { try { const result = JSON.parse(data); resolve(result); } catch (error) { reject(new Error(`解析响应失败: ${error.message}`)); } }); }); req.on('error', (error) => { reject(error); }); req.on('timeout', () => { req.destroy(); reject(new Error('请求超时')); }); req.write(postData); req.end(); }); } function getAllComponents() { const srcDir = path.resolve(__dirname, '../src'); const components = []; // 扫描 prototypes const pagesDir = path.join(srcDir, 'prototypes'); if (fs.existsSync(pagesDir)) { const prototypes = fs.readdirSync(pagesDir, { withFileTypes: true }); prototypes.forEach(page => { if (page.isDirectory()) { const indexPath = path.join(pagesDir, page.name, 'index.tsx'); if (fs.existsSync(indexPath)) { components.push({ type: 'page', name: page.name, path: `prototypes/${page.name}` }); } } }); } // 扫描 components const elementsDir = path.join(srcDir, 'components'); if (fs.existsSync(elementsDir)) { const components = fs.readdirSync(elementsDir, { withFileTypes: true }); components.forEach(element => { if (element.isDirectory()) { const indexPath = path.join(elementsDir, element.name, 'index.tsx'); if (fs.existsSync(indexPath)) { components.push({ type: 'element', name: element.name, path: `components/${element.name}` }); } } }); } return components; } function formatIssue(issue, indent = ' ') { const icon = issue.type === 'error' ? '❌' : '⚠️'; let output = `${indent}${icon} [${issue.rule}] ${issue.message}`; if (issue.suggestion) { output += `\n${indent} 💡 ${issue.suggestion}`; } return output; } async function main() { console.log('\n🔍 扫描项目中的所有组件和页面...\n'); const components = getAllComponents(); if (components.length === 0) { console.log('❌ 未找到任何组件或页面\n'); process.exit(1); } console.log(`找到 ${components.length} 个组件/页面\n`); console.log('='.repeat(70)); let totalChecked = 0; let totalPassed = 0; let totalErrors = 0; let totalWarnings = 0; const failedComponents = []; for (const component of components) { totalChecked++; const displayName = `${component.type === 'page' ? '📄' : '🧩'} ${component.name}`; try { const result = await reviewCode(component.path); if (result.error) { console.log(`\n${displayName}`); console.log(` ❌ 检查失败: ${result.error}`); continue; } const errors = result.issues.filter(i => i.type === 'error'); const warnings = result.issues.filter(i => i.type === 'warning'); totalErrors += errors.length; totalWarnings += warnings.length; if (result.passed) { totalPassed++; console.log(`\n${displayName}`); console.log(` ✅ 通过`); } else { failedComponents.push({ component, result }); console.log(`\n${displayName}`); console.log(` ❌ 未通过 (${errors.length} 错误, ${warnings.length} 警告)`); // 只显示错误,不显示警告(简化输出) if (errors.length > 0) { errors.forEach(issue => { console.log(formatIssue(issue)); }); } } } catch (error) { console.log(`\n${displayName}`); console.log(` ❌ 检查失败: ${error.message}`); } } // 总结 console.log('\n' + '='.repeat(70)); console.log('\n📊 检查总结:\n'); console.log(` 总计: ${totalChecked} 个组件/页面`); console.log(` 通过: ${totalPassed} 个 ✅`); console.log(` 失败: ${totalChecked - totalPassed} 个 ❌`); console.log(` 错误: ${totalErrors} 个`); console.log(` 警告: ${totalWarnings} 个`); if (failedComponents.length > 0) { console.log('\n⚠️ 需要修复的组件:\n'); failedComponents.forEach(({ component }) => { console.log(` - ${component.path}`); }); } console.log('\n' + '='.repeat(70) + '\n'); if (totalPassed === totalChecked) { console.log('✅ 所有组件都符合规范!\n'); } else { console.log('⚠️ 部分组件需要修复,请查看上面的详细信息。\n'); console.log('💡 使用以下命令查看单个组件的详细问题:'); console.log(' node scripts/code-review.js \n'); process.exit(1); } } // 检查服务器 function checkServer() { return new Promise((resolve) => { const req = http.get(`http://${HOST}:${PORT}/api/version`, (res) => { resolve(true); }); req.on('error', () => { resolve(false); }); req.setTimeout(2000, () => { req.destroy(); resolve(false); }); }); } (async () => { const serverRunning = await checkServer(); if (!serverRunning) { console.error('\n❌ 错误:开发服务器未运行'); console.log('\n请先启动开发服务器:'); console.log(' npm run dev\n'); process.exit(1); } await main(); })();