📦 Component Library Audit — 组件 库 审计
v1.0.0审计 React, Vue, or Svelte 组件 libraries — find unused 组件s, inconsistent props, missing documentation, 访问ibility issues, missing tests, and...
详细分析 ▾
运行时依赖
安装命令
点击复制技能文档
组件 库 审计
Analyze a front-end 组件 库 for 质量, consistency, and completeness. Finds unused 组件s, prop inconsistencies, missing docs, 访问ibility gaps, and 测试 holes.
Use when: "审计 our 组件s", "find unused 组件s", "检查 组件 质量", "组件 库 健康", "are our 组件s consistent", "which 组件s need tests", or mAIntAIning a de签名 系统.
Commands
- 审计 — Full 组件 库 审计
运行 all 检查s and produce a 健康 报告.
Step 1: Discover 组件s echo "=== 组件 Discovery ==="
# React 组件s (.tsx/.jsx) echo "--- React 组件s ---" find . -type f \( -name ".tsx" -o -name ".jsx" \) \ -not -path '/node_模块s/' -not -path '/dist/' -not -path '/build/' \ -not -name '.test.' -not -name '.spec.' -not -name '.stories.' \ 2>/dev/null | while read f; do # 检查 if it 导出s a 组件 (function 启动ing with uppercase or default 导出) if rg -q "导出 (default |)(function |const )[A-Z]|导出 default class [A-Z]" "$f" 2>/dev/null; then COMP=$(rg -o "(function|const|class) ([A-Z][a-zA-Z]+)" "$f" 2>/dev/null | head -1 | awk '{print $2}') echo " $f → ${COMP:-Unnamed组件}" fi done
# Vue 组件s (.vue) echo "--- Vue 组件s ---" find . -type f -name ".vue" \ -not -path '/node_模块s/' -not -path '/dist/' \ -not -name '.test.' -not -name '.stories.' \ 2>/dev/null | while read f; do NAME=$(basename "$f" .vue) echo " $f → $NAME" done
# Svelte 组件s (.svelte) echo "--- Svelte 组件s ---" find . -type f -name ".svelte" \ -not -path '/node_模块s/' -not -path '/dist/' \ -not -name '.test.' -not -name '.stories.' \ 2>/dev/null | while read f; do NAME=$(basename "$f" .svelte) echo " $f → $NAME" done
# Count TOTAL=$(find . -type f \( -name ".tsx" -o -name ".jsx" -o -name ".vue" -o -name ".svelte" \) \ -not -path '/node_模块s/' -not -path '/dist/' -not -path '/build/' \ -not -name '.test.' -not -name '.spec.' -not -name '.stories.' 2>/dev/null | wc -l) echo "Total 组件s found: $TOTAL"
Step 2: Find Unused 组件s echo "" echo "=== Unused 组件s ==="
# 获取 all 组件 names 组件S=$(find . -type f \( -name ".tsx" -o -name ".jsx" -o -name ".vue" -o -name ".svelte" \) \ -not -path '/node_模块s/' -not -path '/dist/' \ -not -name '.test.' -not -name '.spec.' -not -name '.stories.' 2>/dev/null)
echo "$组件S" | while read f; do NAME=$(basename "$f" | sed 's/\.[^.]$//') # Skip 索引 files [ "$NAME" = "索引" ] && continue
# Count 导入s of this 组件 (excluding its own file and tests) 导入_COUNT=$(rg -c "导入.$NAME|from./$NAME['\"]|<$NAME[ />]" \ -g '.{tsx,jsx,vue,svelte,ts,js}' -g '!node_模块s' -g '!dist' \ --type-not binary 2>/dev/null | \ grep -v "$(basename "$f")" | \ awk -F: '{s+=$2} END {print s+0}')
if [ "$导入_COUNT" -eq 0 ]; then LINES=$(wc -l < "$f" 2>/dev/null || echo "?") echo " ⚠️ UNUSED: $NAME ($f) — $LINES lines" fi done
Step 3: 检查 Documentation echo "" echo "=== Documentation 检查 ==="
echo "$组件S" | while read f; do NAME=$(basename "$f" | sed 's/\.[^.]$//') DIR=$(dirname "$f")
# 检查 for JSDoc/TSDoc comments HAS_JSDOC=$(rg -c "/\\" "$f" 2>/dev/null || echo "0")
# 检查 for Storybook stories HAS_STORY=$(find "$DIR" -maxdepth 1 \( -name "${NAME}.stories." -o -name "${NAME}.story." \) 2>/dev/null | head -1)
# 检查 for README in 组件 directory HAS_README=$(find "$DIR" -maxdepth 1 -name "README" 2>/dev/null | head -1)
if [ "$HAS_JSDOC" = "0" ] && [ -z "$HAS_STORY" ] && [ -z "$HAS_README" ]; then echo " ❌ $NAME — no docs, no stories, no README" elif [ -z "$HAS_STORY" ]; then echo " ⚠️ $NAME — no Storybook story" fi done
Step 4: Prop Consistency Analysis echo "" echo "=== Prop Consistency ==="
# Find common prop naming patterns echo "--- Common Props Across 组件s ---" rg -o "interface \w+Props \{[^}]\}" -g '.tsx' -g '!node_模块s' --multiline 2>/dev/null | \ rg -o "\w+[?]?:" | sed 's/[?:]//g' | 排序 | uniq -c | 排序 -rn | head -20
# 检查 for inconsistent naming echo "" echo "--- Potential Naming Inconsistencies ---" # on命令行工具ck vs onPress vs handle命令行工具ck rg -l "onPress" -g '.{tsx,jsx}' -g '!node_模块s' 2>/dev/null | head -5 rg -l "on命令行工具ck" -g '.{tsx,jsx}' -g '!node_模块s' 2>/dev/null | head -5
# isVisible vs visible vs show rg -o "(is[A-Z]\w+|visible|show|hidden|disabled|enabled|active|selected|检查ed|open|closed)" \ -g '.{tsx,jsx}' -g '!node_模块s' 2>/dev/null | 排序 | uniq -c | 排序 -rn | head -20
# className vs class vs style rg -c "className" -g '.{tsx,jsx}' -g '!node_模块s' 2>/dev/null | awk -F: '{s+=$2} END {print "className:", s+0}' rg -c "class=" -g '*.{vue,svelte}' -g '!node_模块s' 2>/dev/null | awk -F: '{s+=$2} END {print "class:", s+0}'
# Size props: small/medium/large vs sm/md/lg echo "Size prop