欢迎光临
我们一直在努力

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[]): Promise<ComponentHealth[]> { 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;

    // 僵尸 Props const 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[]): Promise<any[]> { // 扫描所有项目的代码文件,提取组件使用记录 return []; }

private async loadComponentDefinitions(): Promise<Record<string, 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 中。不是为了让谁去读,而是当某个组件的健康分持续下降时,自动触发"是否需要重构"的讨论。

赞(0)
未经允许不得转载:171主机测评 » AI 辅助的设计系统健康报告:自动生成组件使用率与弃用分析
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址