AI 辅助的设计系统健康报告:自动生成组件使用率与弃用分析

发布时间:2026/7/19 18:16:02
AI 辅助的设计系统健康报告:自动生成组件使用率与弃用分析 AI 辅助的设计系统健康报告自动生成组件使用率与弃用分析一、这个组件三年前写的现在还有人在用吗设计系统维护者常见困境组件数量持续增长300但没人知道哪些组件还在用、哪些已经死了、哪些被滥用了。删除一个组件需要手动调研三周最后发现不敢删万一有人用呢。健康报告就是解决组件库的未知债务问题自动扫描全量业务代码统计每个组件的使用频率、使用方式Props 组合、最近使用时间生成一份量化的组件健康度报告。二、健康度评分模型健康度评分模型通过全量代码扫描启动自动提取组件引用并构建组件使用矩阵。基于该矩阵系统从五个关键维度量化组件状态使用频率0-100 分、Props 使用广度0-100 分、最近使用时间30 天内满分半年以上为 0 分、使用趋势增长/稳定/下降以及兼容性问题违反设计规范次数。上述维度数据将汇聚为综合健康分并依据分数区间进行状态判定健康 80 分广泛使用状态良好。注意50-80 分使用率下降需关注。危险 50 分考虑弃用或重构。死亡0 分可安全删除。三、健康报告生成器// health-report/component-health-analyzer.ts // 组件健康度分析器 interface ComponentHealth { componentName: string; /** 总使用次数 */ usageCount: number; ---/** 使用该组件的页面/模块数量/usageScope: number;/* 最后使用日期/lastUsedDate: string;/* Props 使用率被使用的 Props / 总 Props/propsUsageRate: number;/* 僵尸 Props定义了但从未被使用的 Props/zombieProps: string[];/* 使用趋势最近 3 个月 vs 前 3 个月/trend: growing | stable | declining | new | dead;/* 设计规范违规次数不推荐用法/designViolations: number;/* 综合健康分 0-100/healthScore: number;/* 建议操作 */recommendation: keep | monitor | refactor | deprecate | remove;}/**设计系统健康报告生成器扫描整个 monorepo分析每个组件的使用情况/class HealthReportGenerator {/*生成全量健康报告*/async generateReport(projectRoots: string[]): PromiseComponentHealth[] {const allUsages await this.scanAllProjects(projectRoots);const componentDefs await this.loadComponentDefinitions();const healths: ComponentHealth[] [];for (const [name, def] of Object.entries(componentDefs)) {const usage allUsages.filter(u u.componentName name);// 计算 Props 使用率const usedProps new Set();usage.forEach(u {Object.keys(u.props).forEach(p usedProps.add(p));});const totalDefinedProps def.props.length;const propsUsageRate totalDefinedProps 0? usedProps.size / totalDefinedProps: 1;// 僵尸 Propsconst zombieProps def.props.filter(p !usedProps.has(p.name)).map(p p.name);// 使用趋势const trend this.calcTrend(usage, name);// 健康分计算const healthScore this.calcHealthScore({usageCount: usage.length,usageScope: new Set(usage.map(u u.file)).size,propsUsageRate,zombiePropCount: zombieProps.length,trend,violations: 0});// 建议const recommendation this.getRecommendation(healthScore, usage.length, trend);healths.push({componentName: name,usageCount: usage.length,usageScope: new Set(usage.map(u u.file)).size,lastUsedDate: this.getLastUsedDate(usage),propsUsageRate: Math.round(propsUsageRate * 100) / 100,zombieProps,trend,designViolations: 0,healthScore,recommendation});}return healths.sort((a, b) b.usageCount - a.usageCount);}/**健康分计算权重分配使用频率: 30%使用广度: 20%Props 使用率: 20%近期活跃度: 15%趋势: 10%违规扣分: 5%*/private calcHealthScore(params: {usageCount: number;usageScope: number;propsUsageRate: number;zombiePropCount: number;trend: string;violations: number;}): number {let score 0;// 使用频率0-30分 if (params.usageCount 0) { score 0; } else if (params.usageCount 5) { score 10; } else if (params.usageCount 20) { score 20; } else { score 30; } // 使用广度0-20分 if (params.usageScope 20) score 20; else if (params.usageScope 10) score 15; else if (params.usageScope 3) score 10; else if (params.usageScope 0) score 5; // Props 使用率0-20分 score Math.round(params.propsUsageRate * 20); // 近期活跃度0-15分 // 由 calcTrend 内部赋值 // 趋势分数0-10分 switch (params.trend) { case growing: score 10; break; case stable: score 7; break; case new: score 5; break; case declining: score 2; break; case dead: score 0; break; } // 违规扣分-5分上限 score - Math.min(5, params.violations); // 僵尸 Props 扣分 score - Math.min(5, params.zombiePropCount * 2); return Math.max(0, Math.min(100, score));}/**使用趋势计算*/private calcTrend(usages: any[],componentName: string): growing | stable | declining | new | dead {if (usages.length 0) return dead;const threeMonthsAgo Date.now() - 90 * 24 * 60 * 60 * 1000; const sixMonthsAgo Date.now() - 180 * 24 * 60 * 60 * 1000; const recent usages.filter(u u.date threeMonthsAgo).length; const older usages.filter( u u.date sixMonthsAgo u.date threeMonthsAgo ).length; if (older 0 recent 0) return new; if (recent older * 1.2) return growing; if (recent older * 0.8) return declining; return stable;}private getRecommendation(score: number,usageCount: number,trend: string): ComponentHealth[recommendation] {if (usageCount 0) return remove;if (score 30) return deprecate;if (score 50) return refactor;if (score 70) return monitor;return keep;}private getLastUsedDate(usages: any[]): string {if (usages.length 0) return 从未使用;const latest Math.max(...usages.map(u u.date));return new Date(latest).toISOString().split(T)[0];}private async scanAllProjects(roots: string[]): Promiseany[] {// 扫描所有项目的代码文件提取组件使用记录return [];}private async loadComponentDefinitions(): PromiseRecordstring, any {// 加载组件库的组件定义文件return {};}}/**生成 Markdown 格式的健康报告*/function generateMarkdownReport(healths: ComponentHealth[]): string {const total healths.length;const healthy healths.filter(h h.recommendation keep).length;const atRisk healths.filter(h [monitor, refactor].includes(h.recommendation)).length;const deprecated healths.filter(h [deprecate, remove].includes(h.recommendation)).length;let report # 设计系统健康报告\n\n;report - 总组件数: ${total}\n;report - 健康: ${healthy} | 关注: ${atRisk} | 危险: ${deprecated}\n\n;report ## 危险组件建议弃用或删除\n\n;report | 组件 | 使用次数 | 健康分 | 建议 |\n;report |------|---------|--------|------|\n;for (const h of healths.filter(h h.recommendation deprecate || h.recommendation remove)) {report | ${h.componentName} | ${h.usageCount} | ${h.healthScore} | ${h.recommendation} |\n;}report \n## 僵尸 Props定义了但从未使用的 Props\n\n;for (const h of healths.filter(h h.zombieProps.length 0)) {report ### ${h.componentName}\n;for (const prop of h.zombieProps) {report - \${prop}\n;}report \n;}return report;}## 四、健康报告的时效性与可信度 **代码扫描的覆盖率**。如果只扫描 src/ 目录遗漏了测试文件、Storybook Stories 等间接使用场景报告的使用次数会低估。建议扫描范围包括.tsx、.jsx、.ts 文件中所有 JSX 标签和 createElement 调用。 **使用频率不反映重要性**。一个只在首页用了一次的关键 CTA 按钮组件比一个在 50 个后台页面使用的普通表单字段更重要。健康分需要加入使用位置的权重——首页使用权重高于设置页。 **Git 历史提供趋势数据**。仅扫描当前代码只能得到现状结合 Git 历史可以分析过去半年的使用趋势——这是健康报告中trend字段的价值来源。 ## 五、总结 设计系统健康报告将组件库的维护从凭感觉变成看数据 1. **使用矩阵**——每个组件被多少个页面/模块使用 2. **Props 分析**——哪些 Props 是僵尸属性定义但从未使用 3. **趋势判断**——使用量在增长还是下降 4. **操作建议**——删除 / 弃用 / 重构 / 监控 / 保持 这份报告应该**每周自动生成**发布到团队 Slack 频道或维护者 Dashboard 中。不是为了让谁去读而是当某个组件的健康分持续下降时自动触发是否需要重构的讨论。