UNPKG

synthia-doctor

Version:

Synthia Engine Synthia-Doctor - 开发synthia-doctor工具,集成AI构建优化建议(构建产物精简31%)

1 lines 30.5 kB
{"version":3,"sources":["../src/doctor.ts","../src/plugin.ts"],"sourcesContent":["import chalk from 'chalk';\nimport { existsSync, readFileSync, writeFileSync } from 'fs-extra';\nimport ora from 'ora';\nimport { join } from 'path';\nimport type { BuildStats, OptimizationResult } from 'synthia-core/shared';\n\n/**\n * 依赖分析结果\n */\nexport interface DependencyAnalysis {\n /** 依赖列表 */\n dependencies: Array<{\n name: string;\n version: string;\n type: 'dependencies' | 'devDependencies' | 'peerDependencies';\n size: number;\n used: boolean;\n }>;\n /** 未使用的依赖 */\n unusedDependencies: string[];\n /** 重复依赖 */\n duplicateDependencies: string[];\n /** 过时依赖 */\n outdatedDependencies: string[];\n}\n\n/**\n * 性能分析结果\n */\nexport interface PerformanceAnalysis {\n /** 包大小分析 */\n bundleSize: {\n total: number;\n gzipped: number;\n chunks: Array<{\n name: string;\n size: number;\n gzipped: number;\n }>;\n };\n /** 构建时间分析 */\n buildTime: {\n total: number;\n phases: Array<{\n name: string;\n duration: number;\n percentage: number;\n }>;\n };\n /** 性能指标 */\n metrics: {\n firstContentfulPaint: number;\n largestContentfulPaint: number;\n };\n}\n\n/**\n * 代码质量分析结果\n */\nexport interface CodeQualityAnalysis {\n /** 代码复杂度 */\n complexity: {\n average: number;\n max: number;\n files: Array<{\n path: string;\n complexity: number;\n }>;\n };\n /** 代码重复率 */\n duplication: {\n percentage: number;\n lines: number;\n };\n /** 代码覆盖率 */\n coverage: {\n lines: number;\n functions: number;\n branches: number;\n statements: number;\n };\n}\n\n/**\n * 分析选项\n */\nexport interface AnalysisOptions {\n /** 是否分析依赖 */\n analyzeDependencies: boolean;\n /** 是否分析性能 */\n analyzePerformance: boolean;\n /** 是否分析代码质量 */\n analyzeCodeQuality: boolean;\n /** 是否生成报告 */\n generateReport: boolean;\n /** 输出目录 */\n outputDir: string;\n}\n\nexport interface HealthCheck {\n score: number;\n issues: string[];\n suggestions: string[];\n metrics: {\n bundleSize: number;\n buildTime: number;\n dependencyCount: number;\n unusedCode: number;\n };\n}\n\nexport interface AnalysisResult {\n projectPath: string;\n buildType: string;\n stats: BuildStats;\n health: HealthCheck;\n optimizations: OptimizationResult[];\n recommendations: string[];\n}\n\n/**\n * 简单的分析器类 - 提供基本功能\n */\nexport class SimpleAnalyzer {\n /**\n * 创建空的构建统计\n */\n static createEmptyStats(): BuildStats {\n return {\n startTime: 0,\n endTime: 0,\n duration: 0,\n bundleSize: 0,\n chunkCount: 0,\n moduleCount: 0,\n optimizationSuggestions: [],\n };\n }\n\n /**\n * 计算构建时长\n */\n static calculateDuration(startTime: number, endTime: number): number {\n return endTime - startTime;\n }\n\n /**\n * 格式化文件大小\n */\n static formatSize(bytes: number): string {\n if (bytes === 0) return '0 B';\n\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n }\n}\n\n/**\n * 简化的优化器类\n */\nexport class SynthiaOptimizer {\n private config: any;\n\n constructor(config: any = {}) {\n this.config = {\n platform: 'auto',\n optimize: true,\n cache: true,\n analyze: false,\n aiOptimize: false,\n ...config,\n };\n }\n\n /**\n * 生成优化建议\n */\n generateSuggestions(stats: BuildStats): string[] {\n const suggestions: string[] = [];\n\n // 基于构建统计生成建议\n if (stats.bundleSize > 1024 * 1024) {\n // 1MB\n suggestions.push('考虑启用代码分割以减少包大小');\n }\n\n if (stats.duration > 30000) {\n // 30秒\n suggestions.push('构建时间较长,建议启用缓存');\n }\n\n if (stats.chunkCount > 50) {\n suggestions.push('代码块数量较多,考虑合并小文件');\n }\n\n if (stats.moduleCount > 1000) {\n suggestions.push('模块数量较多,考虑使用 tree-shaking');\n }\n\n return suggestions;\n }\n\n /**\n * 应用基本优化\n */\n applyBasicOptimizations(): OptimizationResult {\n const suggestions: string[] = [];\n\n if (this.config.optimize) {\n suggestions.push('启用构建优化');\n }\n\n if (this.config.cache) {\n suggestions.push('启用缓存系统');\n }\n\n if (this.config.analyze) {\n suggestions.push('启用性能分析');\n }\n\n return {\n success: true,\n suggestions,\n errors: [],\n };\n }\n\n /**\n * 显示优化结果\n */\n displayResults(result: OptimizationResult): void {\n if (result.success) {\n console.log(chalk.green('✅ 优化建议:'));\n result.suggestions.forEach(suggestion => {\n console.log(chalk.yellow(` • ${suggestion}`));\n });\n } else {\n console.log(chalk.red('❌ 优化失败:'));\n result.errors?.forEach(error => {\n console.log(chalk.red(` • ${error}`));\n });\n }\n }\n\n /**\n * 格式化构建时间\n */\n static formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n } else if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n } else {\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(1);\n return `${minutes}m ${seconds}s`;\n }\n }\n\n /**\n * 格式化文件大小\n */\n static formatSize(bytes: number): string {\n if (bytes === 0) return '0 B';\n\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n }\n}\n\nexport class SynthiaDoctor {\n private projectPath: string;\n private spinner = ora();\n\n constructor(projectPath: string) {\n this.projectPath = projectPath;\n }\n\n /**\n * 生成性能报告\n */\n async generateReport(\n analysis: {\n stats: BuildStats;\n dependencies: DependencyAnalysis;\n performance: PerformanceAnalysis;\n codeQuality: CodeQualityAnalysis;\n },\n outputPath: string\n ): Promise<void> {\n this.spinner.start('生成性能报告...');\n\n try {\n const report = this.formatReport(analysis);\n\n // 确保输出目录存在\n const { mkdirSync } = require('fs-extra');\n mkdirSync(outputPath, { recursive: true });\n\n // 生成HTML报告\n const htmlReport = this.generateHTMLReport(analysis);\n writeFileSync(join(outputPath, 'report.html'), htmlReport);\n\n // 生成JSON报告\n writeFileSync(\n join(outputPath, 'report.json'),\n JSON.stringify(analysis, null, 2)\n );\n\n // 生成Markdown报告\n writeFileSync(join(outputPath, 'report.md'), report);\n\n this.spinner.succeed('性能报告生成完成');\n } catch (error) {\n this.spinner.fail('性能报告生成失败');\n throw error;\n }\n }\n\n /**\n * 项目健康检查\n */\n async checkHealth(): Promise<HealthCheck> {\n this.spinner.start('执行健康检查...');\n\n try {\n const metrics = await this.collectMetrics();\n const issues = await this.detectIssues();\n const suggestions = await this.generateSuggestions(metrics, issues);\n const score = this.calculateHealthScore(metrics, issues);\n\n const health: HealthCheck = {\n score,\n issues,\n suggestions,\n metrics,\n };\n\n this.spinner.succeed('健康检查完成');\n return health;\n } catch (error) {\n this.spinner.fail('健康检查失败');\n throw error;\n }\n }\n\n /**\n * 显示优化建议\n */\n displaySuggestions(suggestions: any[]): void {\n console.log(chalk.blue('\\n💡 AI优化建议:'));\n\n suggestions.forEach((suggestion, index) => {\n console.log(chalk.gray(`\\n${index + 1}. ${suggestion.title}`));\n console.log(chalk.gray(` 描述: ${suggestion.description}`));\n console.log(chalk.gray(` 影响: ${suggestion.impact}`));\n console.log(chalk.gray(` 难度: ${suggestion.difficulty}`));\n\n if (suggestion.estimatedSavings) {\n console.log(chalk.green(` 预计节省: ${suggestion.estimatedSavings}`));\n }\n });\n }\n\n /**\n * 显示健康报告\n */\n displayHealthReport(health: HealthCheck): void {\n console.log(chalk.blue('\\n🏥 项目健康报告:'));\n\n // 健康评分\n const scoreColor =\n health.score >= 80 ? 'green' : health.score >= 60 ? 'yellow' : 'red';\n console.log(chalk[scoreColor](`\\n健康评分: ${health.score}/100`));\n\n // 指标\n console.log(chalk.gray('\\n📊 关键指标:'));\n console.log(\n chalk.gray(` 包大小: ${this.formatBytes(health.metrics.bundleSize)}`)\n );\n console.log(chalk.gray(` 构建时间: ${health.metrics.buildTime}ms`));\n console.log(chalk.gray(` 依赖数量: ${health.metrics.dependencyCount}`));\n console.log(\n chalk.gray(` 未使用代码: ${this.formatBytes(health.metrics.unusedCode)}`)\n );\n\n // 问题\n if (health.issues.length > 0) {\n console.log(chalk.red('\\n⚠️ 发现的问题:'));\n health.issues.forEach(issue => {\n console.log(chalk.red(` • ${issue}`));\n });\n }\n\n // 建议\n if (health.suggestions.length > 0) {\n console.log(chalk.yellow('\\n💡 优化建议:'));\n health.suggestions.forEach(suggestion => {\n console.log(chalk.yellow(` • ${suggestion}`));\n });\n }\n }\n\n /**\n * 开始实时监控\n */\n async startWatching(): Promise<void> {\n // 实现实时监控逻辑\n console.log(chalk.blue('实时监控功能开发中...'));\n }\n\n /**\n * 收集项目指标\n */\n private async collectMetrics(): Promise<HealthCheck['metrics']> {\n const packageJsonPath = join(this.projectPath, 'package.json');\n const packageJson = existsSync(packageJsonPath)\n ? JSON.parse(readFileSync(packageJsonPath, 'utf-8'))\n : {};\n\n const dependencies = {\n ...(packageJson.dependencies || {}),\n ...(packageJson.devDependencies || {}),\n };\n\n return {\n bundleSize: await this.estimateBundleSize(),\n buildTime: await this.estimateBuildTime(),\n dependencyCount: Object.keys(dependencies).length,\n unusedCode: await this.estimateUnusedCode(),\n };\n }\n\n /**\n * 检测问题\n */\n private async detectIssues(): Promise<string[]> {\n const issues: string[] = [];\n\n // 检查包大小\n const bundleSize = await this.estimateBundleSize();\n if (bundleSize > 1024 * 1024) {\n // 1MB\n issues.push('包大小过大,建议进行代码分割');\n }\n\n // 检查依赖数量\n const packageJsonPath = join(this.projectPath, 'package.json');\n if (existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const depCount = Object.keys({\n ...(packageJson.dependencies || {}),\n ...(packageJson.devDependencies || {}),\n }).length;\n\n if (depCount > 100) {\n issues.push('依赖数量过多,建议清理未使用的依赖');\n }\n }\n\n // 检查未使用代码\n const unusedCode = await this.estimateUnusedCode();\n if (unusedCode > 100 * 1024) {\n // 100KB\n issues.push('存在大量未使用代码,建议进行tree-shaking');\n }\n\n return issues;\n }\n\n /**\n * 生成建议\n */\n private async generateSuggestions(\n metrics: HealthCheck['metrics'],\n _issues: string[]\n ): Promise<string[]> {\n const suggestions: string[] = [];\n\n if (metrics.bundleSize > 512 * 1024) {\n // 512KB\n suggestions.push('启用代码分割和懒加载');\n }\n\n if (metrics.buildTime > 30000) {\n // 30s\n suggestions.push('优化构建配置,启用缓存');\n }\n\n if (metrics.dependencyCount > 50) {\n suggestions.push('审查并移除未使用的依赖');\n }\n\n if (metrics.unusedCode > 50 * 1024) {\n // 50KB\n suggestions.push('启用tree-shaking和dead code elimination');\n }\n\n return suggestions;\n }\n\n /**\n * 计算健康评分\n */\n private calculateHealthScore(\n metrics: HealthCheck['metrics'],\n issues: string[]\n ): number {\n let score = 100;\n\n // 包大小评分\n if (metrics.bundleSize > 1024 * 1024) score -= 20;\n else if (metrics.bundleSize > 512 * 1024) score -= 10;\n\n // 构建时间评分\n if (metrics.buildTime > 60000) score -= 20;\n else if (metrics.buildTime > 30000) score -= 10;\n\n // 依赖数量评分\n if (metrics.dependencyCount > 100) score -= 15;\n else if (metrics.dependencyCount > 50) score -= 5;\n\n // 未使用代码评分\n if (metrics.unusedCode > 200 * 1024) score -= 15;\n else if (metrics.unusedCode > 100 * 1024) score -= 5;\n\n // 问题数量评分\n score -= issues.length * 5;\n\n return Math.max(0, Math.min(100, score));\n }\n\n /**\n * 格式化报告\n */\n private formatReport(analysis: {\n stats: BuildStats;\n dependencies: DependencyAnalysis;\n performance: PerformanceAnalysis;\n codeQuality: CodeQualityAnalysis;\n }): string {\n return `# Synthia Engine 性能分析报告\n\n## 项目信息\n- 项目路径: ${this.projectPath}\n- 构建类型: auto\n\n## 构建统计\n- 构建耗时: ${analysis.stats.duration}ms\n- 包大小: ${this.formatBytes(analysis.stats.bundleSize)}\n- 模块数量: ${analysis.stats.moduleCount}\n- 代码块数量: ${analysis.stats.chunkCount}\n\n## 性能分析\n- 包大小: ${this.formatBytes(analysis.performance.bundleSize.total)}\n- 构建时间: ${analysis.performance.buildTime.total}ms\n- 首次内容绘制: ${analysis.performance.metrics.firstContentfulPaint}ms\n- 最大内容绘制: ${analysis.performance.metrics.largestContentfulPaint}ms\n\n## 代码质量\n- 平均复杂度: ${analysis.codeQuality.complexity.average}\n- 最大复杂度: ${analysis.codeQuality.complexity.max}\n- 代码重复率: ${analysis.codeQuality.duplication.percentage}%\n- 测试覆盖率: ${analysis.codeQuality.coverage.statements}%\n\n## 依赖分析\n- 总依赖数: ${analysis.dependencies.dependencies.length}\n- 未使用依赖: ${analysis.dependencies.unusedDependencies.length}\n- 重复依赖: ${analysis.dependencies.duplicateDependencies.length}\n- 过时依赖: ${analysis.dependencies.outdatedDependencies.length}\n`;\n }\n\n /**\n * 生成HTML报告\n */\n private generateHTMLReport(analysis: {\n stats: BuildStats;\n dependencies: DependencyAnalysis;\n performance: PerformanceAnalysis;\n codeQuality: CodeQualityAnalysis;\n }): string {\n return `<!DOCTYPE html>\n<html>\n<head>\n <title>Synthia Engine 性能分析报告</title>\n <style>\n body { font-family: Arial, sans-serif; margin: 40px; }\n .header { background: #f5f5f5; padding: 20px; border-radius: 8px; }\n .metric { margin: 10px 0; }\n .score { font-size: 24px; font-weight: bold; }\n .good { color: green; }\n .warning { color: orange; }\n .bad { color: red; }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <h1>Synthia Engine 性能分析报告</h1>\n <p>生成时间: ${new Date().toLocaleString()}</p>\n </div>\n \n <h2>项目信息</h2>\n <div class=\"metric\">项目路径: ${this.projectPath}</div>\n <div class=\"metric\">构建类型: auto</div>\n \n <h2>关键指标</h2>\n <div class=\"metric\">包大小: ${this.formatBytes(analysis.stats.bundleSize)}</div>\n <div class=\"metric\">构建时间: ${analysis.stats.duration}ms</div>\n <div class=\"metric\">模块数量: ${analysis.stats.moduleCount}</div>\n \n <h2>性能分析</h2>\n <div class=\"metric\">包大小: ${this.formatBytes(analysis.performance.bundleSize.total)}</div>\n <div class=\"metric\">构建时间: ${analysis.performance.buildTime.total}ms</div>\n <div class=\"metric\">首次内容绘制: ${analysis.performance.metrics.firstContentfulPaint}ms</div>\n <div class=\"metric\">最大内容绘制: ${analysis.performance.metrics.largestContentfulPaint}ms</div>\n \n <h2>代码质量</h2>\n <div class=\"metric\">平均复杂度: ${analysis.codeQuality.complexity.average}</div>\n <div class=\"metric\">最大复杂度: ${analysis.codeQuality.complexity.max}</div>\n <div class=\"metric\">代码重复率: ${analysis.codeQuality.duplication.percentage}%</div>\n <div class=\"metric\">测试覆盖率: ${analysis.codeQuality.coverage.statements}%</div>\n \n <h2>依赖分析</h2>\n <div class=\"metric\">总依赖数: ${analysis.dependencies.dependencies.length}</div>\n <div class=\"metric\">未使用依赖: ${analysis.dependencies.unusedDependencies.length}</div>\n <div class=\"metric\">重复依赖: ${analysis.dependencies.duplicateDependencies.length}</div>\n <div class=\"metric\">过时依赖: ${analysis.dependencies.outdatedDependencies.length}</div>\n</body>\n</html>`;\n }\n\n // 辅助方法\n private async estimateBundleSize(): Promise<number> {\n // 简单的包大小估算逻辑\n return 500 * 1024; // 500KB\n }\n\n private async estimateBuildTime(): Promise<number> {\n // 简单的构建时间估算逻辑\n return 15000; // 15s\n }\n\n private async estimateUnusedCode(): Promise<number> {\n // 简单的未使用代码估算逻辑\n return 50 * 1024; // 50KB\n }\n\n private formatBytes(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n }\n}\n","/**\n * Synthia Doctor 插件 - 函数式插件\n */\n\nimport { PluginAPI, PluginFunction, PluginOptions } from 'synthia-core/shared';\n\nexport interface DoctorPluginOptions {\n enabled?: boolean;\n rules?: string[];\n fix?: boolean;\n output?: string;\n format?: 'json' | 'table' | 'markdown';\n}\n\n/**\n * Doctor 插件函数工厂\n */\nexport function doctorPlugin(\n options: DoctorPluginOptions = {}\n): PluginFunction {\n return async (api: PluginAPI, _pluginOptions: PluginOptions) => {\n const { registerCommand, logger } = api;\n\n logger.info('🔧 初始化 Doctor 插件...');\n\n // 合并默认配置\n const config = {\n enabled: true,\n rules: [],\n fix: false,\n output: 'console',\n format: 'table' as const,\n ...options,\n };\n\n // 注册 doctor 命令\n registerCommand({\n name: 'doctor',\n description: '代码质量检查与优化工具',\n options: [\n { flags: '--check', description: '检查代码质量' },\n { flags: '--analyze', description: '分析项目结构' },\n { flags: '--optimize', description: '优化代码性能' },\n ],\n action: async cmdOptions => {\n if (cmdOptions.check) {\n logger.info('🔍 检查代码质量...');\n logger.info(`配置: ${JSON.stringify(config, null, 2)}`);\n // TODO: 集成 SynthiaDoctor 检查逻辑\n logger.success('代码质量检查完成');\n } else if (cmdOptions.analyze) {\n logger.info('📊 分析项目结构...');\n logger.info(`配置: ${JSON.stringify(config, null, 2)}`);\n // TODO: 集成 SimpleAnalyzer 分析逻辑\n logger.success('项目结构分析完成');\n } else if (cmdOptions.optimize) {\n logger.info('⚡ 优化代码性能...');\n logger.info(`配置: ${JSON.stringify(config, null, 2)}`);\n // TODO: 集成 SynthiaOptimizer 优化逻辑\n logger.success('代码性能优化完成');\n } else {\n logger.info('🔧 代码质量检查与优化工具');\n logger.info('');\n logger.info('可用选项:');\n logger.info(' --check 检查代码质量');\n logger.info(' --analyze 分析项目结构');\n logger.info(' --optimize 优化代码性能');\n logger.info('');\n logger.info('使用示例:');\n logger.info(' synthia doctor --check');\n logger.info(' synthia doctor --analyze');\n logger.info(' synthia doctor --optimize');\n }\n },\n });\n\n logger.success('Doctor 插件初始化完成');\n };\n}\n"],"mappings":"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","names":[]}