← 返回
未分类 中文

Svelte Component Auditor

Audit Svelte and SvelteKit components for performance, accessibility, reactive statement usage, store design, and SSR compatibility. Use when reviewing Svelt...
审计 Svelte 与 SvelteKit 组件的性能、可访问性、响应式语句使用、store 设计以及 SSR 兼容性。在审查 Svelte 代码时使用。
charlie-morrison charlie-morrison 来源
未分类 clawhub v1.0.0 1 版本 100000 Key: 无需
★ 0
Stars
📥 303
下载
💾 0
安装
1
版本
#latest

概述

Svelte Component Auditor

Deep audit of Svelte and SvelteKit components. Analyzes reactive declarations, store patterns, accessibility, SSR readiness, and rendering performance. Produces prioritized findings with concrete fixes.

Use when: reviewing a Svelte/SvelteKit project, preparing for production, auditing accessibility, or establishing component quality standards.

Analysis Steps

1. Project Discovery

cat package.json 2>/dev/null | jq '{svelte: .devDependencies.svelte, sveltekit: .devDependencies["@sveltejs/kit"]}'
cat svelte.config.js 2>/dev/null || cat svelte.config.ts 2>/dev/null
find . -name "*.svelte" -not -path '*/node_modules/*' -not -path '*/.svelte-kit/*' | wc -l
find . -path "*/routes/*" -name "+*" -not -path '*/node_modules/*' 2>/dev/null | sort | head -20

Determine: Svelte version (4 vs 5 runes), SvelteKit presence, adapter type, component count, route structure.

2. Reactive Statement Audit

# Reactive declarations ($: label syntax — Svelte 4)
grep -rn '^\s*\$:' --include="*.svelte" . 2>/dev/null | head -25

# Reactive assignments that won't trigger (array mutation)
grep -rn '\$:.*\.push\|\$:.*\.splice\|\$:.*\.sort' --include="*.svelte" . 2>/dev/null | head -15

# Complex reactive chains (>5 per component = smell)
for f in $(find . -name "*.svelte" -not -path '*/node_modules/*' 2>/dev/null); do
  count=$(grep -c '^\s*\$:' "$f" 2>/dev/null)
  if [ "$count" -gt 5 ]; then echo "COMPLEX($count): $f"; fi
done | head -15

# Svelte 5 runes
grep -rn '\$state\|\$derived\|\$effect\|\$props' --include="*.svelte" --include="*.svelte.ts" . 2>/dev/null | head -15

Check for:

  • Mutating arrays in reactive declarations: $: items.push(x) won't trigger — must reassign: items = [...items, x]
  • Circular reactive dependencies: cause runtime errors
  • Over-complex reactive chains: >5 $: declarations signals need for store or utility extraction
  • $effect without cleanup: effects with subscriptions/timers must return a cleanup function

3. Store Design Analysis

grep -rn "writable(\|readable(\|derived(" --include="*.ts" --include="*.js" --include="*.svelte" . 2>/dev/null | grep -v 'venv/' | head -20

# Store subscriptions without unsubscribe (leak in non-component code)
grep -rn "\.subscribe(" --include="*.ts" --include="*.js" . 2>/dev/null | head -15

# Auto-subscription in components ($store)
grep -rn '\$[a-zA-Z]' --include="*.svelte" . 2>/dev/null | grep -v '\$:\|//' | head -15

Flag:

  • Store subscriptions in .ts/.js without unsubscribe: auto-unsubscribe ($store) only works in .svelte files
  • Global stores with SSR: module-scope writable stores cause cross-request data leaks — use context or page data
  • Missing derived stores: repeated computations across components should be derived
  • Overloaded stores: single store managing unrelated concerns — split by domain

4. Performance Analysis

# Large components (>200 lines)
for f in $(find . -name "*.svelte" -not -path '*/node_modules/*' 2>/dev/null); do
  lines=$(wc -l < "$f"); if [ "$lines" -gt 200 ]; then echo "LARGE($lines): $f"; fi
done | sort -t'(' -k1.7 -rn | head -10

# Unkeyed each blocks
grep -rn '{#each' --include="*.svelte" . 2>/dev/null | grep -v '(' | head -15

# bind:this overuse
grep -rn "bind:this" --include="*.svelte" . 2>/dev/null | head -15

