vite-plugin-ai-perf-analyzer 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dependency-analyzer.ts","../src/history-analyzer.ts","../src/optimization-examples.ts","../src/analyzer.ts","../src/reporter.ts","../src/index.ts"],"names":["path","fs","pc"],"mappings":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kDAAA,EAuPe,OAAO,SAAS,CAAA;AAAA;;AAAA;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","file":"index.mjs","sourcesContent":["/**\r\n * 依赖分析器\r\n */\r\n\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport type { BundleInfo, DependencyInfo } from \"./types\";\r\n\r\nexport class DependencyAnalyzer {\r\n /**\r\n * 分析依赖\r\n */\r\n analyzeDependencies(bundles: BundleInfo[]): {\r\n total: number;\r\n duplicates: DependencyInfo[];\r\n largest: DependencyInfo[];\r\n } {\r\n const jsFiles = bundles.filter((b) => b.type === \"javascript\");\r\n const dependencies = this.extractDependencies(jsFiles);\r\n\r\n // 检测重复依赖\r\n const duplicates = this.findDuplicates(dependencies);\r\n\r\n // 找出最大的依赖\r\n const largest = [...dependencies]\r\n .sort((a, b) => b.size - a.size)\r\n .slice(0, 10);\r\n\r\n return {\r\n total: dependencies.length,\r\n duplicates,\r\n largest,\r\n };\r\n }\r\n\r\n /**\r\n * 从 JS 文件中提取依赖信息\r\n */\r\n private extractDependencies(jsFiles: BundleInfo[]): DependencyInfo[] {\r\n const depMap = new Map<string, DependencyInfo>();\r\n\r\n jsFiles.forEach((file) => {\r\n // 尝试解析文件内容,提取依赖\r\n const imports = this.parseImports(file);\r\n\r\n imports.forEach((depName) => {\r\n if (!depMap.has(depName)) {\r\n depMap.set(depName, {\r\n name: depName,\r\n size: 0,\r\n usedBy: [],\r\n isDuplicate: false,\r\n });\r\n }\r\n\r\n const dep = depMap.get(depName)!;\r\n dep.usedBy.push(file.name);\r\n // 估算依赖大小(简化处理)\r\n dep.size += file.size / imports.length;\r\n });\r\n });\r\n\r\n return Array.from(depMap.values());\r\n }\r\n\r\n /**\r\n * 解析文件中的 import 语句\r\n */\r\n private parseImports(file: BundleInfo): string[] {\r\n const imports: string[] = [];\r\n\r\n try {\r\n const distDir = path.resolve(process.cwd(), \"dist\");\r\n const filePath = path.join(distDir, file.path);\r\n\r\n if (!fs.existsSync(filePath)) {\r\n return imports;\r\n }\r\n\r\n const content = fs.readFileSync(filePath, \"utf-8\");\r\n\r\n // 匹配常见的依赖模式\r\n const patterns = [\r\n // node_modules 依赖\r\n /from\\s+[\"']([^\"']+)[\"']/g,\r\n /require\\([\"']([^\"']+)[\"']\\)/g,\r\n // Vite 特殊标记\r\n /__vite_ssr_import__\\(\"([^\"]+)\"\\)/g,\r\n ];\r\n\r\n patterns.forEach((pattern) => {\r\n let match;\r\n while ((match = pattern.exec(content)) !== null) {\r\n const depName = match[1];\r\n // 只保留 node_modules 依赖\r\n if (!depName.startsWith(\".\") && !depName.startsWith(\"/\")) {\r\n // 提取包名(去掉子路径)\r\n const pkgName = depName\r\n .split(\"/\")\r\n .slice(0, depName.startsWith(\"@\") ? 2 : 1)\r\n .join(\"/\");\r\n if (!imports.includes(pkgName)) {\r\n imports.push(pkgName);\r\n }\r\n }\r\n }\r\n });\r\n } catch (error) {\r\n // 忽略解析错误\r\n }\r\n\r\n return imports;\r\n }\r\n\r\n /**\r\n * 查找重复打包的依赖\r\n */\r\n private findDuplicates(dependencies: DependencyInfo[]): DependencyInfo[] {\r\n return dependencies\r\n .filter((dep) => dep.usedBy.length > 1)\r\n .map((dep) => ({\r\n ...dep,\r\n isDuplicate: true,\r\n }))\r\n .sort((a, b) => b.usedBy.length - a.usedBy.length)\r\n .slice(0, 10);\r\n }\r\n}\r\n","/**\r\n * 历史对比分析器\r\n */\r\n\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport type {\r\n BundleInfo,\r\n HistoryComparison,\r\n HistoryRecord,\r\n ComparisonResult,\r\n} from \"./types\";\r\n\r\nexport class HistoryAnalyzer {\r\n private historyFile: string;\r\n\r\n constructor() {\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n this.historyFile = path.join(reportsDir, \".perf-history.json\");\r\n }\r\n\r\n /**\r\n * 对比当前构建与历史记录\r\n */\r\n compare(\r\n currentBundles: BundleInfo[],\r\n currentTotalSize: number,\r\n currentFileCount: number\r\n ): HistoryComparison | undefined {\r\n const history = this.loadHistory();\r\n\r\n if (history.length === 0) {\r\n // 没有历史记录,保存当前记录\r\n this.saveHistory(currentBundles, currentTotalSize, currentFileCount);\r\n return undefined;\r\n }\r\n\r\n // 获取上一次记录\r\n const previous = history[history.length - 1];\r\n\r\n // 对比总大小\r\n const totalSize = this.compareValue(currentTotalSize, previous.totalSize);\r\n\r\n // 对比文件数量\r\n const fileCount = this.compareValue(currentFileCount, previous.fileCount);\r\n\r\n // 对比最大文件变化\r\n const largestFileChanges = this.compareLargestFiles(\r\n currentBundles,\r\n previous.files\r\n );\r\n\r\n // 检测新增和删除的文件\r\n const currentFileNames = new Set(currentBundles.map((b) => b.name));\r\n const previousFileNames = new Set(previous.files.map((f) => f.name));\r\n\r\n const newFiles = currentBundles\r\n .filter((b) => !previousFileNames.has(b.name))\r\n .map((b) => b.name);\r\n\r\n const removedFiles = previous.files\r\n .filter((f) => !currentFileNames.has(f.name))\r\n .map((f) => f.name);\r\n\r\n // 保存当前记录\r\n this.saveHistory(currentBundles, currentTotalSize, currentFileCount);\r\n\r\n return {\r\n totalSize,\r\n fileCount,\r\n largestFileChanges,\r\n newFiles,\r\n removedFiles,\r\n };\r\n }\r\n\r\n /**\r\n * 对比数值\r\n */\r\n private compareValue(current: number, previous: number): ComparisonResult {\r\n const diff = current - previous;\r\n const diffPercent = previous === 0 ? 0 : (diff / previous) * 100;\r\n\r\n let trend: \"increased\" | \"decreased\" | \"unchanged\";\r\n if (Math.abs(diffPercent) < 1) {\r\n trend = \"unchanged\";\r\n } else if (diff > 0) {\r\n trend = \"increased\";\r\n } else {\r\n trend = \"decreased\";\r\n }\r\n\r\n return {\r\n current,\r\n previous,\r\n diff,\r\n diffPercent,\r\n trend,\r\n };\r\n }\r\n\r\n /**\r\n * 对比最大文件的变化\r\n */\r\n private compareLargestFiles(\r\n currentBundles: BundleInfo[],\r\n previousFiles: Array<{ name: string; size: number }>\r\n ): Array<{\r\n name: string;\r\n current: number;\r\n previous: number;\r\n diff: number;\r\n }> {\r\n const changes: Array<{\r\n name: string;\r\n current: number;\r\n previous: number;\r\n diff: number;\r\n }> = [];\r\n\r\n // 创建文件映射\r\n const previousMap = new Map(previousFiles.map((f) => [f.name, f.size]));\r\n\r\n currentBundles.forEach((bundle) => {\r\n const previousSize = previousMap.get(bundle.name);\r\n if (previousSize !== undefined) {\r\n const diff = bundle.size - previousSize;\r\n // 只记录变化超过 10KB 的文件\r\n if (Math.abs(diff) > 10 * 1024) {\r\n changes.push({\r\n name: bundle.name,\r\n current: bundle.size,\r\n previous: previousSize,\r\n diff,\r\n });\r\n }\r\n }\r\n });\r\n\r\n // 按变化幅度排序\r\n return changes\r\n .sort((a, b) => Math.abs(b.diff) - Math.abs(a.diff))\r\n .slice(0, 10);\r\n }\r\n\r\n /**\r\n * 加载历史记录\r\n */\r\n private loadHistory(): HistoryRecord[] {\r\n if (!fs.existsSync(this.historyFile)) {\r\n return [];\r\n }\r\n\r\n try {\r\n const content = fs.readFileSync(this.historyFile, \"utf-8\");\r\n const history = JSON.parse(content);\r\n // 只保留最近 10 次记录\r\n return history.slice(-10);\r\n } catch (error) {\r\n console.warn(\"⚠️ 无法读取历史记录\");\r\n return [];\r\n }\r\n }\r\n\r\n /**\r\n * 保存历史记录\r\n */\r\n private saveHistory(\r\n bundles: BundleInfo[],\r\n totalSize: number,\r\n fileCount: number\r\n ): void {\r\n const history = this.loadHistory();\r\n\r\n const record: HistoryRecord = {\r\n timestamp: new Date().toISOString(),\r\n totalSize,\r\n fileCount,\r\n files: bundles.map((b) => ({\r\n name: b.name,\r\n size: b.size,\r\n })),\r\n };\r\n\r\n history.push(record);\r\n\r\n // 确保目录存在\r\n const dir = path.dirname(this.historyFile);\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n\r\n // 只保留最近 10 次记录\r\n const recentHistory = history.slice(-10);\r\n\r\n fs.writeFileSync(\r\n this.historyFile,\r\n JSON.stringify(recentHistory, null, 2),\r\n \"utf-8\"\r\n );\r\n }\r\n\r\n /**\r\n * 清除历史记录\r\n */\r\n clearHistory(): void {\r\n if (fs.existsSync(this.historyFile)) {\r\n fs.unlinkSync(this.historyFile);\r\n }\r\n }\r\n}\r\n","/**\r\n * 优化示例生成器\r\n */\r\n\r\nimport type {\r\n OptimizationExample,\r\n PerformanceIssue,\r\n DependencyInfo,\r\n} from \"./types\";\r\n\r\nexport class OptimizationExamples {\r\n /**\r\n * 根据问题生成优化示例\r\n */\r\n generate(\r\n issues: PerformanceIssue[],\r\n duplicateDeps?: DependencyInfo[]\r\n ): OptimizationExample[] {\r\n const examples: OptimizationExample[] = [];\r\n\r\n // 代码分割示例\r\n if (issues.some((i) => i.type === \"size\")) {\r\n examples.push(this.getCodeSplittingExample());\r\n }\r\n\r\n // 重复依赖优化\r\n if (duplicateDeps && duplicateDeps.length > 0) {\r\n examples.push(this.getDependencyOptimizationExample(duplicateDeps));\r\n }\r\n\r\n // 压缩优化\r\n if (issues.some((i) => i.type === \"optimization\")) {\r\n examples.push(this.getCompressionExample());\r\n }\r\n\r\n // 图片优化\r\n if (issues.some((i) => i.description.includes(\"图片\"))) {\r\n examples.push(this.getImageOptimizationExample());\r\n }\r\n\r\n // 动态导入\r\n if (issues.some((i) => i.type === \"size\" && i.severity === \"high\")) {\r\n examples.push(this.getDynamicImportExample());\r\n }\r\n\r\n // Tree-shaking 优化\r\n examples.push(this.getTreeShakingExample());\r\n\r\n return examples;\r\n }\r\n\r\n /**\r\n * 代码分割示例\r\n */\r\n private getCodeSplittingExample(): OptimizationExample {\r\n return {\r\n title: \"配置代码分割\",\r\n description: \"将大文件拆分成多个小文件,提高加载性能\",\r\n priority: \"high\",\r\n impact: \"可减少 30-50% 的初始加载大小\",\r\n difficulty: \"简单\",\r\n code: {\r\n language: \"typescript\",\r\n content: `// vite.config.ts\r\nexport default defineConfig({\r\n build: {\r\n rollupOptions: {\r\n output: {\r\n manualChunks: {\r\n // 提取 Vue 核心库\r\n 'vue-vendor': ['vue', 'vue-router', 'pinia'],\r\n \r\n // 提取 UI 组件库\r\n 'ui-vendor': ['element-plus', '@element-plus/icons-vue'],\r\n \r\n // 提取工具库\r\n 'utils': ['lodash-es', 'dayjs', 'axios'],\r\n \r\n // 提取图表库(如果使用)\r\n 'charts': ['echarts', 'chart.js'],\r\n },\r\n \r\n // 自动分割大于 500KB 的文件\r\n chunkFileNames: (chunkInfo) => {\r\n const facadeModuleId = chunkInfo.facadeModuleId \r\n ? chunkInfo.facadeModuleId.split('/').pop() \r\n : 'chunk';\r\n return \\`js/\\${facadeModuleId}-[hash].js\\`;\r\n },\r\n },\r\n },\r\n \r\n // 设置 chunk 大小警告阈值\r\n chunkSizeWarningLimit: 500,\r\n },\r\n});`,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * 重复依赖优化示例\r\n */\r\n private getDependencyOptimizationExample(\r\n duplicates: DependencyInfo[]\r\n ): OptimizationExample {\r\n const topDuplicates = duplicates.slice(0, 3).map((d) => d.name);\r\n\r\n return {\r\n title: \"优化重复依赖\",\r\n description: `检测到 ${duplicates.length} 个重复打包的依赖,建议提取到公共 chunk`,\r\n priority: \"high\",\r\n impact: `可减少 ${(\r\n duplicates.reduce((sum, d) => sum + d.size, 0) /\r\n 1024 /\r\n 1024\r\n ).toFixed(2)}MB`,\r\n difficulty: \"简单\",\r\n code: {\r\n language: \"typescript\",\r\n content: `// vite.config.ts\r\nexport default defineConfig({\r\n build: {\r\n rollupOptions: {\r\n output: {\r\n manualChunks: {\r\n // 提取重复依赖到公共 chunk\r\n 'common-vendor': [\r\n ${topDuplicates.map((name) => `'${name}'`).join(\",\\n \")}\r\n ],\r\n },\r\n },\r\n },\r\n },\r\n \r\n // 或者使用自动分割策略\r\n optimizeDeps: {\r\n include: [\r\n ${topDuplicates.map((name) => `'${name}'`).join(\",\\n \")}\r\n ],\r\n },\r\n});`,\r\n },\r\n relatedFiles: duplicates.flatMap((d) => d.usedBy).slice(0, 5),\r\n };\r\n }\r\n\r\n /**\r\n * 压缩优化示例\r\n */\r\n private getCompressionExample(): OptimizationExample {\r\n return {\r\n title: \"启用 Gzip/Brotli 压缩\",\r\n description: \"使用压缩插件减少传输大小\",\r\n priority: \"medium\",\r\n impact: \"可减少 60-70% 的传输大小\",\r\n difficulty: \"简单\",\r\n code: {\r\n language: \"bash\",\r\n content: `# 1. 安装压缩插件\r\nnpm install vite-plugin-compression -D\r\n\r\n# 2. 配置插件\r\n# vite.config.ts\r\nimport viteCompression from 'vite-plugin-compression';\r\n\r\nexport default defineConfig({\r\n plugins: [\r\n // Gzip 压缩\r\n viteCompression({\r\n algorithm: 'gzip',\r\n ext: '.gz',\r\n threshold: 10240, // 大于 10KB 才压缩\r\n deleteOriginFile: false,\r\n }),\r\n \r\n // Brotli 压缩(可选,压缩率更高)\r\n viteCompression({\r\n algorithm: 'brotliCompress',\r\n ext: '.br',\r\n threshold: 10240,\r\n deleteOriginFile: false,\r\n }),\r\n ],\r\n});\r\n\r\n# 3. Nginx 配置(服务器端)\r\n# nginx.conf\r\ngzip on;\r\ngzip_types text/plain text/css application/json application/javascript;\r\ngzip_min_length 1024;`,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * 图片优化示例\r\n */\r\n private getImageOptimizationExample(): OptimizationExample {\r\n return {\r\n title: \"优化图片资源\",\r\n description: \"压缩图片并转换为现代格式\",\r\n priority: \"medium\",\r\n impact: \"可减少 50-80% 的图片大小\",\r\n difficulty: \"简单\",\r\n code: {\r\n language: \"bash\",\r\n content: `# 1. 安装图片优化插件\r\nnpm install vite-plugin-imagemin -D\r\n\r\n# 2. 配置插件\r\n# vite.config.ts\r\nimport viteImagemin from 'vite-plugin-imagemin';\r\n\r\nexport default defineConfig({\r\n plugins: [\r\n viteImagemin({\r\n // GIF 优化\r\n gifsicle: {\r\n optimizationLevel: 7,\r\n interlaced: false,\r\n },\r\n \r\n // PNG 优化\r\n optipng: {\r\n optimizationLevel: 7,\r\n },\r\n \r\n // JPEG 优化\r\n mozjpeg: {\r\n quality: 80,\r\n },\r\n \r\n // SVG 优化\r\n svgo: {\r\n plugins: [\r\n { name: 'removeViewBox', active: false },\r\n { name: 'removeEmptyAttrs', active: true },\r\n ],\r\n },\r\n \r\n // WebP 转换\r\n webp: {\r\n quality: 80,\r\n },\r\n }),\r\n ],\r\n});\r\n\r\n# 3. 使用 WebP 格式(HTML)\r\n<picture>\r\n <source srcset=\"image.webp\" type=\"image/webp\">\r\n <img src=\"image.jpg\" alt=\"description\">\r\n</picture>`,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * 动态导入示例\r\n */\r\n private getDynamicImportExample(): OptimizationExample {\r\n return {\r\n title: \"使用动态导入(懒加载)\",\r\n description: \"按需加载组件和路由,减少初始加载大小\",\r\n priority: \"high\",\r\n impact: \"可减少 40-60% 的初始加载大小\",\r\n difficulty: \"中等\",\r\n code: {\r\n language: \"typescript\",\r\n content: `// 1. 路由懒加载\r\n// router/index.ts\r\nconst routes = [\r\n {\r\n path: '/dashboard',\r\n name: 'Dashboard',\r\n // 使用动态导入\r\n component: () => import('@/views/Dashboard.vue'),\r\n },\r\n {\r\n path: '/settings',\r\n name: 'Settings',\r\n component: () => import('@/views/Settings.vue'),\r\n },\r\n];\r\n\r\n// 2. 组件懒加载\r\n// App.vue\r\n<script setup>\r\nimport { defineAsyncComponent } from 'vue';\r\n\r\n// 异步组件\r\nconst HeavyComponent = defineAsyncComponent(() =>\r\n import('./components/HeavyComponent.vue')\r\n);\r\n\r\n// 带加载状态的异步组件\r\nconst AsyncComponent = defineAsyncComponent({\r\n loader: () => import('./components/AsyncComponent.vue'),\r\n loadingComponent: LoadingSpinner,\r\n errorComponent: ErrorComponent,\r\n delay: 200,\r\n timeout: 3000,\r\n});\r\n</script>\r\n\r\n// 3. 条件加载\r\n<script setup>\r\nconst loadCharts = async () => {\r\n if (needCharts) {\r\n const { default: ECharts } = await import('echarts');\r\n // 使用 ECharts\r\n }\r\n};\r\n</script>`,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Tree-shaking 优化示例\r\n */\r\n private getTreeShakingExample(): OptimizationExample {\r\n return {\r\n title: \"优化 Tree-shaking\",\r\n description: \"确保未使用的代码被正确移除\",\r\n priority: \"medium\",\r\n impact: \"可减少 10-30% 的代码大小\",\r\n difficulty: \"中等\",\r\n code: {\r\n language: \"typescript\",\r\n content: `// 1. 使用 ES6 模块导入(支持 tree-shaking)\r\n// ❌ 不推荐\r\nimport _ from 'lodash';\r\nconst result = _.debounce(fn, 300);\r\n\r\n// ✅ 推荐\r\nimport { debounce } from 'lodash-es';\r\nconst result = debounce(fn, 300);\r\n\r\n// 2. 配置 package.json\r\n{\r\n \"sideEffects\": false, // 标记为无副作用\r\n // 或指定有副作用的文件\r\n \"sideEffects\": [\"*.css\", \"*.scss\"]\r\n}\r\n\r\n// 3. Vite 配置\r\n// vite.config.ts\r\nexport default defineConfig({\r\n build: {\r\n // 启用 tree-shaking\r\n minify: 'terser',\r\n terserOptions: {\r\n compress: {\r\n drop_console: true, // 移除 console\r\n drop_debugger: true, // 移除 debugger\r\n pure_funcs: ['console.log'], // 移除特定函数\r\n },\r\n },\r\n },\r\n});\r\n\r\n// 4. 避免副作用导入\r\n// ❌ 不推荐(会导入整个模块)\r\nimport 'some-library';\r\n\r\n// ✅ 推荐(明确导入需要的部分)\r\nimport { specificFunction } from 'some-library';`,\r\n },\r\n };\r\n }\r\n}\r\n","/**\r\n * 性能分析器\r\n */\r\n\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport { gzipSync } from \"zlib\";\r\nimport { ChatOpenAI } from \"@langchain/openai\";\r\nimport { HumanMessage, SystemMessage } from \"@langchain/core/messages\";\r\nimport type {\r\n AnalysisResult,\r\n BundleInfo,\r\n PerformanceIssue,\r\n AnalyzerOptions,\r\n} from \"./types\";\r\nimport { DependencyAnalyzer } from \"./dependency-analyzer\";\r\nimport { HistoryAnalyzer } from \"./history-analyzer\";\r\nimport { OptimizationExamples } from \"./optimization-examples\";\r\n\r\nexport class PerfAnalyzer {\r\n private llm: ChatOpenAI | null = null;\r\n private options: AnalyzerOptions;\r\n private depAnalyzer: DependencyAnalyzer;\r\n private historyAnalyzer: HistoryAnalyzer;\r\n private examplesGenerator: OptimizationExamples;\r\n\r\n constructor(options: AnalyzerOptions) {\r\n this.options = options;\r\n this.depAnalyzer = new DependencyAnalyzer();\r\n this.historyAnalyzer = new HistoryAnalyzer();\r\n this.examplesGenerator = new OptimizationExamples();\r\n\r\n if (options.apiKey) {\r\n this.llm = new ChatOpenAI({\r\n openAIApiKey: options.apiKey,\r\n configuration: { baseURL: options.apiUrl },\r\n modelName: options.model,\r\n temperature: 0.2,\r\n maxTokens: 4000,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * 分析构建产物\r\n */\r\n async analyze(): Promise<AnalysisResult> {\r\n const distDir = path.resolve(process.cwd(), \"dist\");\r\n\r\n if (!fs.existsSync(distDir)) {\r\n throw new Error(\"构建目录不存在,请先执行构建\");\r\n }\r\n\r\n // 收集文件信息\r\n const bundles = this.collectBundles(distDir);\r\n\r\n // 计算统计信息\r\n const summary = this.calculateSummary(bundles);\r\n\r\n // 依赖分析\r\n console.log(\"📦 正在分析依赖...\");\r\n const dependencies = this.depAnalyzer.analyzeDependencies(bundles);\r\n\r\n // 历史对比\r\n console.log(\"📊 正在对比历史记录...\");\r\n const comparison = this.historyAnalyzer.compare(\r\n bundles,\r\n summary.totalSize,\r\n summary.fileCount\r\n );\r\n\r\n // 检测性能问题\r\n const issues = this.detectIssues(bundles, summary, dependencies);\r\n\r\n // 生成基础建议\r\n const suggestions = this.generateSuggestions(issues);\r\n\r\n // 生成优化示例\r\n console.log(\"💡 正在生成优化示例...\");\r\n const optimizationExamples = this.examplesGenerator.generate(\r\n issues,\r\n dependencies.duplicates\r\n );\r\n\r\n // AI 分析(如果配置了 API Key)\r\n let aiAnalysis: string | undefined;\r\n if (this.llm) {\r\n console.log(\"🤖 正在使用 AI 分析性能...\\n\");\r\n aiAnalysis = await this.performAIAnalysis(\r\n bundles,\r\n summary,\r\n issues,\r\n dependencies,\r\n comparison\r\n );\r\n }\r\n\r\n return {\r\n timestamp: new Date().toLocaleString(\"zh-CN\"),\r\n summary,\r\n dependencies,\r\n comparison,\r\n issues,\r\n suggestions,\r\n optimizationExamples,\r\n aiAnalysis,\r\n };\r\n }\r\n\r\n /**\r\n * 收集构建产物信息\r\n */\r\n private collectBundles(dir: string, baseDir: string = dir): BundleInfo[] {\r\n const bundles: BundleInfo[] = [];\r\n const files = fs.readdirSync(dir);\r\n\r\n for (const file of files) {\r\n const filePath = path.join(dir, file);\r\n const stat = fs.statSync(filePath);\r\n\r\n if (stat.isDirectory()) {\r\n bundles.push(...this.collectBundles(filePath, baseDir));\r\n } else {\r\n const content = fs.readFileSync(filePath);\r\n const gzipSize = gzipSync(content).length;\r\n const relativePath = path.relative(baseDir, filePath);\r\n\r\n bundles.push({\r\n name: file,\r\n size: stat.size,\r\n gzipSize,\r\n type: this.getFileType(file),\r\n path: relativePath,\r\n });\r\n }\r\n }\r\n\r\n return bundles;\r\n }\r\n\r\n /**\r\n * 获取文件类型\r\n */\r\n private getFileType(filename: string): string {\r\n const ext = path.extname(filename).toLowerCase();\r\n const typeMap: Record<string, string> = {\r\n \".js\": \"javascript\",\r\n \".mjs\": \"javascript\",\r\n \".css\": \"stylesheet\",\r\n \".html\": \"html\",\r\n \".png\": \"image\",\r\n \".jpg\": \"image\",\r\n \".jpeg\": \"image\",\r\n \".gif\": \"image\",\r\n \".svg\": \"image\",\r\n \".webp\": \"image\",\r\n \".woff\": \"font\",\r\n \".woff2\": \"font\",\r\n \".ttf\": \"font\",\r\n \".eot\": \"font\",\r\n \".json\": \"data\",\r\n \".map\": \"sourcemap\",\r\n };\r\n return typeMap[ext] || \"other\";\r\n }\r\n\r\n /**\r\n * 计算统计信息\r\n */\r\n private calculateSummary(bundles: BundleInfo[]) {\r\n const totalSize = bundles.reduce((sum, b) => sum + b.size, 0);\r\n const totalGzipSize = bundles.reduce(\r\n (sum, b) => sum + (b.gzipSize || 0),\r\n 0\r\n );\r\n\r\n // 按大小排序,取前 10\r\n const largestFiles = [...bundles]\r\n .sort((a, b) => b.size - a.size)\r\n .slice(0, 10);\r\n\r\n // 按类型分组\r\n const byType: Record<string, { count: number; size: number }> = {};\r\n bundles.forEach((bundle) => {\r\n if (!byType[bundle.type]) {\r\n byType[bundle.type] = { count: 0, size: 0 };\r\n }\r\n byType[bundle.type].count++;\r\n byType[bundle.type].size += bundle.size;\r\n });\r\n\r\n return {\r\n totalSize,\r\n totalGzipSize,\r\n fileCount: bundles.length,\r\n largestFiles,\r\n byType,\r\n };\r\n }\r\n\r\n /**\r\n * 检测性能问题\r\n */\r\n private detectIssues(\r\n bundles: BundleInfo[],\r\n summary: any,\r\n dependencies?: {\r\n total: number;\r\n duplicates: DependencyInfo[];\r\n largest: DependencyInfo[];\r\n }\r\n ): PerformanceIssue[] {\r\n const issues: PerformanceIssue[] = [];\r\n const { threshold } = this.options;\r\n\r\n // 检查总大小\r\n const totalSizeMB = summary.totalSize / 1024 / 1024;\r\n if (threshold.totalSize && totalSizeMB > threshold.totalSize) {\r\n issues.push({\r\n type: \"size\",\r\n severity: \"high\",\r\n title: \"构建产物总大小过大\",\r\n description: `总大小 ${totalSizeMB.toFixed(2)}MB 超过阈值 ${\r\n threshold.totalSize\r\n }MB`,\r\n suggestion: \"考虑代码分割、tree-shaking、压缩等优化手段\",\r\n });\r\n }\r\n\r\n // 检查单个文件大小\r\n const largeBundles = bundles.filter(\r\n (b) => b.size / 1024 > (threshold.bundleSize || 500)\r\n );\r\n if (largeBundles.length > 0) {\r\n issues.push({\r\n type: \"size\",\r\n severity: \"medium\",\r\n title: \"存在过大的单个文件\",\r\n description: `发现 ${largeBundles.length} 个文件超过 ${threshold.bundleSize}KB`,\r\n files: largeBundles.map(\r\n (b) => `${b.name} (${(b.size / 1024).toFixed(2)}KB)`\r\n ),\r\n suggestion: \"考虑拆分大文件,使用动态导入或代码分割\",\r\n });\r\n }\r\n\r\n // 检查 chunk 数量\r\n const jsFiles = bundles.filter((b) => b.type === \"javascript\");\r\n if (threshold.chunkCount && jsFiles.length > threshold.chunkCount) {\r\n issues.push({\r\n type: \"count\",\r\n severity: \"low\",\r\n title: \"JavaScript 文件数量过多\",\r\n description: `共有 ${jsFiles.length} 个 JS 文件,超过阈值 ${threshold.chunkCount}`,\r\n suggestion: \"过多的文件会增加 HTTP 请求数,考虑合并小文件\",\r\n });\r\n }\r\n\r\n // 检查未压缩的图片\r\n const images = bundles.filter((b) => b.type === \"image\");\r\n const largeImages = images.filter((img) => img.size > 100 * 1024); // 100KB\r\n if (largeImages.length > 0) {\r\n issues.push({\r\n type: \"optimization\",\r\n severity: \"medium\",\r\n title: \"存在未优化的图片\",\r\n description: `发现 ${largeImages.length} 个大于 100KB 的图片`,\r\n files: largeImages.map(\r\n (img) => `${img.name} (${(img.size / 1024).toFixed(2)}KB)`\r\n ),\r\n suggestion: \"使用图片压缩工具,或转换为 WebP 格式\",\r\n });\r\n }\r\n\r\n // 检查 sourcemap\r\n const sourcemaps = bundles.filter((b) => b.type === \"sourcemap\");\r\n if (sourcemaps.length > 0) {\r\n const totalMapSize = sourcemaps.reduce((sum, m) => sum + m.size, 0);\r\n issues.push({\r\n type: \"optimization\",\r\n severity: \"low\",\r\n title: \"生产环境包含 sourcemap\",\r\n description: `Sourcemap 文件占用 ${(totalMapSize / 1024 / 1024).toFixed(\r\n 2\r\n )}MB`,\r\n suggestion: \"生产环境建议禁用 sourcemap 或使用外部 sourcemap\",\r\n });\r\n }\r\n\r\n // 检查重复依赖\r\n if (dependencies && dependencies.duplicates.length > 0) {\r\n const topDuplicates = dependencies.duplicates.slice(0, 3);\r\n issues.push({\r\n type: \"dependency\",\r\n severity: \"medium\",\r\n title: \"检测到重复打包的依赖\",\r\n description: `发现 ${dependencies.duplicates.length} 个依赖被多次打包`,\r\n files: topDuplicates.map(\r\n (d) =>\r\n `${d.name} (被 ${d.usedBy.length} 个文件使用, ${(\r\n d.size / 1024\r\n ).toFixed(2)}KB)`\r\n ),\r\n suggestion: \"将重复依赖提取到公共 chunk 中\",\r\n });\r\n }\r\n\r\n return issues;\r\n }\r\n\r\n /**\r\n * 生成基础建议\r\n */\r\n private generateSuggestions(issues: PerformanceIssue[]): string[] {\r\n const suggestions: string[] = [];\r\n\r\n if (issues.some((i) => i.type === \"size\")) {\r\n suggestions.push(\"启用 gzip/brotli 压缩\");\r\n suggestions.push(\"配置 Vite 的 build.rollupOptions 进行代码分割\");\r\n suggestions.push(\"使用 vite-plugin-compression 插件\");\r\n }\r\n\r\n if (issues.some((i) => i.type === \"optimization\")) {\r\n suggestions.push(\"使用 vite-plugin-imagemin 优化图片\");\r\n suggestions.push(\"配置 CSS 压缩和 tree-shaking\");\r\n }\r\n\r\n if (issues.length === 0) {\r\n suggestions.push(\"构建产物已经很优秀,继续保持!\");\r\n }\r\n\r\n return suggestions;\r\n }\r\n\r\n /**\r\n * AI 性能分析\r\n */\r\n private async performAIAnalysis(\r\n bundles: BundleInfo[],\r\n summary: any,\r\n issues: PerformanceIssue[],\r\n dependencies?: {\r\n total: number;\r\n duplicates: DependencyInfo[];\r\n largest: DependencyInfo[];\r\n },\r\n comparison?: any\r\n ): Promise<string> {\r\n const systemPrompt = new SystemMessage(\r\n \"你是一个专业的前端性能优化专家,精通 Vite、Webpack 等构建工具。请分析构建产物并提供专业的优化建议。\"\r\n );\r\n\r\n const bundlesSummary = summary.largestFiles\r\n .slice(0, 5)\r\n .map((b: BundleInfo) => `- ${b.name}: ${(b.size / 1024).toFixed(2)}KB`)\r\n .join(\"\\n\");\r\n\r\n const typesSummary = Object.entries(summary.byType)\r\n .map(\r\n ([type, info]: [string, any]) =>\r\n `- ${type}: ${info.count} 个文件, ${(info.size / 1024).toFixed(2)}KB`\r\n )\r\n .join(\"\\n\");\r\n\r\n const issuesSummary = issues\r\n .map(\r\n (issue) => `- [${issue.severity}] ${issue.title}: ${issue.description}`\r\n )\r\n .join(\"\\n\");\r\n\r\n // 依赖分析摘要\r\n let dependencySummary = \"\";\r\n if (dependencies) {\r\n dependencySummary = `\r\n## 依赖分析\r\n- 总依赖数: ${dependencies.total}\r\n- 重复依赖: ${dependencies.duplicates.length} 个\r\n- 最大依赖: ${dependencies.largest\r\n .slice(0, 3)\r\n .map((d) => `${d.name} (${(d.size / 1024).toFixed(2)}KB)`)\r\n .join(\", \")}`;\r\n }\r\n\r\n // 历史对比摘要\r\n let comparisonSummary = \"\";\r\n if (comparison) {\r\n const sizeChange =\r\n comparison.totalSize.trend === \"increased\" ? \"增加\" : \"减少\";\r\n comparisonSummary = `\r\n## 历史对比\r\n- 总大小${sizeChange}: ${Math.abs(comparison.totalSize.diffPercent).toFixed(2)}%\r\n- 文件数量变化: ${comparison.fileCount.diff > 0 ? \"+\" : \"\"}${\r\n comparison.fileCount.diff\r\n }\r\n- 新增文件: ${comparison.newFiles.length} 个\r\n- 删除文件: ${comparison.removedFiles.length} 个`;\r\n }\r\n\r\n const userPrompt = new HumanMessage(`\r\n请分析以下构建产物信息:\r\n\r\n## 总体统计\r\n- 总大小: ${(summary.totalSize / 1024 / 1024).toFixed(2)}MB\r\n- Gzip 后: ${(summary.totalGzipSize / 1024 / 1024).toFixed(2)}MB\r\n- 文件数量: ${summary.fileCount}\r\n\r\n## 最大的文件\r\n${bundlesSummary}\r\n\r\n## 按类型分组\r\n${typesSummary}\r\n${dependencySummary}\r\n${comparisonSummary}\r\n\r\n## 检测到的问题\r\n${issuesSummary || \"无明显问题\"}\r\n\r\n请提供:\r\n1. 性能评估(3-5 句话)\r\n2. 具体优化建议(3-5 条,每条简洁明了)\r\n3. 优先级排序\r\n\r\n请用简洁专业的语言回答,不要过于冗长。\r\n`);\r\n\r\n const response = await this.llm!.invoke([systemPrompt, userPrompt]);\r\n return response.content.toString();\r\n }\r\n}\r\n","/**\r\n * 性能分析报告生成器\r\n */\r\n\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport pc from \"picocolors\";\r\nimport type { AnalysisResult, PerformanceIssue } from \"./types\";\r\n\r\nexport interface ReporterOptions {\r\n console?: boolean;\r\n html?: boolean;\r\n json?: boolean;\r\n}\r\n\r\nexport class PerfReporter {\r\n /**\r\n * 生成报告\r\n */\r\n async generate(\r\n result: AnalysisResult,\r\n options: ReporterOptions = {},\r\n ): Promise<void> {\r\n if (options.html) {\r\n await this.generateHTMLReport(result);\r\n }\r\n\r\n if (options.json) {\r\n await this.generateJSONReport(result);\r\n }\r\n }\r\n\r\n /**\r\n * 控制台输出\r\n */\r\n printConsole(result: AnalysisResult): void {\r\n console.log(\"\\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\");\r\n console.log(\"⚡ 性能分析报告\");\r\n console.log(\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n\");\r\n\r\n // 总体统计\r\n console.log(\"📊 总体统计:\");\r\n console.log(\r\n ` 总大小: ${(result.summary.totalSize / 1024 / 1024).toFixed(2)}MB`,\r\n );\r\n console.log(\r\n ` Gzip后: ${(result.summary.totalGzipSize / 1024 / 1024).toFixed(2)}MB`,\r\n );\r\n console.log(` 文件数: ${result.summary.fileCount}\\n`);\r\n\r\n // 历史对比\r\n if (result.comparison) {\r\n console.log(\"📈 历史对比:\");\r\n const { totalSize, fileCount, newFiles, removedFiles } =\r\n result.comparison;\r\n const sizeIcon = totalSize.trend === \"increased\" ? \"📈\" : \"📉\";\r\n console.log(\r\n ` ${sizeIcon} 总大小: ${totalSize.trend === \"increased\" ? \"+\" : \"\"}${(\r\n totalSize.diff /\r\n 1024 /\r\n 1024\r\n ).toFixed(2)}MB (${\r\n totalSize.diffPercent > 0 ? \"+\" : \"\"\r\n }${totalSize.diffPercent.toFixed(2)}%)`,\r\n );\r\n console.log(\r\n ` 📊 文件数: ${fileCount.diff > 0 ? \"+\" : \"\"}${fileCount.diff}`,\r\n );\r\n if (newFiles.length > 0) {\r\n console.log(` ✨ 新增: ${newFiles.slice(0, 3).join(\", \")}`);\r\n }\r\n if (removedFiles.length > 0) {\r\n console.log(` 🗑️ 删除: ${removedFiles.slice(0, 3).join(\", \")}`);\r\n }\r\n console.log();\r\n }\r\n\r\n // 依赖分析\r\n if (result.dependencies) {\r\n console.log(\"📦 依赖分析:\");\r\n console.log(` 总依赖数: ${result.dependencies.total}`);\r\n if (result.dependencies.duplicates.length > 0) {\r\n console.log(\r\n ` ⚠️ 重复依赖: ${result.dependencies.duplicates.length} 个`,\r\n );\r\n result.dependencies.duplicates.slice(0, 3).forEach((dep) => {\r\n console.log(\r\n ` - ${dep.name}: 被 ${dep.usedBy.length} 个文件使用`,\r\n );\r\n });\r\n }\r\n console.log();\r\n }\r\n\r\n // 最大文件\r\n console.log(\"📦 最大的文件:\");\r\n result.summary.largestFiles.slice(0, 5).forEach((file, index) => {\r\n console.log(\r\n ` ${index + 1}. ${file.name}: ${(file.size / 1024).toFixed(2)}KB`,\r\n );\r\n });\r\n console.log();\r\n\r\n // 按类型统计\r\n console.log(\"📋 按类型统计:\");\r\n Object.entries(result.summary.byType).forEach(([type, info]) => {\r\n console.log(\r\n ` ${type}: ${info.count} 个, ${(info.size / 1024).toFixed(2)}KB`,\r\n );\r\n });\r\n console.log();\r\n\r\n // 性能问题\r\n if (result.issues.length > 0) {\r\n console.log(\"⚠️ 性能问题:\");\r\n result.issues.forEach((issue, index) => {\r\n const icon = this.getSeverityIcon(issue.severity);\r\n console.log(` ${index + 1}. ${icon} ${issue.title}`);\r\n console.log(` ${issue.description}`);\r\n if (issue.suggestion) {\r\n console.log(` 💡 ${issue.suggestion}`);\r\n }\r\n });\r\n console.log();\r\n } else {\r\n console.log(\"✅ 未发现明显的性能问题\\n\");\r\n }\r\n\r\n // 优化建议\r\n if (result.suggestions.length > 0) {\r\n console.log(\"💡 优化建议:\");\r\n result.suggestions.forEach((suggestion, index) => {\r\n console.log(` ${index + 1}. ${suggestion}`);\r\n });\r\n console.log();\r\n }\r\n\r\n // 优化示例\r\n if (result.optimizationExamples && result.optimizationExamples.length > 0) {\r\n console.log(\"🔧 优化示例:\");\r\n result.optimizationExamples.slice(0, 3).forEach((example, index) => {\r\n console.log(` ${index + 1}. ${example.title} (${example.priority})`);\r\n console.log(` ${example.description}`);\r\n });\r\n console.log();\r\n }\r\n\r\n // AI 分析\r\n if (result.aiAnalysis) {\r\n console.log(\"🤖 AI 分析:\");\r\n console.log(\r\n result.aiAnalysis\r\n .split(\"\\n\")\r\n .map((line) => ` ${line}`)\r\n .join(\"\\n\"),\r\n );\r\n console.log();\r\n }\r\n\r\n console.log(\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n\");\r\n }\r\n\r\n /**\r\n * 生成 HTML 报告\r\n */\r\n private async generateHTMLReport(result: AnalysisResult): Promise<void> {\r\n const html = `\r\n<!DOCTYPE html>\r\n<html lang=\"zh-CN\">\r\n<head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>性能分析报告</title>\r\n <style>\r\n * { margin: 0; padding: 0; box-sizing: border-box; }\r\n body {\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n padding: 20px;\r\n min-height: 100vh;\r\n }\r\n .container {\r\n max-width: 1200px;\r\n margin: 0 auto;\r\n background: white;\r\n border-radius: 12px;\r\n box-shadow: 0 8px 32px rgba(0,0,0,0.2);\r\n overflow: hidden;\r\n }\r\n .header {\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n color: white;\r\n padding: 30px;\r\n text-align: center;\r\n }\r\n .header h1 {\r\n font-size: 32px;\r\n margin-bottom: 10px;\r\n }\r\n .header .time {\r\n font-size: 14px;\r\n opacity: 0.9;\r\n }\r\n .content {\r\n padding: 30px;\r\n }\r\n .section {\r\n margin-bottom: 30px;\r\n }\r\n .section-title {\r\n font-size: 20px;\r\n font-weight: bold;\r\n color: #333;\r\n margin-bottom: 15px;\r\n padding-bottom: 10px;\r\n border-bottom: 2px solid #667eea;\r\n }\r\n .stats-grid {\r\n display: grid;\r\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\r\n gap: 20px;\r\n margin-bottom: 20px;\r\n }\r\n .stat-card {\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n color: white;\r\n padding: 20px;\r\n border-radius: 12px;\r\n text-align: center;\r\n }\r\n .stat-value {\r\n font-size: 32px;\r\n font-weight: bold;\r\n margin: 10px 0;\r\n }\r\n .stat-label {\r\n font-size: 14px;\r\n opacity: 0.9;\r\n }\r\n .file-list {\r\n background: #f7fafc;\r\n border-radius: 8px;\r\n padding: 15px;\r\n }\r\n .file-item {\r\n display: flex;\r\n justify-content: space-between;\r\n padding: 10px;\r\n border-bottom: 1px solid #e2e8f0;\r\n }\r\n .file-item:last-child {\r\n border-bottom: none;\r\n }\r\n .file-name {\r\n font-family: monospace;\r\n color: #333;\r\n }\r\n .file-size {\r\n color: #667eea;\r\n font-weight: bold;\r\n }\r\n .issue {\r\n background: #fff5f5;\r\n border-left: 4px solid #f56565;\r\n padding: 15px;\r\n border-radius: 8px;\r\n margin-bottom: 15px;\r\n }\r\n .issue.medium {\r\n background: #fffaf0;\r\n border-left-color: #ed8936;\r\n }\r\n .issue.low {\r\n background: #f0f9ff;\r\n border-left-color: #4299e1;\r\n }\r\n .issue-title {\r\n font-weight: bold;\r\n color: #333;\r\n margin-bottom: 8px;\r\n }\r\n .issue-desc {\r\n color: #666;\r\n margin-bottom: 8px;\r\n }\r\n .issue-suggestion {\r\n background: #e6fffa;\r\n padding: 10px;\r\n border-radius: 6px;\r\n margin-top: 10px;\r\n color: #234e52;\r\n }\r\n .suggestion-list {\r\n background: #f0fdf4;\r\n border-radius: 8px;\r\n padding: 15px;\r\n }\r\n .suggestion-item {\r\n padding: 10px;\r\n border-bottom: 1px solid #d1fae5;\r\n color: #065f46;\r\n }\r\n .suggestion-item:last-child {\r\n border-bottom: none;\r\n }\r\n .ai-analysis {\r\n background: #f0f9ff;\r\n border-left: 4px solid #3b82f6;\r\n padding: 20px;\r\n border-radius: 8px;\r\n line-height: 1.8;\r\n color: #1e40af;\r\n white-space: pre-wrap;\r\n }\r\n .footer {\r\n background: #f7fafc;\r\n padding: 20px;\r\n text-align: center;\r\n color: #718096;\r\n font-size: 14px;\r\n }\r\n .trend-up {\r\n background: linear-gradient(135deg, #f56565 0%, #ed8936 100%) !important;\r\n }\r\n .trend-down {\r\n background: linear-gradient(135deg, #48bb78 0%, #38a169 100%) !important;\r\n }\r\n .optimization-example {\r\n background: #f7fafc;\r\n border-radius: 12px;\r\n padding: 20px;\r\n margin-bottom: 20px;\r\n border: 1px solid #e2e8f0;\r\n }\r\n .example-header {\r\n margin-bottom: 15px;\r\n }\r\n .example-title {\r\n font-size: 18px;\r\n font-weight: bold;\r\n color: #333;\r\n margin-bottom: 8px;\r\n display: flex;\r\n align-items: center;\r\n gap: 10px;\r\n }\r\n .priority-badge {\r\n font-size: 12px;\r\n padding: 4px 12px;\r\n border-radius: 12px;\r\n font-weight: normal;\r\n }\r\n .priority-high {\r\n background: #fed7d7;\r\n color: #c53030;\r\n }\r\n .priority-medium {\r\n background: #feebc8;\r\n color: #c05621;\r\n }\r\n .priority-low {\r\n background: #bee3f8;\r\n color: #2c5282;\r\n }\r\n .example-meta {\r\n display: flex;\r\n gap: 15px;\r\n font-size: 14px;\r\n color: #666;\r\n }\r\n .example-desc {\r\n color: #666;\r\n margin-bottom: 15px;\r\n line-height: 1.6;\r\n }\r\n .code-block {\r\n background: #1e293b;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n margin-top: 10px;\r\n }\r\n .code-header {\r\n background: #334155;\r\n color: #94a3b8;\r\n padding: 8px 15px;\r\n font-size: 12px;\r\n font-family: monospace;\r\n }\r\n .code-block pre {\r\n margin: 0;\r\n padding: 15px;\r\n overflow-x: auto;\r\n }\r\n .code-block code {\r\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\r\n font-size: 13px;\r\n line-height: 1.6;\r\n color: #e2e8f0;\r\n }\r\n .related-files {\r\n margin-top: 15px;\r\n padding: 10px;\r\n background: #e6fffa;\r\n border-radius: 6px;\r\n font-size: 14px;\r\n color: #234e52;\r\n }\r\n </style>\r\n</head>\r\n<body>\r\n <div class=\"container\">\r\n <div class=\"header\">\r\n <h1>⚡ 性能分析报告</h1>\r\n <div class=\"time\">生成时间: ${result.timestamp}</div>\r\n </div>\r\n\r\n <div class=\"content\">\r\n <!-- 总体统计 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">📊 总体统计</div>\r\n <div class=\"stats-grid\">\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">总大小</div>\r\n <div class=\"stat-value\">${(\r\n result.summary.totalSize /\r\n 1024 /\r\n 1024\r\n ).toFixed(2)}MB</div>\r\n </div>\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">Gzip 后</div>\r\n <div class=\"stat-value\">${(\r\n result.summary.totalGzipSize /\r\n 1024 /\r\n 1024\r\n ).toFixed(2)}MB</div>\r\n </div>\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">文件数量</div>\r\n <div class=\"stat-value\">${result.summary.fileCount}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- 最大文件 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">📦 最大的文件</div>\r\n <div class=\"file-list\">\r\n ${result.summary.largestFiles\r\n .slice(0, 10)\r\n .map(\r\n (file) => `\r\n <div class=\"file-item\">\r\n <span class=\"file-name\">${file.name}</span>\r\n <span class=\"file-size\">${(file.size / 1024).toFixed(2)}KB</span>\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n </div>\r\n\r\n <!-- 按类型统计 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">📋 按类型统计</div>\r\n <div class=\"file-list\">\r\n ${Object.entries(result.summary.byType)\r\n .map(\r\n ([type, info]) => `\r\n <div class=\"file-item\">\r\n <span class=\"file-name\">${type}</span>\r\n <span class=\"file-size\">${info.count} 个, ${(\r\n info.size / 1024\r\n ).toFixed(2)}KB</span>\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n </div>\r\n\r\n <!-- 历史对比 -->\r\n ${\r\n result.comparison\r\n ? `\r\n <div class=\"section\">\r\n <div class=\"section-title\">📈 历史对比</div>\r\n <div class=\"stats-grid\">\r\n <div class=\"stat-card ${\r\n result.comparison.totalSize.trend === \"increased\"\r\n ? \"trend-up\"\r\n : \"trend-down\"\r\n }\">\r\n <div class=\"stat-label\">总大小变化</div>\r\n <div class=\"stat-value\">${\r\n result.comparison.totalSize.diffPercent > 0 ? \"+\" : \"\"\r\n }${result.comparison.totalSize.diffPercent.toFixed(2)}%</div>\r\n <div class=\"stat-label\">${\r\n result.comparison.totalSize.trend === \"increased\" ? \"+\" : \"\"\r\n }${(result.comparison.totalSize.diff / 1024 / 1024).toFixed(\r\n 2,\r\n )}MB</div>\r\n </div>\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">文件数变化</div>\r\n <div class=\"stat-value\">${\r\n result.comparison.fileCount.diff > 0 ? \"+\" : \"\"\r\n }${result.comparison.fileCount.diff}</div>\r\n </div>\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">新增文件</div>\r\n <div class=\"stat-value\">${result.comparison.newFiles.length}</div>\r\n </div>\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">删除文件</div>\r\n <div class=\"stat-value\">${\r\n result.comparison.removedFiles.length\r\n }</div>\r\n </div>\r\n </div>\r\n ${\r\n result.comparison.largestFileChanges.length > 0\r\n ? `\r\n <div class=\"file-list\" style=\"margin-top: 15px;\">\r\n <div style=\"font-weight: bold; padding: 10px; color: #333;\">文件大小变化 Top 5:</div>\r\n ${result.comparison.largestFileChanges\r\n .slice(0, 5)\r\n .map(\r\n (change) => `\r\n <div class=\"file-item\">\r\n <span class=\"file-name\">${change.name}</span>\r\n <span class=\"file-size ${\r\n change.diff > 0 ? \"trend-up\" : \"trend-down\"\r\n }\">\r\n ${change.diff > 0 ? \"+\" : \"\"}${(change.diff / 1024).toFixed(\r\n 2,\r\n )}KB\r\n </span>\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n\r\n <!-- 依赖分析 -->\r\n ${\r\n result.dependencies\r\n ? `\r\n <div class=\"section\">\r\n <div class=\"section-title\">📦 依赖分析</div>\r\n <div class=\"stats-grid\">\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">总依赖数</div>\r\n <div class=\"stat-value\">${result.dependencies.total}</div>\r\n </div>\r\n <div class=\"stat-card ${\r\n result.dependencies.duplicates.length > 0 ? \"trend-up\" : \"\"\r\n }\">\r\n <div class=\"stat-label\">重复依赖</div>\r\n <div class=\"stat-value\">${\r\n result.dependencies.duplicates.length\r\n }</div>\r\n </div>\r\n </div>\r\n ${\r\n result.dependencies.duplicates.length > 0\r\n ? `\r\n <div class=\"file-list\" style=\"margin-top: 15px;\">\r\n <div style=\"font-weight: bold; padding: 10px; color: #333;\">重复打包的依赖:</div>\r\n ${result.dependencies.duplicates\r\n .slice(0, 10)\r\n .map(\r\n (dep) => `\r\n <div class=\"file-item\">\r\n <span class=\"file-name\">${dep.name}</span>\r\n <span class=\"file-size\">\r\n ${(dep.size / 1024).toFixed(2)}KB · 被 ${\r\n dep.usedBy.length\r\n } 个文件使用\r\n </span>\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n ${\r\n result.dependencies.largest.length > 0\r\n ? `\r\n <div class=\"file-list\" style=\"margin-top: 15px;\">\r\n <div style=\"font-weight: bold; padding: 10px; color: #333;\">最大的依赖:</div>\r\n ${result.dependencies.largest\r\n .slice(0, 10)\r\n .map(\r\n (dep) => `\r\n <div class=\"file-item\">\r\n <span class=\"file-name\">${dep.name}</span>\r\n <span class=\"file-size\">${(dep.size / 1024).toFixed(\r\n 2,\r\n )}KB</span>\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n\r\n <!-- 性能问题 -->\r\n ${\r\n result.issues.length > 0\r\n ? `\r\n <div class=\"section\">\r\n <div class=\"section-title\">⚠️ 性能问题</div>\r\n ${result.issues\r\n .map(\r\n (issue) => `\r\n <div class=\"issue ${issue.severity}\">\r\n <div class=\"issue-title\">${this.getSeverityIcon(\r\n issue.severity,\r\n )} ${issue.title}</div>\r\n <div class=\"issue-desc\">${issue.description}</div>\r\n ${\r\n issue.files\r\n ? `<div class=\"issue-desc\">相关文件: ${issue.files.join(\r\n \", \",\r\n )}</div>`\r\n : \"\"\r\n }\r\n ${\r\n issue.suggestion\r\n ? `<div class=\"issue-suggestion\">💡 ${issue.suggestion}</div>`\r\n : \"\"\r\n }\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n `\r\n : '<div class=\"section\"><div class=\"section-title\">✅ 未发现明显的性能问题</div></div>'\r\n }\r\n\r\n <!-- 优化建议 -->\r\n ${\r\n result.suggestions.length > 0\r\n ? `\r\n <div class=\"section\">\r\n <div class=\"section-title\">💡 优化建议</div>\r\n <div class=\"suggestion-list\">\r\n ${result.suggestions\r\n .map(\r\n (suggestion, index) => `\r\n <div class=\"suggestion-item\">${index + 1}. ${suggestion}</div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n\r\n <!-- 优化示例 -->\r\n ${\r\n result.optimizationExamples && result.optimizationExamples.length > 0\r\n ? `\r\n <div class=\"section\">\r\n <div class=\"section-title\">🔧 优化示例</div>\r\n ${result.optimizationExamples\r\n .map(\r\n (example) => `\r\n <div class=\"optimization-example\">\r\n <div class=\"example-header\">\r\n <div class=\"example-title\">\r\n ${example.title}\r\n <span class=\"priority-badge priority-${example.priority}\">${\r\n example.priority === \"high\"\r\n ? \"高优先级\"\r\n : example.priority === \"medium\"\r\n ? \"中优先级\"\r\n : \"低优先级\"\r\n }</span>\r\n </div>\r\n <div class=\"example-meta\">\r\n <span>💪 ${example.difficulty}</span>\r\n <span>📈 ${example.impact}</span>\r\n </div>\r\n </div>\r\n <div class=\"example-desc\">${example.description}</div>\r\n <div class=\"code-block\">\r\n <div class=\"code-header\">${example.code.language}</div>\r\n <pre><code>${this.escapeHtml(example.code.content)}</code></pre>\r\n </div>\r\n ${\r\n example.relatedFiles && example.relatedFiles.length > 0\r\n ? `\r\n <div class=\"related-files\">\r\n <strong>相关文件:</strong> ${example.relatedFiles.join(\", \")}\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n\r\n <!-- AI 分析 -->\r\n ${\r\n result.aiAnalysis\r\n ? `\r\n <div class=\"section\">\r\n <div class=\"section-title\">🤖 AI 分析</div>\r\n <div class=\"ai-analysis\">${this.escapeHtml(result.aiAnalysis)}</div>\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n </div>\r\n\r\n <div class=\"footer\">\r\n <p>AI Performance Analyzer v1.0.0</p>\r\n <p>Powered by Vite & OpenAI</p>\r\n </div>\r\n </div>\r\n</body>\r\n</html>\r\n `.trim();\r\n\r\n // 创建报告目录\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n if (!fs.existsSync(reportsDir)) {\r\n fs.mkdirSync(reportsDir, { recursive: true });\r\n }\r\n\r\n const reportPath = path.resolve(reportsDir, \"performance-report.html\");\r\n fs.writeFileSync(reportPath, html, \"utf-8\");\r\n console.log(pc.green(`\\n📄 性能报告已生成: ${pc.cyan(reportPath)}\\n`));\r\n }\r\n\r\n /**\r\n * 生成 JSON 报告\r\n */\r\n private async generateJSONReport(result: AnalysisResult): Promise<void> {\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n if (!fs.existsSync(reportsDir)) {\r\n fs.mkdirSync(reportsDir, { recursive: true });\r\n }\r\n\r\n const reportPath = path.resolve(reportsDir, \"performance-report.json\");\r\n fs.writeFileSync(reportPath, JSON.stringify(result, null, 2), \"utf-8\");\r\n console.log(pc.green(`📄 JSON 报告已生成: ${pc.cyan(reportPath)}`));\r\n }\r\n\r\n /**\r\n * 获取严重程度图标\r\n */\r\n private getSeverityIcon(severity: string): string {\r\n const icons: Record<string, string> = {\r\n high: \"🔴\",\r\n medium: \"🟡\",\r\n low: \"🔵\",\r\n };\r\n return icons[severity] || \"⚪\";\r\n }\r\n\r\n /**\r\n * 转义 HTML\r\n */\r\n private escapeHtml(text: string): string {\r\n const map: Record<string, string> = {\r\n \"&\": \"&amp;\",\r\n \"<\": \"&lt;\",\r\n \">\": \"&gt;\",\r\n '\"': \"&quot;\",\r\n \"'\": \"&#039;\",\r\n };\r\n return text.replace(/[&<>\"']/g, (m) => map[m]);\r\n }\r\n}\r\n","/**\r\n * AI 性能分析插件\r\n *\r\n * 功能:\r\n * - 分析构建产物大小\r\n * - 检测性能问题\r\n * - 提供优化建议\r\n */\r\n\r\nimport type { Plugin } from \"vite\";\r\nimport pc from \"picocolors\";\r\nimport { PerfAnalyzer } from \"./analyzer\";\r\nimport { PerfReporter } from \"./reporter\";\r\nimport type { AnalysisResult } from \"./types\";\r\n\r\nexport interface PerfAnalyzerOptions {\r\n // AI 配置\r\n apiKey?: string;\r\n apiUrl?: string;\r\n model?: string;\r\n // 分析配置\r\n enabled?: boolean;\r\n threshold?: {\r\n bundleSize?: number; // 单个文件大小阈值 (KB)\r\n totalSize?: number; // 总大小阈值 (MB)\r\n chunkCount?: number; // chunk 数量阈值\r\n };\r\n // 输出配置\r\n output?: {\r\n console?: boolean;\r\n html?: boolean;\r\n json?: boolean;\r\n };\r\n}\r\n\r\nexport function vitePluginAIPerfAnalyzer(\r\n options: PerfAnalyzerOptions = {},\r\n): Plugin {\r\n const {\r\n apiKey = process.env.OPENAI_API_KEY || \"\",\r\n apiUrl = process.env.OPENAI_API_URL || \"https://api.openai.com/v1\",\r\n model = process.env.OPENAI_MODEL || \"gpt-4\",\r\n enabled = true,\r\n threshold = {\r\n bundleSize: 500, // 500KB\r\n totalSize: 5, // 5MB\r\n chunkCount: 20,\r\n },\r\n output = {\r\n console: true,\r\n html: true,\r\n json: false,\r\n },\r\n } = options;\r\n\r\n const analyzer = new PerfAnalyzer({ apiKey, apiUrl, model, threshold });\r\n const reporter = new PerfReporter();\r\n\r\n let analysisResult: AnalysisResult | null = null;\r\n\r\n return {\r\n name: \"vite-plugin-ai-perf-analyzer\",\r\n enforce: \"post\",\r\n\r\n configResolved(config) {\r\n if (!enabled) return;\r\n\r\n console.log(pc.cyan(\"\\n⚡ AI 性能分析插件已启动...\"));\r\n console.log(`📊 分析阈值:`);\r\n console.log(` 单文件: ${pc.yellow(threshold.bundleSize + \"KB\")}`);\r\n console.log(` 总大小: ${pc.yellow(threshold.totalSize + \"MB\")}`);\r\n console.log(\r\n ` Chunk数: ${pc.yellow((threshold.chunkCount ?? 10).toString())}`,\r\n );\r\n console.log(`🔑 API Key: ${apiKey ? \"已配置\" : \"未配置\"}\\n`);\r\n },\r\n\r\n async closeBundle() {\r\n if (!enabled) return;\r\n\r\n console.log(\"\\n⚡ 正在分析构建产物...\\n\");\r\n\r\n try {\r\n // 分析构建产物\r\n analysisResult = await analyzer.analyze();\r\n\r\n // 生成报告\r\n await reporter.generate(analysisResult, output);\r\n\r\n // 控制台输出\r\n if (output.console) {\r\n reporter.printConsole(analysisResult);\r\n }\r\n } catch (error: any) {\r\n console.error(\"❌ 性能分析失败:\", error.message);\r\n }\r\n },\r\n };\r\n}\r\n\r\n// 默认导出\r\nexport default vitePluginAIPerfAnalyzer;\r\n"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/analyzer.ts","../src/dependency-analyzer.ts","../src/history-analyzer.ts","../src/optimization-examples.ts","../src/reporter.ts"],"sourcesContent":["/**\r\n * AI 性能分析插件\r\n *\r\n * 功能:\r\n * - 分析构建产物大小\r\n * - 检测性能问题\r\n * - 提供优化建议\r\n */\r\n\r\nimport type { Plugin } from \"vite\";\r\nimport pc from \"picocolors\";\r\nimport { PerfAnalyzer } from \"./analyzer\";\r\nimport { PerfReporter } from \"./reporter\";\r\nimport type { AnalysisResult } from \"./types\";\r\n\r\nexport interface PerfAnalyzerOptions {\r\n // AI 配置\r\n apiKey?: string;\r\n apiUrl?: string;\r\n model?: string;\r\n // 分析配置\r\n enabled?: boolean;\r\n threshold?: {\r\n bundleSize?: number; // 单个文件大小阈值 (KB)\r\n totalSize?: number; // 总大小阈值 (MB)\r\n chunkCount?: number; // chunk 数量阈值\r\n };\r\n // 输出配置\r\n output?: {\r\n console?: boolean;\r\n html?: boolean;\r\n json?: boolean;\r\n };\r\n}\r\n\r\nexport function vitePluginAIPerfAnalyzer(\r\n options: PerfAnalyzerOptions = {},\r\n): Plugin {\r\n const {\r\n apiKey = process.env.OPENAI_API_KEY || \"\",\r\n apiUrl = process.env.OPENAI_API_URL || \"https://api.openai.com/v1\",\r\n model = process.env.OPENAI_MODEL || \"gpt-4\",\r\n enabled = true,\r\n threshold = {\r\n bundleSize: 500, // 500KB\r\n totalSize: 5, // 5MB\r\n chunkCount: 20,\r\n },\r\n output = {\r\n console: true,\r\n html: true,\r\n json: false,\r\n },\r\n } = options;\r\n\r\n const analyzer = new PerfAnalyzer({ apiKey, apiUrl, model, threshold });\r\n const reporter = new PerfReporter();\r\n\r\n let analysisResult: AnalysisResult | null = null;\r\n\r\n return {\r\n name: \"vite-plugin-ai-perf-analyzer\",\r\n enforce: \"post\",\r\n\r\n configResolved(config) {\r\n if (!enabled) return;\r\n\r\n console.log(pc.cyan(\"\\n⚡ AI 性能分析插件已启动...\"));\r\n console.log(`📊 分析阈值:`);\r\n console.log(` 单文件: ${pc.yellow(threshold.bundleSize + \"KB\")}`);\r\n console.log(` 总大小: ${pc.yellow(threshold.totalSize + \"MB\")}`);\r\n console.log(\r\n ` Chunk数: ${pc.yellow((threshold.chunkCount ?? 10).toString())}`,\r\n );\r\n console.log(`🔑 API Key: ${apiKey ? \"已配置\" : \"未配置\"}\\n`);\r\n },\r\n\r\n async closeBundle() {\r\n if (!enabled) return;\r\n\r\n console.log(\"\\n⚡ 正在分析构建产物...\\n\");\r\n\r\n try {\r\n // 分析构建产物\r\n analysisResult = await analyzer.analyze();\r\n\r\n // 生成报告\r\n await reporter.generate(analysisResult, output);\r\n\r\n // 控制台输出\r\n if (output.console) {\r\n reporter.printConsole(analysisResult);\r\n }\r\n } catch (error: any) {\r\n console.error(\"❌ 性能分析失败:\", error.message);\r\n }\r\n },\r\n };\r\n}\r\n\r\n// 默认导出\r\nexport default vitePluginAIPerfAnalyzer;\r\n","/**\r\n * 性能分析器\r\n */\r\n\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport { gzipSync } from \"zlib\";\r\nimport { ChatOpenAI } from \"@langchain/openai\";\r\nimport { HumanMessage, SystemMessage } from \"@langchain/core/messages\";\r\nimport type {\r\n AnalysisResult,\r\n BundleInfo,\r\n PerformanceIssue,\r\n AnalyzerOptions,\r\n} from \"./types\";\r\nimport { DependencyAnalyzer } from \"./dependency-analyzer\";\r\nimport { HistoryAnalyzer } from \"./history-analyzer\";\r\nimport { OptimizationExamples } from \"./optimization-examples\";\r\n\r\nexport class PerfAnalyzer {\r\n private llm: ChatOpenAI | null = null;\r\n private options: AnalyzerOptions;\r\n private depAnalyzer: DependencyAnalyzer;\r\n private historyAnalyzer: HistoryAnalyzer;\r\n private examplesGenerator: OptimizationExamples;\r\n\r\n constructor(options: AnalyzerOptions) {\r\n this.options = options;\r\n this.depAnalyzer = new DependencyAnalyzer();\r\n this.historyAnalyzer = new HistoryAnalyzer();\r\n this.examplesGenerator = new OptimizationExamples();\r\n\r\n if (options.apiKey) {\r\n this.llm = new ChatOpenAI({\r\n openAIApiKey: options.apiKey,\r\n configuration: { baseURL: options.apiUrl },\r\n modelName: options.model,\r\n temperature: 0.2,\r\n maxTokens: 4000,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * 分析构建产物\r\n */\r\n async analyze(): Promise<AnalysisResult> {\r\n const distDir = path.resolve(process.cwd(), \"dist\");\r\n\r\n if (!fs.existsSync(distDir)) {\r\n throw new Error(\"构建目录不存在,请先执行构建\");\r\n }\r\n\r\n // 收集文件信息\r\n const bundles = this.collectBundles(distDir);\r\n\r\n // 计算统计信息\r\n const summary = this.calculateSummary(bundles);\r\n\r\n // 依赖分析\r\n console.log(\"📦 正在分析依赖...\");\r\n const dependencies = this.depAnalyzer.analyzeDependencies(bundles);\r\n\r\n // 历史对比\r\n console.log(\"📊 正在对比历史记录...\");\r\n const comparison = this.historyAnalyzer.compare(\r\n bundles,\r\n summary.totalSize,\r\n summary.fileCount\r\n );\r\n\r\n // 检测性能问题\r\n const issues = this.detectIssues(bundles, summary, dependencies);\r\n\r\n // 生成基础建议\r\n const suggestions = this.generateSuggestions(issues);\r\n\r\n // 生成优化示例\r\n console.log(\"💡 正在生成优化示例...\");\r\n const optimizationExamples = this.examplesGenerator.generate(\r\n issues,\r\n dependencies.duplicates\r\n );\r\n\r\n // AI 分析(如果配置了 API Key)\r\n let aiAnalysis: string | undefined;\r\n if (this.llm) {\r\n console.log(\"🤖 正在使用 AI 分析性能...\\n\");\r\n aiAnalysis = await this.performAIAnalysis(\r\n bundles,\r\n summary,\r\n issues,\r\n dependencies,\r\n comparison\r\n );\r\n }\r\n\r\n return {\r\n timestamp: new Date().toLocaleString(\"zh-CN\"),\r\n summary,\r\n dependencies,\r\n comparison,\r\n issues,\r\n suggestions,\r\n optimizationExamples,\r\n aiAnalysis,\r\n };\r\n }\r\n\r\n /**\r\n * 收集构建产物信息\r\n */\r\n private collectBundles(dir: string, baseDir: string = dir): BundleInfo[] {\r\n const bundles: BundleInfo[] = [];\r\n const files = fs.readdirSync(dir);\r\n\r\n for (const file of files) {\r\n const filePath = path.join(dir, file);\r\n const stat = fs.statSync(filePath);\r\n\r\n if (stat.isDirectory()) {\r\n bundles.push(...this.collectBundles(filePath, baseDir));\r\n } else {\r\n const content = fs.readFileSync(filePath);\r\n const gzipSize = gzipSync(content).length;\r\n const relativePath = path.relative(baseDir, filePath);\r\n\r\n bundles.push({\r\n name: file,\r\n size: stat.size,\r\n gzipSize,\r\n type: this.getFileType(file),\r\n path: relativePath,\r\n });\r\n }\r\n }\r\n\r\n return bundles;\r\n }\r\n\r\n /**\r\n * 获取文件类型\r\n */\r\n private getFileType(filename: string): string {\r\n const ext = path.extname(filename).toLowerCase();\r\n const typeMap: Record<string, string> = {\r\n \".js\": \"javascript\",\r\n \".mjs\": \"javascript\",\r\n \".css\": \"stylesheet\",\r\n \".html\": \"html\",\r\n \".png\": \"image\",\r\n \".jpg\": \"image\",\r\n \".jpeg\": \"image\",\r\n \".gif\": \"image\",\r\n \".svg\": \"image\",\r\n \".webp\": \"image\",\r\n \".woff\": \"font\",\r\n \".woff2\": \"font\",\r\n \".ttf\": \"font\",\r\n \".eot\": \"font\",\r\n \".json\": \"data\",\r\n \".map\": \"sourcemap\",\r\n };\r\n return typeMap[ext] || \"other\";\r\n }\r\n\r\n /**\r\n * 计算统计信息\r\n */\r\n private calculateSummary(bundles: BundleInfo[]) {\r\n const totalSize = bundles.reduce((sum, b) => sum + b.size, 0);\r\n const totalGzipSize = bundles.reduce(\r\n (sum, b) => sum + (b.gzipSize || 0),\r\n 0\r\n );\r\n\r\n // 按大小排序,取前 10\r\n const largestFiles = [...bundles]\r\n .sort((a, b) => b.size - a.size)\r\n .slice(0, 10);\r\n\r\n // 按类型分组\r\n const byType: Record<string, { count: number; size: number }> = {};\r\n bundles.forEach((bundle) => {\r\n if (!byType[bundle.type]) {\r\n byType[bundle.type] = { count: 0, size: 0 };\r\n }\r\n byType[bundle.type].count++;\r\n byType[bundle.type].size += bundle.size;\r\n });\r\n\r\n return {\r\n totalSize,\r\n totalGzipSize,\r\n fileCount: bundles.length,\r\n largestFiles,\r\n byType,\r\n };\r\n }\r\n\r\n /**\r\n * 检测性能问题\r\n */\r\n private detectIssues(\r\n bundles: BundleInfo[],\r\n summary: any,\r\n dependencies?: {\r\n total: number;\r\n duplicates: DependencyInfo[];\r\n largest: DependencyInfo[];\r\n }\r\n ): PerformanceIssue[] {\r\n const issues: PerformanceIssue[] = [];\r\n const { threshold } = this.options;\r\n\r\n // 检查总大小\r\n const totalSizeMB = summary.totalSize / 1024 / 1024;\r\n if (threshold.totalSize && totalSizeMB > threshold.totalSize) {\r\n issues.push({\r\n type: \"size\",\r\n severity: \"high\",\r\n title: \"构建产物总大小过大\",\r\n description: `总大小 ${totalSizeMB.toFixed(2)}MB 超过阈值 ${\r\n threshold.totalSize\r\n }MB`,\r\n suggestion: \"考虑代码分割、tree-shaking、压缩等优化手段\",\r\n });\r\n }\r\n\r\n // 检查单个文件大小\r\n const largeBundles = bundles.filter(\r\n (b) => b.size / 1024 > (threshold.bundleSize || 500)\r\n );\r\n if (largeBundles.length > 0) {\r\n issues.push({\r\n type: \"size\",\r\n severity: \"medium\",\r\n title: \"存在过大的单个文件\",\r\n description: `发现 ${largeBundles.length} 个文件超过 ${threshold.bundleSize}KB`,\r\n files: largeBundles.map(\r\n (b) => `${b.name} (${(b.size / 1024).toFixed(2)}KB)`\r\n ),\r\n suggestion: \"考虑拆分大文件,使用动态导入或代码分割\",\r\n });\r\n }\r\n\r\n // 检查 chunk 数量\r\n const jsFiles = bundles.filter((b) => b.type === \"javascript\");\r\n if (threshold.chunkCount && jsFiles.length > threshold.chunkCount) {\r\n issues.push({\r\n type: \"count\",\r\n severity: \"low\",\r\n title: \"JavaScript 文件数量过多\",\r\n description: `共有 ${jsFiles.length} 个 JS 文件,超过阈值 ${threshold.chunkCount}`,\r\n suggestion: \"过多的文件会增加 HTTP 请求数,考虑合并小文件\",\r\n });\r\n }\r\n\r\n // 检查未压缩的图片\r\n const images = bundles.filter((b) => b.type === \"image\");\r\n const largeImages = images.filter((img) => img.size > 100 * 1024); // 100KB\r\n if (largeImages.length > 0) {\r\n issues.push({\r\n type: \"optimization\",\r\n severity: \"medium\",\r\n title: \"存在未优化的图片\",\r\n description: `发现 ${largeImages.length} 个大于 100KB 的图片`,\r\n files: largeImages.map(\r\n (img) => `${img.name} (${(img.size / 1024).toFixed(2)}KB)`\r\n ),\r\n suggestion: \"使用图片压缩工具,或转换为 WebP 格式\",\r\n });\r\n }\r\n\r\n // 检查 sourcemap\r\n const sourcemaps = bundles.filter((b) => b.type === \"sourcemap\");\r\n if (sourcemaps.length > 0) {\r\n const totalMapSize = sourcemaps.reduce((sum, m) => sum + m.size, 0);\r\n issues.push({\r\n type: \"optimization\",\r\n severity: \"low\",\r\n title: \"生产环境包含 sourcemap\",\r\n description: `Sourcemap 文件占用 ${(totalMapSize / 1024 / 1024).toFixed(\r\n 2\r\n )}MB`,\r\n suggestion: \"生产环境建议禁用 sourcemap 或使用外部 sourcemap\",\r\n });\r\n }\r\n\r\n // 检查重复依赖\r\n if (dependencies && dependencies.duplicates.length > 0) {\r\n const topDuplicates = dependencies.duplicates.slice(0, 3);\r\n issues.push({\r\n type: \"dependency\",\r\n severity: \"medium\",\r\n title: \"检测到重复打包的依赖\",\r\n description: `发现 ${dependencies.duplicates.length} 个依赖被多次打包`,\r\n files: topDuplicates.map(\r\n (d) =>\r\n `${d.name} (被 ${d.usedBy.length} 个文件使用, ${(\r\n d.size / 1024\r\n ).toFixed(2)}KB)`\r\n ),\r\n suggestion: \"将重复依赖提取到公共 chunk 中\",\r\n });\r\n }\r\n\r\n return issues;\r\n }\r\n\r\n /**\r\n * 生成基础建议\r\n */\r\n private generateSuggestions(issues: PerformanceIssue[]): string[] {\r\n const suggestions: string[] = [];\r\n\r\n if (issues.some((i) => i.type === \"size\")) {\r\n suggestions.push(\"启用 gzip/brotli 压缩\");\r\n suggestions.push(\"配置 Vite 的 build.rollupOptions 进行代码分割\");\r\n suggestions.push(\"使用 vite-plugin-compression 插件\");\r\n }\r\n\r\n if (issues.some((i) => i.type === \"optimization\")) {\r\n suggestions.push(\"使用 vite-plugin-imagemin 优化图片\");\r\n suggestions.push(\"配置 CSS 压缩和 tree-shaking\");\r\n }\r\n\r\n if (issues.length === 0) {\r\n suggestions.push(\"构建产物已经很优秀,继续保持!\");\r\n }\r\n\r\n return suggestions;\r\n }\r\n\r\n /**\r\n * AI 性能分析\r\n */\r\n private async performAIAnalysis(\r\n bundles: BundleInfo[],\r\n summary: any,\r\n issues: PerformanceIssue[],\r\n dependencies?: {\r\n total: number;\r\n duplicates: DependencyInfo[];\r\n largest: DependencyInfo[];\r\n },\r\n comparison?: any\r\n ): Promise<string> {\r\n const systemPrompt = new SystemMessage(\r\n \"你是一个专业的前端性能优化专家,精通 Vite、Webpack 等构建工具。请分析构建产物并提供专业的优化建议。\"\r\n );\r\n\r\n const bundlesSummary = summary.largestFiles\r\n .slice(0, 5)\r\n .map((b: BundleInfo) => `- ${b.name}: ${(b.size / 1024).toFixed(2)}KB`)\r\n .join(\"\\n\");\r\n\r\n const typesSummary = Object.entries(summary.byType)\r\n .map(\r\n ([type, info]: [string, any]) =>\r\n `- ${type}: ${info.count} 个文件, ${(info.size / 1024).toFixed(2)}KB`\r\n )\r\n .join(\"\\n\");\r\n\r\n const issuesSummary = issues\r\n .map(\r\n (issue) => `- [${issue.severity}] ${issue.title}: ${issue.description}`\r\n )\r\n .join(\"\\n\");\r\n\r\n // 依赖分析摘要\r\n let dependencySummary = \"\";\r\n if (dependencies) {\r\n dependencySummary = `\r\n## 依赖分析\r\n- 总依赖数: ${dependencies.total}\r\n- 重复依赖: ${dependencies.duplicates.length} 个\r\n- 最大依赖: ${dependencies.largest\r\n .slice(0, 3)\r\n .map((d) => `${d.name} (${(d.size / 1024).toFixed(2)}KB)`)\r\n .join(\", \")}`;\r\n }\r\n\r\n // 历史对比摘要\r\n let comparisonSummary = \"\";\r\n if (comparison) {\r\n const sizeChange =\r\n comparison.totalSize.trend === \"increased\" ? \"增加\" : \"减少\";\r\n comparisonSummary = `\r\n## 历史对比\r\n- 总大小${sizeChange}: ${Math.abs(comparison.totalSize.diffPercent).toFixed(2)}%\r\n- 文件数量变化: ${comparison.fileCount.diff > 0 ? \"+\" : \"\"}${\r\n comparison.fileCount.diff\r\n }\r\n- 新增文件: ${comparison.newFiles.length} 个\r\n- 删除文件: ${comparison.removedFiles.length} 个`;\r\n }\r\n\r\n const userPrompt = new HumanMessage(`\r\n请分析以下构建产物信息:\r\n\r\n## 总体统计\r\n- 总大小: ${(summary.totalSize / 1024 / 1024).toFixed(2)}MB\r\n- Gzip 后: ${(summary.totalGzipSize / 1024 / 1024).toFixed(2)}MB\r\n- 文件数量: ${summary.fileCount}\r\n\r\n## 最大的文件\r\n${bundlesSummary}\r\n\r\n## 按类型分组\r\n${typesSummary}\r\n${dependencySummary}\r\n${comparisonSummary}\r\n\r\n## 检测到的问题\r\n${issuesSummary || \"无明显问题\"}\r\n\r\n请提供:\r\n1. 性能评估(3-5 句话)\r\n2. 具体优化建议(3-5 条,每条简洁明了)\r\n3. 优先级排序\r\n\r\n请用简洁专业的语言回答,不要过于冗长。\r\n`);\r\n\r\n const response = await this.llm!.invoke([systemPrompt, userPrompt]);\r\n return response.content.toString();\r\n }\r\n}\r\n","/**\r\n * 依赖分析器\r\n */\r\n\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport type { BundleInfo, DependencyInfo } from \"./types\";\r\n\r\nexport class DependencyAnalyzer {\r\n /**\r\n * 分析依赖\r\n */\r\n analyzeDependencies(bundles: BundleInfo[]): {\r\n total: number;\r\n duplicates: DependencyInfo[];\r\n largest: DependencyInfo[];\r\n } {\r\n const jsFiles = bundles.filter((b) => b.type === \"javascript\");\r\n const dependencies = this.extractDependencies(jsFiles);\r\n\r\n // 检测重复依赖\r\n const duplicates = this.findDuplicates(dependencies);\r\n\r\n // 找出最大的依赖\r\n const largest = [...dependencies]\r\n .sort((a, b) => b.size - a.size)\r\n .slice(0, 10);\r\n\r\n return {\r\n total: dependencies.length,\r\n duplicates,\r\n largest,\r\n };\r\n }\r\n\r\n /**\r\n * 从 JS 文件中提取依赖信息\r\n */\r\n private extractDependencies(jsFiles: BundleInfo[]): DependencyInfo[] {\r\n const depMap = new Map<string, DependencyInfo>();\r\n\r\n jsFiles.forEach((file) => {\r\n // 尝试解析文件内容,提取依赖\r\n const imports = this.parseImports(file);\r\n\r\n imports.forEach((depName) => {\r\n if (!depMap.has(depName)) {\r\n depMap.set(depName, {\r\n name: depName,\r\n size: 0,\r\n usedBy: [],\r\n isDuplicate: false,\r\n });\r\n }\r\n\r\n const dep = depMap.get(depName)!;\r\n dep.usedBy.push(file.name);\r\n // 估算依赖大小(简化处理)\r\n dep.size += file.size / imports.length;\r\n });\r\n });\r\n\r\n return Array.from(depMap.values());\r\n }\r\n\r\n /**\r\n * 解析文件中的 import 语句\r\n */\r\n private parseImports(file: BundleInfo): string[] {\r\n const imports: string[] = [];\r\n\r\n try {\r\n const distDir = path.resolve(process.cwd(), \"dist\");\r\n const filePath = path.join(distDir, file.path);\r\n\r\n if (!fs.existsSync(filePath)) {\r\n return imports;\r\n }\r\n\r\n const content = fs.readFileSync(filePath, \"utf-8\");\r\n\r\n // 匹配常见的依赖模式\r\n const patterns = [\r\n // node_modules 依赖\r\n /from\\s+[\"']([^\"']+)[\"']/g,\r\n /require\\([\"']([^\"']+)[\"']\\)/g,\r\n // Vite 特殊标记\r\n /__vite_ssr_import__\\(\"([^\"]+)\"\\)/g,\r\n ];\r\n\r\n patterns.forEach((pattern) => {\r\n let match;\r\n while ((match = pattern.exec(content)) !== null) {\r\n const depName = match[1];\r\n // 只保留 node_modules 依赖\r\n if (!depName.startsWith(\".\") && !depName.startsWith(\"/\")) {\r\n // 提取包名(去掉子路径)\r\n const pkgName = depName\r\n .split(\"/\")\r\n .slice(0, depName.startsWith(\"@\") ? 2 : 1)\r\n .join(\"/\");\r\n if (!imports.includes(pkgName)) {\r\n imports.push(pkgName);\r\n }\r\n }\r\n }\r\n });\r\n } catch (error) {\r\n // 忽略解析错误\r\n }\r\n\r\n return imports;\r\n }\r\n\r\n /**\r\n * 查找重复打包的依赖\r\n */\r\n private findDuplicates(dependencies: DependencyInfo[]): DependencyInfo[] {\r\n return dependencies\r\n .filter((dep) => dep.usedBy.length > 1)\r\n .map((dep) => ({\r\n ...dep,\r\n isDuplicate: true,\r\n }))\r\n .sort((a, b) => b.usedBy.length - a.usedBy.length)\r\n .slice(0, 10);\r\n }\r\n}\r\n","/**\r\n * 历史对比分析器\r\n */\r\n\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport type {\r\n BundleInfo,\r\n HistoryComparison,\r\n HistoryRecord,\r\n ComparisonResult,\r\n} from \"./types\";\r\n\r\nexport class HistoryAnalyzer {\r\n private historyFile: string;\r\n\r\n constructor() {\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n this.historyFile = path.join(reportsDir, \".perf-history.json\");\r\n }\r\n\r\n /**\r\n * 对比当前构建与历史记录\r\n */\r\n compare(\r\n currentBundles: BundleInfo[],\r\n currentTotalSize: number,\r\n currentFileCount: number\r\n ): HistoryComparison | undefined {\r\n const history = this.loadHistory();\r\n\r\n if (history.length === 0) {\r\n // 没有历史记录,保存当前记录\r\n this.saveHistory(currentBundles, currentTotalSize, currentFileCount);\r\n return undefined;\r\n }\r\n\r\n // 获取上一次记录\r\n const previous = history[history.length - 1];\r\n\r\n // 对比总大小\r\n const totalSize = this.compareValue(currentTotalSize, previous.totalSize);\r\n\r\n // 对比文件数量\r\n const fileCount = this.compareValue(currentFileCount, previous.fileCount);\r\n\r\n // 对比最大文件变化\r\n const largestFileChanges = this.compareLargestFiles(\r\n currentBundles,\r\n previous.files\r\n );\r\n\r\n // 检测新增和删除的文件\r\n const currentFileNames = new Set(currentBundles.map((b) => b.name));\r\n const previousFileNames = new Set(previous.files.map((f) => f.name));\r\n\r\n const newFiles = currentBundles\r\n .filter((b) => !previousFileNames.has(b.name))\r\n .map((b) => b.name);\r\n\r\n const removedFiles = previous.files\r\n .filter((f) => !currentFileNames.has(f.name))\r\n .map((f) => f.name);\r\n\r\n // 保存当前记录\r\n this.saveHistory(currentBundles, currentTotalSize, currentFileCount);\r\n\r\n return {\r\n totalSize,\r\n fileCount,\r\n largestFileChanges,\r\n newFiles,\r\n removedFiles,\r\n };\r\n }\r\n\r\n /**\r\n * 对比数值\r\n */\r\n private compareValue(current: number, previous: number): ComparisonResult {\r\n const diff = current - previous;\r\n const diffPercent = previous === 0 ? 0 : (diff / previous) * 100;\r\n\r\n let trend: \"increased\" | \"decreased\" | \"unchanged\";\r\n if (Math.abs(diffPercent) < 1) {\r\n trend = \"unchanged\";\r\n } else if (diff > 0) {\r\n trend = \"increased\";\r\n } else {\r\n trend = \"decreased\";\r\n }\r\n\r\n return {\r\n current,\r\n previous,\r\n diff,\r\n diffPercent,\r\n trend,\r\n };\r\n }\r\n\r\n /**\r\n * 对比最大文件的变化\r\n */\r\n private compareLargestFiles(\r\n currentBundles: BundleInfo[],\r\n previousFiles: Array<{ name: string; size: number }>\r\n ): Array<{\r\n name: string;\r\n current: number;\r\n previous: number;\r\n diff: number;\r\n }> {\r\n const changes: Array<{\r\n name: string;\r\n current: number;\r\n previous: number;\r\n diff: number;\r\n }> = [];\r\n\r\n // 创建文件映射\r\n const previousMap = new Map(previousFiles.map((f) => [f.name, f.size]));\r\n\r\n currentBundles.forEach((bundle) => {\r\n const previousSize = previousMap.get(bundle.name);\r\n if (previousSize !== undefined) {\r\n const diff = bundle.size - previousSize;\r\n // 只记录变化超过 10KB 的文件\r\n if (Math.abs(diff) > 10 * 1024) {\r\n changes.push({\r\n name: bundle.name,\r\n current: bundle.size,\r\n previous: previousSize,\r\n diff,\r\n });\r\n }\r\n }\r\n });\r\n\r\n // 按变化幅度排序\r\n return changes\r\n .sort((a, b) => Math.abs(b.diff) - Math.abs(a.diff))\r\n .slice(0, 10);\r\n }\r\n\r\n /**\r\n * 加载历史记录\r\n */\r\n private loadHistory(): HistoryRecord[] {\r\n if (!fs.existsSync(this.historyFile)) {\r\n return [];\r\n }\r\n\r\n try {\r\n const content = fs.readFileSync(this.historyFile, \"utf-8\");\r\n const history = JSON.parse(content);\r\n // 只保留最近 10 次记录\r\n return history.slice(-10);\r\n } catch (error) {\r\n console.warn(\"⚠️ 无法读取历史记录\");\r\n return [];\r\n }\r\n }\r\n\r\n /**\r\n * 保存历史记录\r\n */\r\n private saveHistory(\r\n bundles: BundleInfo[],\r\n totalSize: number,\r\n fileCount: number\r\n ): void {\r\n const history = this.loadHistory();\r\n\r\n const record: HistoryRecord = {\r\n timestamp: new Date().toISOString(),\r\n totalSize,\r\n fileCount,\r\n files: bundles.map((b) => ({\r\n name: b.name,\r\n size: b.size,\r\n })),\r\n };\r\n\r\n history.push(record);\r\n\r\n // 确保目录存在\r\n const dir = path.dirname(this.historyFile);\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n\r\n // 只保留最近 10 次记录\r\n const recentHistory = history.slice(-10);\r\n\r\n fs.writeFileSync(\r\n this.historyFile,\r\n JSON.stringify(recentHistory, null, 2),\r\n \"utf-8\"\r\n );\r\n }\r\n\r\n /**\r\n * 清除历史记录\r\n */\r\n clearHistory(): void {\r\n if (fs.existsSync(this.historyFile)) {\r\n fs.unlinkSync(this.historyFile);\r\n }\r\n }\r\n}\r\n","/**\r\n * 优化示例生成器\r\n */\r\n\r\nimport type {\r\n OptimizationExample,\r\n PerformanceIssue,\r\n DependencyInfo,\r\n} from \"./types\";\r\n\r\nexport class OptimizationExamples {\r\n /**\r\n * 根据问题生成优化示例\r\n */\r\n generate(\r\n issues: PerformanceIssue[],\r\n duplicateDeps?: DependencyInfo[]\r\n ): OptimizationExample[] {\r\n const examples: OptimizationExample[] = [];\r\n\r\n // 代码分割示例\r\n if (issues.some((i) => i.type === \"size\")) {\r\n examples.push(this.getCodeSplittingExample());\r\n }\r\n\r\n // 重复依赖优化\r\n if (duplicateDeps && duplicateDeps.length > 0) {\r\n examples.push(this.getDependencyOptimizationExample(duplicateDeps));\r\n }\r\n\r\n // 压缩优化\r\n if (issues.some((i) => i.type === \"optimization\")) {\r\n examples.push(this.getCompressionExample());\r\n }\r\n\r\n // 图片优化\r\n if (issues.some((i) => i.description.includes(\"图片\"))) {\r\n examples.push(this.getImageOptimizationExample());\r\n }\r\n\r\n // 动态导入\r\n if (issues.some((i) => i.type === \"size\" && i.severity === \"high\")) {\r\n examples.push(this.getDynamicImportExample());\r\n }\r\n\r\n // Tree-shaking 优化\r\n examples.push(this.getTreeShakingExample());\r\n\r\n return examples;\r\n }\r\n\r\n /**\r\n * 代码分割示例\r\n */\r\n private getCodeSplittingExample(): OptimizationExample {\r\n return {\r\n title: \"配置代码分割\",\r\n description: \"将大文件拆分成多个小文件,提高加载性能\",\r\n priority: \"high\",\r\n impact: \"可减少 30-50% 的初始加载大小\",\r\n difficulty: \"简单\",\r\n code: {\r\n language: \"typescript\",\r\n content: `// vite.config.ts\r\nexport default defineConfig({\r\n build: {\r\n rollupOptions: {\r\n output: {\r\n manualChunks: {\r\n // 提取 Vue 核心库\r\n 'vue-vendor': ['vue', 'vue-router', 'pinia'],\r\n \r\n // 提取 UI 组件库\r\n 'ui-vendor': ['element-plus', '@element-plus/icons-vue'],\r\n \r\n // 提取工具库\r\n 'utils': ['lodash-es', 'dayjs', 'axios'],\r\n \r\n // 提取图表库(如果使用)\r\n 'charts': ['echarts', 'chart.js'],\r\n },\r\n \r\n // 自动分割大于 500KB 的文件\r\n chunkFileNames: (chunkInfo) => {\r\n const facadeModuleId = chunkInfo.facadeModuleId \r\n ? chunkInfo.facadeModuleId.split('/').pop() \r\n : 'chunk';\r\n return \\`js/\\${facadeModuleId}-[hash].js\\`;\r\n },\r\n },\r\n },\r\n \r\n // 设置 chunk 大小警告阈值\r\n chunkSizeWarningLimit: 500,\r\n },\r\n});`,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * 重复依赖优化示例\r\n */\r\n private getDependencyOptimizationExample(\r\n duplicates: DependencyInfo[]\r\n ): OptimizationExample {\r\n const topDuplicates = duplicates.slice(0, 3).map((d) => d.name);\r\n\r\n return {\r\n title: \"优化重复依赖\",\r\n description: `检测到 ${duplicates.length} 个重复打包的依赖,建议提取到公共 chunk`,\r\n priority: \"high\",\r\n impact: `可减少 ${(\r\n duplicates.reduce((sum, d) => sum + d.size, 0) /\r\n 1024 /\r\n 1024\r\n ).toFixed(2)}MB`,\r\n difficulty: \"简单\",\r\n code: {\r\n language: \"typescript\",\r\n content: `// vite.config.ts\r\nexport default defineConfig({\r\n build: {\r\n rollupOptions: {\r\n output: {\r\n manualChunks: {\r\n // 提取重复依赖到公共 chunk\r\n 'common-vendor': [\r\n ${topDuplicates.map((name) => `'${name}'`).join(\",\\n \")}\r\n ],\r\n },\r\n },\r\n },\r\n },\r\n \r\n // 或者使用自动分割策略\r\n optimizeDeps: {\r\n include: [\r\n ${topDuplicates.map((name) => `'${name}'`).join(\",\\n \")}\r\n ],\r\n },\r\n});`,\r\n },\r\n relatedFiles: duplicates.flatMap((d) => d.usedBy).slice(0, 5),\r\n };\r\n }\r\n\r\n /**\r\n * 压缩优化示例\r\n */\r\n private getCompressionExample(): OptimizationExample {\r\n return {\r\n title: \"启用 Gzip/Brotli 压缩\",\r\n description: \"使用压缩插件减少传输大小\",\r\n priority: \"medium\",\r\n impact: \"可减少 60-70% 的传输大小\",\r\n difficulty: \"简单\",\r\n code: {\r\n language: \"bash\",\r\n content: `# 1. 安装压缩插件\r\nnpm install vite-plugin-compression -D\r\n\r\n# 2. 配置插件\r\n# vite.config.ts\r\nimport viteCompression from 'vite-plugin-compression';\r\n\r\nexport default defineConfig({\r\n plugins: [\r\n // Gzip 压缩\r\n viteCompression({\r\n algorithm: 'gzip',\r\n ext: '.gz',\r\n threshold: 10240, // 大于 10KB 才压缩\r\n deleteOriginFile: false,\r\n }),\r\n \r\n // Brotli 压缩(可选,压缩率更高)\r\n viteCompression({\r\n algorithm: 'brotliCompress',\r\n ext: '.br',\r\n threshold: 10240,\r\n deleteOriginFile: false,\r\n }),\r\n ],\r\n});\r\n\r\n# 3. Nginx 配置(服务器端)\r\n# nginx.conf\r\ngzip on;\r\ngzip_types text/plain text/css application/json application/javascript;\r\ngzip_min_length 1024;`,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * 图片优化示例\r\n */\r\n private getImageOptimizationExample(): OptimizationExample {\r\n return {\r\n title: \"优化图片资源\",\r\n description: \"压缩图片并转换为现代格式\",\r\n priority: \"medium\",\r\n impact: \"可减少 50-80% 的图片大小\",\r\n difficulty: \"简单\",\r\n code: {\r\n language: \"bash\",\r\n content: `# 1. 安装图片优化插件\r\nnpm install vite-plugin-imagemin -D\r\n\r\n# 2. 配置插件\r\n# vite.config.ts\r\nimport viteImagemin from 'vite-plugin-imagemin';\r\n\r\nexport default defineConfig({\r\n plugins: [\r\n viteImagemin({\r\n // GIF 优化\r\n gifsicle: {\r\n optimizationLevel: 7,\r\n interlaced: false,\r\n },\r\n \r\n // PNG 优化\r\n optipng: {\r\n optimizationLevel: 7,\r\n },\r\n \r\n // JPEG 优化\r\n mozjpeg: {\r\n quality: 80,\r\n },\r\n \r\n // SVG 优化\r\n svgo: {\r\n plugins: [\r\n { name: 'removeViewBox', active: false },\r\n { name: 'removeEmptyAttrs', active: true },\r\n ],\r\n },\r\n \r\n // WebP 转换\r\n webp: {\r\n quality: 80,\r\n },\r\n }),\r\n ],\r\n});\r\n\r\n# 3. 使用 WebP 格式(HTML)\r\n<picture>\r\n <source srcset=\"image.webp\" type=\"image/webp\">\r\n <img src=\"image.jpg\" alt=\"description\">\r\n</picture>`,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * 动态导入示例\r\n */\r\n private getDynamicImportExample(): OptimizationExample {\r\n return {\r\n title: \"使用动态导入(懒加载)\",\r\n description: \"按需加载组件和路由,减少初始加载大小\",\r\n priority: \"high\",\r\n impact: \"可减少 40-60% 的初始加载大小\",\r\n difficulty: \"中等\",\r\n code: {\r\n language: \"typescript\",\r\n content: `// 1. 路由懒加载\r\n// router/index.ts\r\nconst routes = [\r\n {\r\n path: '/dashboard',\r\n name: 'Dashboard',\r\n // 使用动态导入\r\n component: () => import('@/views/Dashboard.vue'),\r\n },\r\n {\r\n path: '/settings',\r\n name: 'Settings',\r\n component: () => import('@/views/Settings.vue'),\r\n },\r\n];\r\n\r\n// 2. 组件懒加载\r\n// App.vue\r\n<script setup>\r\nimport { defineAsyncComponent } from 'vue';\r\n\r\n// 异步组件\r\nconst HeavyComponent = defineAsyncComponent(() =>\r\n import('./components/HeavyComponent.vue')\r\n);\r\n\r\n// 带加载状态的异步组件\r\nconst AsyncComponent = defineAsyncComponent({\r\n loader: () => import('./components/AsyncComponent.vue'),\r\n loadingComponent: LoadingSpinner,\r\n errorComponent: ErrorComponent,\r\n delay: 200,\r\n timeout: 3000,\r\n});\r\n</script>\r\n\r\n// 3. 条件加载\r\n<script setup>\r\nconst loadCharts = async () => {\r\n if (needCharts) {\r\n const { default: ECharts } = await import('echarts');\r\n // 使用 ECharts\r\n }\r\n};\r\n</script>`,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Tree-shaking 优化示例\r\n */\r\n private getTreeShakingExample(): OptimizationExample {\r\n return {\r\n title: \"优化 Tree-shaking\",\r\n description: \"确保未使用的代码被正确移除\",\r\n priority: \"medium\",\r\n impact: \"可减少 10-30% 的代码大小\",\r\n difficulty: \"中等\",\r\n code: {\r\n language: \"typescript\",\r\n content: `// 1. 使用 ES6 模块导入(支持 tree-shaking)\r\n// ❌ 不推荐\r\nimport _ from 'lodash';\r\nconst result = _.debounce(fn, 300);\r\n\r\n// ✅ 推荐\r\nimport { debounce } from 'lodash-es';\r\nconst result = debounce(fn, 300);\r\n\r\n// 2. 配置 package.json\r\n{\r\n \"sideEffects\": false, // 标记为无副作用\r\n // 或指定有副作用的文件\r\n \"sideEffects\": [\"*.css\", \"*.scss\"]\r\n}\r\n\r\n// 3. Vite 配置\r\n// vite.config.ts\r\nexport default defineConfig({\r\n build: {\r\n // 启用 tree-shaking\r\n minify: 'terser',\r\n terserOptions: {\r\n compress: {\r\n drop_console: true, // 移除 console\r\n drop_debugger: true, // 移除 debugger\r\n pure_funcs: ['console.log'], // 移除特定函数\r\n },\r\n },\r\n },\r\n});\r\n\r\n// 4. 避免副作用导入\r\n// ❌ 不推荐(会导入整个模块)\r\nimport 'some-library';\r\n\r\n// ✅ 推荐(明确导入需要的部分)\r\nimport { specificFunction } from 'some-library';`,\r\n },\r\n };\r\n }\r\n}\r\n","/**\r\n * 性能分析报告生成器\r\n */\r\n\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport pc from \"picocolors\";\r\nimport type { AnalysisResult, PerformanceIssue } from \"./types\";\r\n\r\nexport interface ReporterOptions {\r\n console?: boolean;\r\n html?: boolean;\r\n json?: boolean;\r\n}\r\n\r\nexport class PerfReporter {\r\n /**\r\n * 生成报告\r\n */\r\n async generate(\r\n result: AnalysisResult,\r\n options: ReporterOptions = {},\r\n ): Promise<void> {\r\n if (options.html) {\r\n await this.generateHTMLReport(result);\r\n }\r\n\r\n if (options.json) {\r\n await this.generateJSONReport(result);\r\n }\r\n }\r\n\r\n /**\r\n * 控制台输出\r\n */\r\n printConsole(result: AnalysisResult): void {\r\n console.log(\"\\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\");\r\n console.log(\"⚡ 性能分析报告\");\r\n console.log(\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n\");\r\n\r\n // 总体统计\r\n console.log(\"📊 总体统计:\");\r\n console.log(\r\n ` 总大小: ${(result.summary.totalSize / 1024 / 1024).toFixed(2)}MB`,\r\n );\r\n console.log(\r\n ` Gzip后: ${(result.summary.totalGzipSize / 1024 / 1024).toFixed(2)}MB`,\r\n );\r\n console.log(` 文件数: ${result.summary.fileCount}\\n`);\r\n\r\n // 历史对比\r\n if (result.comparison) {\r\n console.log(\"📈 历史对比:\");\r\n const { totalSize, fileCount, newFiles, removedFiles } =\r\n result.comparison;\r\n const sizeIcon = totalSize.trend === \"increased\" ? \"📈\" : \"📉\";\r\n console.log(\r\n ` ${sizeIcon} 总大小: ${totalSize.trend === \"increased\" ? \"+\" : \"\"}${(\r\n totalSize.diff /\r\n 1024 /\r\n 1024\r\n ).toFixed(2)}MB (${\r\n totalSize.diffPercent > 0 ? \"+\" : \"\"\r\n }${totalSize.diffPercent.toFixed(2)}%)`,\r\n );\r\n console.log(\r\n ` 📊 文件数: ${fileCount.diff > 0 ? \"+\" : \"\"}${fileCount.diff}`,\r\n );\r\n if (newFiles.length > 0) {\r\n console.log(` ✨ 新增: ${newFiles.slice(0, 3).join(\", \")}`);\r\n }\r\n if (removedFiles.length > 0) {\r\n console.log(` 🗑️ 删除: ${removedFiles.slice(0, 3).join(\", \")}`);\r\n }\r\n console.log();\r\n }\r\n\r\n // 依赖分析\r\n if (result.dependencies) {\r\n console.log(\"📦 依赖分析:\");\r\n console.log(` 总依赖数: ${result.dependencies.total}`);\r\n if (result.dependencies.duplicates.length > 0) {\r\n console.log(\r\n ` ⚠️ 重复依赖: ${result.dependencies.duplicates.length} 个`,\r\n );\r\n result.dependencies.duplicates.slice(0, 3).forEach((dep) => {\r\n console.log(\r\n ` - ${dep.name}: 被 ${dep.usedBy.length} 个文件使用`,\r\n );\r\n });\r\n }\r\n console.log();\r\n }\r\n\r\n // 最大文件\r\n console.log(\"📦 最大的文件:\");\r\n result.summary.largestFiles.slice(0, 5).forEach((file, index) => {\r\n console.log(\r\n ` ${index + 1}. ${file.name}: ${(file.size / 1024).toFixed(2)}KB`,\r\n );\r\n });\r\n console.log();\r\n\r\n // 按类型统计\r\n console.log(\"📋 按类型统计:\");\r\n Object.entries(result.summary.byType).forEach(([type, info]) => {\r\n console.log(\r\n ` ${type}: ${info.count} 个, ${(info.size / 1024).toFixed(2)}KB`,\r\n );\r\n });\r\n console.log();\r\n\r\n // 性能问题\r\n if (result.issues.length > 0) {\r\n console.log(\"⚠️ 性能问题:\");\r\n result.issues.forEach((issue, index) => {\r\n const icon = this.getSeverityIcon(issue.severity);\r\n console.log(` ${index + 1}. ${icon} ${issue.title}`);\r\n console.log(` ${issue.description}`);\r\n if (issue.suggestion) {\r\n console.log(` 💡 ${issue.suggestion}`);\r\n }\r\n });\r\n console.log();\r\n } else {\r\n console.log(\"✅ 未发现明显的性能问题\\n\");\r\n }\r\n\r\n // 优化建议\r\n if (result.suggestions.length > 0) {\r\n console.log(\"💡 优化建议:\");\r\n result.suggestions.forEach((suggestion, index) => {\r\n console.log(` ${index + 1}. ${suggestion}`);\r\n });\r\n console.log();\r\n }\r\n\r\n // 优化示例\r\n if (result.optimizationExamples && result.optimizationExamples.length > 0) {\r\n console.log(\"🔧 优化示例:\");\r\n result.optimizationExamples.slice(0, 3).forEach((example, index) => {\r\n console.log(` ${index + 1}. ${example.title} (${example.priority})`);\r\n console.log(` ${example.description}`);\r\n });\r\n console.log();\r\n }\r\n\r\n // AI 分析\r\n if (result.aiAnalysis) {\r\n console.log(\"🤖 AI 分析:\");\r\n console.log(\r\n result.aiAnalysis\r\n .split(\"\\n\")\r\n .map((line) => ` ${line}`)\r\n .join(\"\\n\"),\r\n );\r\n console.log();\r\n }\r\n\r\n console.log(\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n\");\r\n }\r\n\r\n /**\r\n * 生成 HTML 报告\r\n */\r\n private async generateHTMLReport(result: AnalysisResult): Promise<void> {\r\n const html = `\r\n<!DOCTYPE html>\r\n<html lang=\"zh-CN\">\r\n<head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>性能分析报告</title>\r\n <style>\r\n * { margin: 0; padding: 0; box-sizing: border-box; }\r\n body {\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n padding: 20px;\r\n min-height: 100vh;\r\n }\r\n .container {\r\n max-width: 1200px;\r\n margin: 0 auto;\r\n background: white;\r\n border-radius: 12px;\r\n box-shadow: 0 8px 32px rgba(0,0,0,0.2);\r\n overflow: hidden;\r\n }\r\n .header {\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n color: white;\r\n padding: 30px;\r\n text-align: center;\r\n }\r\n .header h1 {\r\n font-size: 32px;\r\n margin-bottom: 10px;\r\n }\r\n .header .time {\r\n font-size: 14px;\r\n opacity: 0.9;\r\n }\r\n .content {\r\n padding: 30px;\r\n }\r\n .section {\r\n margin-bottom: 30px;\r\n }\r\n .section-title {\r\n font-size: 20px;\r\n font-weight: bold;\r\n color: #333;\r\n margin-bottom: 15px;\r\n padding-bottom: 10px;\r\n border-bottom: 2px solid #667eea;\r\n }\r\n .stats-grid {\r\n display: grid;\r\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\r\n gap: 20px;\r\n margin-bottom: 20px;\r\n }\r\n .stat-card {\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n color: white;\r\n padding: 20px;\r\n border-radius: 12px;\r\n text-align: center;\r\n }\r\n .stat-value {\r\n font-size: 32px;\r\n font-weight: bold;\r\n margin: 10px 0;\r\n }\r\n .stat-label {\r\n font-size: 14px;\r\n opacity: 0.9;\r\n }\r\n .file-list {\r\n background: #f7fafc;\r\n border-radius: 8px;\r\n padding: 15px;\r\n }\r\n .file-item {\r\n display: flex;\r\n justify-content: space-between;\r\n padding: 10px;\r\n border-bottom: 1px solid #e2e8f0;\r\n }\r\n .file-item:last-child {\r\n border-bottom: none;\r\n }\r\n .file-name {\r\n font-family: monospace;\r\n color: #333;\r\n }\r\n .file-size {\r\n color: #667eea;\r\n font-weight: bold;\r\n }\r\n .issue {\r\n background: #fff5f5;\r\n border-left: 4px solid #f56565;\r\n padding: 15px;\r\n border-radius: 8px;\r\n margin-bottom: 15px;\r\n }\r\n .issue.medium {\r\n background: #fffaf0;\r\n border-left-color: #ed8936;\r\n }\r\n .issue.low {\r\n background: #f0f9ff;\r\n border-left-color: #4299e1;\r\n }\r\n .issue-title {\r\n font-weight: bold;\r\n color: #333;\r\n margin-bottom: 8px;\r\n }\r\n .issue-desc {\r\n color: #666;\r\n margin-bottom: 8px;\r\n }\r\n .issue-suggestion {\r\n background: #e6fffa;\r\n padding: 10px;\r\n border-radius: 6px;\r\n margin-top: 10px;\r\n color: #234e52;\r\n }\r\n .suggestion-list {\r\n background: #f0fdf4;\r\n border-radius: 8px;\r\n padding: 15px;\r\n }\r\n .suggestion-item {\r\n padding: 10px;\r\n border-bottom: 1px solid #d1fae5;\r\n color: #065f46;\r\n }\r\n .suggestion-item:last-child {\r\n border-bottom: none;\r\n }\r\n .ai-analysis {\r\n background: #f0f9ff;\r\n border-left: 4px solid #3b82f6;\r\n padding: 20px;\r\n border-radius: 8px;\r\n line-height: 1.8;\r\n color: #1e40af;\r\n white-space: pre-wrap;\r\n }\r\n .footer {\r\n background: #f7fafc;\r\n padding: 20px;\r\n text-align: center;\r\n color: #718096;\r\n font-size: 14px;\r\n }\r\n .trend-up {\r\n background: linear-gradient(135deg, #f56565 0%, #ed8936 100%) !important;\r\n }\r\n .trend-down {\r\n background: linear-gradient(135deg, #48bb78 0%, #38a169 100%) !important;\r\n }\r\n .optimization-example {\r\n background: #f7fafc;\r\n border-radius: 12px;\r\n padding: 20px;\r\n margin-bottom: 20px;\r\n border: 1px solid #e2e8f0;\r\n }\r\n .example-header {\r\n margin-bottom: 15px;\r\n }\r\n .example-title {\r\n font-size: 18px;\r\n font-weight: bold;\r\n color: #333;\r\n margin-bottom: 8px;\r\n display: flex;\r\n align-items: center;\r\n gap: 10px;\r\n }\r\n .priority-badge {\r\n font-size: 12px;\r\n padding: 4px 12px;\r\n border-radius: 12px;\r\n font-weight: normal;\r\n }\r\n .priority-high {\r\n background: #fed7d7;\r\n color: #c53030;\r\n }\r\n .priority-medium {\r\n background: #feebc8;\r\n color: #c05621;\r\n }\r\n .priority-low {\r\n background: #bee3f8;\r\n color: #2c5282;\r\n }\r\n .example-meta {\r\n display: flex;\r\n gap: 15px;\r\n font-size: 14px;\r\n color: #666;\r\n }\r\n .example-desc {\r\n color: #666;\r\n margin-bottom: 15px;\r\n line-height: 1.6;\r\n }\r\n .code-block {\r\n background: #1e293b;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n margin-top: 10px;\r\n }\r\n .code-header {\r\n background: #334155;\r\n color: #94a3b8;\r\n padding: 8px 15px;\r\n font-size: 12px;\r\n font-family: monospace;\r\n }\r\n .code-block pre {\r\n margin: 0;\r\n padding: 15px;\r\n overflow-x: auto;\r\n }\r\n .code-block code {\r\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\r\n font-size: 13px;\r\n line-height: 1.6;\r\n color: #e2e8f0;\r\n }\r\n .related-files {\r\n margin-top: 15px;\r\n padding: 10px;\r\n background: #e6fffa;\r\n border-radius: 6px;\r\n font-size: 14px;\r\n color: #234e52;\r\n }\r\n </style>\r\n</head>\r\n<body>\r\n <div class=\"container\">\r\n <div class=\"header\">\r\n <h1>⚡ 性能分析报告</h1>\r\n <div class=\"time\">生成时间: ${result.timestamp}</div>\r\n </div>\r\n\r\n <div class=\"content\">\r\n <!-- 总体统计 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">📊 总体统计</div>\r\n <div class=\"stats-grid\">\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">总大小</div>\r\n <div class=\"stat-value\">${(\r\n result.summary.totalSize /\r\n 1024 /\r\n 1024\r\n ).toFixed(2)}MB</div>\r\n </div>\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">Gzip 后</div>\r\n <div class=\"stat-value\">${(\r\n result.summary.totalGzipSize /\r\n 1024 /\r\n 1024\r\n ).toFixed(2)}MB</div>\r\n </div>\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">文件数量</div>\r\n <div class=\"stat-value\">${result.summary.fileCount}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- 最大文件 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">📦 最大的文件</div>\r\n <div class=\"file-list\">\r\n ${result.summary.largestFiles\r\n .slice(0, 10)\r\n .map(\r\n (file) => `\r\n <div class=\"file-item\">\r\n <span class=\"file-name\">${file.name}</span>\r\n <span class=\"file-size\">${(file.size / 1024).toFixed(2)}KB</span>\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n </div>\r\n\r\n <!-- 按类型统计 -->\r\n <div class=\"section\">\r\n <div class=\"section-title\">📋 按类型统计</div>\r\n <div class=\"file-list\">\r\n ${Object.entries(result.summary.byType)\r\n .map(\r\n ([type, info]) => `\r\n <div class=\"file-item\">\r\n <span class=\"file-name\">${type}</span>\r\n <span class=\"file-size\">${info.count} 个, ${(\r\n info.size / 1024\r\n ).toFixed(2)}KB</span>\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n </div>\r\n\r\n <!-- 历史对比 -->\r\n ${\r\n result.comparison\r\n ? `\r\n <div class=\"section\">\r\n <div class=\"section-title\">📈 历史对比</div>\r\n <div class=\"stats-grid\">\r\n <div class=\"stat-card ${\r\n result.comparison.totalSize.trend === \"increased\"\r\n ? \"trend-up\"\r\n : \"trend-down\"\r\n }\">\r\n <div class=\"stat-label\">总大小变化</div>\r\n <div class=\"stat-value\">${\r\n result.comparison.totalSize.diffPercent > 0 ? \"+\" : \"\"\r\n }${result.comparison.totalSize.diffPercent.toFixed(2)}%</div>\r\n <div class=\"stat-label\">${\r\n result.comparison.totalSize.trend === \"increased\" ? \"+\" : \"\"\r\n }${(result.comparison.totalSize.diff / 1024 / 1024).toFixed(\r\n 2,\r\n )}MB</div>\r\n </div>\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">文件数变化</div>\r\n <div class=\"stat-value\">${\r\n result.comparison.fileCount.diff > 0 ? \"+\" : \"\"\r\n }${result.comparison.fileCount.diff}</div>\r\n </div>\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">新增文件</div>\r\n <div class=\"stat-value\">${result.comparison.newFiles.length}</div>\r\n </div>\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">删除文件</div>\r\n <div class=\"stat-value\">${\r\n result.comparison.removedFiles.length\r\n }</div>\r\n </div>\r\n </div>\r\n ${\r\n result.comparison.largestFileChanges.length > 0\r\n ? `\r\n <div class=\"file-list\" style=\"margin-top: 15px;\">\r\n <div style=\"font-weight: bold; padding: 10px; color: #333;\">文件大小变化 Top 5:</div>\r\n ${result.comparison.largestFileChanges\r\n .slice(0, 5)\r\n .map(\r\n (change) => `\r\n <div class=\"file-item\">\r\n <span class=\"file-name\">${change.name}</span>\r\n <span class=\"file-size ${\r\n change.diff > 0 ? \"trend-up\" : \"trend-down\"\r\n }\">\r\n ${change.diff > 0 ? \"+\" : \"\"}${(change.diff / 1024).toFixed(\r\n 2,\r\n )}KB\r\n </span>\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n\r\n <!-- 依赖分析 -->\r\n ${\r\n result.dependencies\r\n ? `\r\n <div class=\"section\">\r\n <div class=\"section-title\">📦 依赖分析</div>\r\n <div class=\"stats-grid\">\r\n <div class=\"stat-card\">\r\n <div class=\"stat-label\">总依赖数</div>\r\n <div class=\"stat-value\">${result.dependencies.total}</div>\r\n </div>\r\n <div class=\"stat-card ${\r\n result.dependencies.duplicates.length > 0 ? \"trend-up\" : \"\"\r\n }\">\r\n <div class=\"stat-label\">重复依赖</div>\r\n <div class=\"stat-value\">${\r\n result.dependencies.duplicates.length\r\n }</div>\r\n </div>\r\n </div>\r\n ${\r\n result.dependencies.duplicates.length > 0\r\n ? `\r\n <div class=\"file-list\" style=\"margin-top: 15px;\">\r\n <div style=\"font-weight: bold; padding: 10px; color: #333;\">重复打包的依赖:</div>\r\n ${result.dependencies.duplicates\r\n .slice(0, 10)\r\n .map(\r\n (dep) => `\r\n <div class=\"file-item\">\r\n <span class=\"file-name\">${dep.name}</span>\r\n <span class=\"file-size\">\r\n ${(dep.size / 1024).toFixed(2)}KB · 被 ${\r\n dep.usedBy.length\r\n } 个文件使用\r\n </span>\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n ${\r\n result.dependencies.largest.length > 0\r\n ? `\r\n <div class=\"file-list\" style=\"margin-top: 15px;\">\r\n <div style=\"font-weight: bold; padding: 10px; color: #333;\">最大的依赖:</div>\r\n ${result.dependencies.largest\r\n .slice(0, 10)\r\n .map(\r\n (dep) => `\r\n <div class=\"file-item\">\r\n <span class=\"file-name\">${dep.name}</span>\r\n <span class=\"file-size\">${(dep.size / 1024).toFixed(\r\n 2,\r\n )}KB</span>\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n\r\n <!-- 性能问题 -->\r\n ${\r\n result.issues.length > 0\r\n ? `\r\n <div class=\"section\">\r\n <div class=\"section-title\">⚠️ 性能问题</div>\r\n ${result.issues\r\n .map(\r\n (issue) => `\r\n <div class=\"issue ${issue.severity}\">\r\n <div class=\"issue-title\">${this.getSeverityIcon(\r\n issue.severity,\r\n )} ${issue.title}</div>\r\n <div class=\"issue-desc\">${issue.description}</div>\r\n ${\r\n issue.files\r\n ? `<div class=\"issue-desc\">相关文件: ${issue.files.join(\r\n \", \",\r\n )}</div>`\r\n : \"\"\r\n }\r\n ${\r\n issue.suggestion\r\n ? `<div class=\"issue-suggestion\">💡 ${issue.suggestion}</div>`\r\n : \"\"\r\n }\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n `\r\n : '<div class=\"section\"><div class=\"section-title\">✅ 未发现明显的性能问题</div></div>'\r\n }\r\n\r\n <!-- 优化建议 -->\r\n ${\r\n result.suggestions.length > 0\r\n ? `\r\n <div class=\"section\">\r\n <div class=\"section-title\">💡 优化建议</div>\r\n <div class=\"suggestion-list\">\r\n ${result.suggestions\r\n .map(\r\n (suggestion, index) => `\r\n <div class=\"suggestion-item\">${index + 1}. ${suggestion}</div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n\r\n <!-- 优化示例 -->\r\n ${\r\n result.optimizationExamples && result.optimizationExamples.length > 0\r\n ? `\r\n <div class=\"section\">\r\n <div class=\"section-title\">🔧 优化示例</div>\r\n ${result.optimizationExamples\r\n .map(\r\n (example) => `\r\n <div class=\"optimization-example\">\r\n <div class=\"example-header\">\r\n <div class=\"example-title\">\r\n ${example.title}\r\n <span class=\"priority-badge priority-${example.priority}\">${\r\n example.priority === \"high\"\r\n ? \"高优先级\"\r\n : example.priority === \"medium\"\r\n ? \"中优先级\"\r\n : \"低优先级\"\r\n }</span>\r\n </div>\r\n <div class=\"example-meta\">\r\n <span>💪 ${example.difficulty}</span>\r\n <span>📈 ${example.impact}</span>\r\n </div>\r\n </div>\r\n <div class=\"example-desc\">${example.description}</div>\r\n <div class=\"code-block\">\r\n <div class=\"code-header\">${example.code.language}</div>\r\n <pre><code>${this.escapeHtml(example.code.content)}</code></pre>\r\n </div>\r\n ${\r\n example.relatedFiles && example.relatedFiles.length > 0\r\n ? `\r\n <div class=\"related-files\">\r\n <strong>相关文件:</strong> ${example.relatedFiles.join(\", \")}\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n </div>\r\n `,\r\n )\r\n .join(\"\")}\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n\r\n <!-- AI 分析 -->\r\n ${\r\n result.aiAnalysis\r\n ? `\r\n <div class=\"section\">\r\n <div class=\"section-title\">🤖 AI 分析</div>\r\n <div class=\"ai-analysis\">${this.escapeHtml(result.aiAnalysis)}</div>\r\n </div>\r\n `\r\n : \"\"\r\n }\r\n </div>\r\n\r\n <div class=\"footer\">\r\n <p>AI Performance Analyzer v1.0.0</p>\r\n <p>Powered by Vite & OpenAI</p>\r\n </div>\r\n </div>\r\n</body>\r\n</html>\r\n `.trim();\r\n\r\n // 创建报告目录\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n if (!fs.existsSync(reportsDir)) {\r\n fs.mkdirSync(reportsDir, { recursive: true });\r\n }\r\n\r\n const reportPath = path.resolve(reportsDir, \"performance-report.html\");\r\n fs.writeFileSync(reportPath, html, \"utf-8\");\r\n console.log(pc.green(`\\n📄 性能报告已生成: ${pc.cyan(reportPath)}\\n`));\r\n }\r\n\r\n /**\r\n * 生成 JSON 报告\r\n */\r\n private async generateJSONReport(result: AnalysisResult): Promise<void> {\r\n const reportsDir = path.resolve(process.cwd(), \"ai-reports\");\r\n if (!fs.existsSync(reportsDir)) {\r\n fs.mkdirSync(reportsDir, { recursive: true });\r\n }\r\n\r\n const reportPath = path.resolve(reportsDir, \"performance-report.json\");\r\n fs.writeFileSync(reportPath, JSON.stringify(result, null, 2), \"utf-8\");\r\n console.log(pc.green(`📄 JSON 报告已生成: ${pc.cyan(reportPath)}`));\r\n }\r\n\r\n /**\r\n * 获取严重程度图标\r\n */\r\n private getSeverityIcon(severity: string): string {\r\n const icons: Record<string, string> = {\r\n high: \"🔴\",\r\n medium: \"🟡\",\r\n low: \"🔵\",\r\n };\r\n return icons[severity] || \"⚪\";\r\n }\r\n\r\n /**\r\n * 转义 HTML\r\n */\r\n private escapeHtml(text: string): string {\r\n const map: Record<string, string> = {\r\n \"&\": \"&amp;\",\r\n \"<\": \"&lt;\",\r\n \">\": \"&gt;\",\r\n '\"': \"&quot;\",\r\n \"'\": \"&#039;\",\r\n };\r\n return text.replace(/[&<>\"']/g, (m) => map[m]);\r\n }\r\n}\r\n"],"mappings":"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","names":["pc","fs","path","fs","path","path","fs","fs","path","pc"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-ai-perf-analyzer",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "AI-powered performance analyzer for Vite - Analyze bundle size and suggest optimizations",
5
5
  "keywords": [
6
6
  "vite",
@@ -44,7 +44,7 @@
44
44
  "picocolors": "^1.1.1",
45
45
  "@langchain/core": "^0.3.0",
46
46
  "@langchain/openai": "^0.3.0",
47
- "vite-plugin-ai-shared": "1.0.0"
47
+ "vite-plugin-ai-shared": "1.0.1"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/node": "^20.0.0",