Flag:

  • Unkeyed each blocks: {#each items as item} without key causes full list re-renders on any change
  • Components >300 lines: decompose into sub-components
  • Excessive bind:this: direct DOM manipulation bypasses reactivity

5. Accessibility Audit

# Images without alt
grep -rn '<img' --include="*.svelte" . 2>/dev/null | grep -v 'alt=' | head -15

# Click handlers on non-interactive elements
grep -rn 'on:click' --include="*.svelte" . 2>/dev/null \
  | grep '<div\|<span\|<li\|<p' | head -15

# Form inputs without labels
grep -rn '<input' --include="*.svelte" . 2>/dev/null \
  | grep -v 'aria-label\|id=.*label\|type="hidden"\|type="submit"' | head -15

# Focus management
grep -rn 'focus()\|tabindex\|aria-live\|aria-expanded' --include="*.svelte" . 2>/dev/null | head -10

Flag with WCAG reference:

  • Images without alt: WCAG 1.1.1 — all must have alt (empty for decorative)
  • Click on non-interactive elements: WCAG 4.1.2 — use
  • Inputs without labels: WCAG 1.3.1 — every form control needs an accessible name
  • No aria-live regions: WCAG 4.1.3 — dynamic status messages need aria-live="polite"

6. SSR Compatibility

# Browser-only APIs used outside onMount
grep -rn 'window\.\|document\.\|localStorage\|sessionStorage\|navigator\.' \
  --include="*.svelte" --include="*.ts" . 2>/dev/null \
  | grep -v 'node_modules\|\.svelte-kit\|onMount\|onDestroy\|browser' | head -15

# $app/environment browser guard
grep -rn "import.*browser.*\$app" --include="*.svelte" --include="*.ts" . 2>/dev/null | head -10

# Data fetching in components instead of load functions
grep -rn "fetch(" --include="*.svelte" . 2>/dev/null | grep -v 'node_modules' | head -10

# Private env leaked to client
grep -rn '\$env/static/private\|\$env/dynamic/private' --include="*.svelte" . 2>/dev/null | head -5

Flag:

  • Browser APIs outside lifecycle hooks: window, document, localStorage at top level crash SSR
  • Missing browser guard: import { browser } from $app/environment to guard browser-only code
  • Cross-request state pollution: module-level mutable state shared across SSR requests
  • Private env in client code: $env/static/private imported in .svelte files leaks secrets
  • Fetching in components: SvelteKit load functions provide streaming, caching, and SSR — component fetch loses these

7. Component API Surface

grep -rn 'export let ' --include="*.svelte" . 2>/dev/null | head -15
grep -rn 'export let [a-zA-Z]*;$' --include="*.svelte" . 2>/dev/null | head -10
grep -rn "createEventDispatcher\|setContext\|getContext" --include="*.svelte" . 2>/dev/null | head -15
grep -rn '\$\$props\|\$\$restProps' --include="*.svelte" . 2>/dev/null | head -10

Flag:

  • Props without defaults: no compile-time enforcement that callers provide them
  • $$props/$$restProps overuse: bypasses Svelte's prop tracking, prevents tree-shaking
  • Missing slot fallback content: fallback provides better DX
  • Untyped context: setContext/getContext should use typed keys

Output Template

# Svelte Component Audit — [Project Name]

## Summary
- Components: N | Svelte: 4.x/5.x | SvelteKit: yes/no
- Critical: N | Warnings: N | A11y violations: N

## Critical Findings
### [C1] SSR Crash — `window.innerWidth` at top level
- **File**: src/routes/dashboard/+page.svelte:8
- **Fix**: Move inside `onMount(() => { ... })`

### [C2] Cross-Request State Leak
- **File**: src/lib/stores/user.ts:3 — module-scope writable
- **Fix**: Initialize in load functions or context API

## Accessibility Violations
| Rule | Count | Severity | Files |
|------|-------|----------|-------|
| img-alt-missing | N | Critical | file1, file2 |
| click-on-div | N | High | file3 |
| input-no-label | N | High | file4 |

## Performance Issues
| Issue | File | Fix |
|-------|------|-----|
| Unkeyed each block | List.svelte:24 | Add `(item.id)` key |
| 450-line component | Dashboard.svelte | Split into sub-components |

## Recommendations
1. Fix N SSR-breaking browser API usages
2. Add keys to N each blocks
3. Resolve N accessibility violations
4. Move N module-scope stores to context/load for SSR safety
5. Add `+error.svelte` at route group levels

Tips

  • Run npx svelte-check for type errors, a11y warnings, and unused CSS
  • Use @sveltejs/enhanced-img for automatic image optimization in SvelteKit
  • Enable compilerOptions.runes: true in svelte.config.js to start Svelte 5 migration
  • Use {#key expression} to force-recreate a component when data changes
  • Test SSR locally with adapter-node before deploying to catch browser API issues

版本历史

共 1 个版本

  • v1.0.0 当前
    2026-05-08 02:33 安全 安全

安全检测

腾讯云安全 (Keen)

安全,无风险
查看报告

腾讯云安全 (Sanbu)

安全,无风险
查看报告

🔗 相关推荐

Devcontainer Validator

charlie-morrison
在 VS Code 开发容器中验证 devcontainer.json 的语法、结构、功能、端口、生命周期脚本、定制项及安全最佳实践。
★ 0 📥 470

Pyproject Toml Validator

charlie-morrison
依据 PEP 517/621 规则校验 pyproject.toml 文件,验证项目元数据、构建系统和工具配置,并提供详细报告。
★ 0 📥 474

Stylelint Config Validator

charlie-morrison
校验 Stylelint 配置文件,检查错误、已弃用规则、配置结构、插件、extends 和 overrides,并输出文本或 JSON 结果。
★ 0 📥 461