mcpField
F
frontend-architecture

frontend-architecture

github.com/exceptionless開発2.5k49 回インストール1 日前に更新
リポジトリ

frontend-architecture について

Exceptionless.Web の画面を扱うコーディングエージェント向けのフロントエンド開発スキルです。新規 UI では Svelte 5 を標準とし、旧 Angular アプリの変更条件や、設計・アクセシビリティ・テストの規約を示します。

主な機能

  1. 01新規 UI は Svelte 5 を標準化
  2. 02旧 Angular の変更範囲を明示
  3. 03機能単位でコードを構成
  4. 04TypeScript とコンポーネントの規約
  5. 05アクセシビリティとテストを網羅

活用シーン

  1. 01Exceptionless.Web にページやコンポーネントを追加
  2. 02変更対象を Svelte と Angular から選択
  3. 03フロントエンドコードの一貫性を確認
  4. 04UI 変更のテストや検証方法を選定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/exceptionless/exceptionless --skill frontend-architecture

インストール後、Claude Code で/frontend-architectureを入力して読み込まれたか確認します。

詳細

フロントエンドアーキテクチャ

Exceptionless.Web には現在、2 つのフロントエンドコードベースがあります。

  • src/Exceptionless.Web/ClientApp.angular は従来の Angular UI で、現在のサイトの大部分を引き続き担っています。メンテナンス専用として扱ってください。ユーザーから Angular または従来の UI の変更を明示的に依頼された場合を除き、編集したり、ルートを追加したり、そこからパターンを移植したりしないでください。主なフォルダーは app/、components/、less/、img/、lang/、grunt/ です。
  • src/Exceptionless.Web/ClientApp は Svelte 5 アプリで、今後の新しいフロントエンド UI 開発の対象です。

標準では Svelte を使用してください。リクエストに「frontend」、「UI」、「page」、「component」、「form」、「route」とあり、Angular に明示的に言及していない場合は、src/Exceptionless.Web/ClientApp で作業してください。

ユーザーから Angular、従来の UI、またはその画面にしか存在しないバグの修正を明示的に依頼された場合に限り、ClientApp.angular で作業してください。

ディレクトリ構成

src/
├── lib/
│   ├── features/           # Feature slices (vertical organization)
│   │   ├── auth/
│   │   │   ├── api.svelte.ts
│   │   │   ├── models.ts
│   │   │   ├── schemas.ts
│   │   │   └── validators.ts
│   │   ├── organizations/
│   │   ├── projects/
│   │   ├── events/
│   │   └── shared/         # Cross-feature shared code
│   ├── generated/          # API-generated types
│   └── utils/              # Utility functions
├── routes/
│   ├── (app)/              # Authenticated app routes
│   ├── (auth)/             # Authentication routes
│   ├── status/             # Public status route
│   ├── +layout.svelte
│   └── routes.svelte.ts
└── app.html

機能スライス

機能ごとに整理し、新しいファイルを追加する前に、最も近い既存の機能構成に合わせてください。

features/organizations/
├── api.svelte.ts           # TanStack Query hooks (see tanstack-query skill)
├── models.ts               # Feature-local types and generated type aliases
├── schemas.ts              # Zod validation schemas
├── options.ts              # Dropdown options, enums
└── components/
    └── *.svelte

フォーマッターコンポーネント(必ず使用)

コンポーネントが存在する場合は、独自のフォーマット関数ではなくフォーマッターコンポーネントを使用してください。

コンポーネントパス用途
<DateTime>$comp/formatters/date-time.svelte日付と時刻の表示
<TimeAgo>$comp/formatters/time-ago.svelte相対時間(「3 時間前」)
<Duration>$comp/formatters/duration.svelte時間の長さ
<Bytes>$comp/formatters/bytes.svelteファイルサイズ、メモリ
<Number>$comp/formatters/number.svelteロケールに応じた数値の表示
<NumberCompact>$comp/formatters/number-compact.svelteコンパクトな数値表示
<Boolean>$comp/formatters/boolean.svelte真偽値の表示
<Currency>$comp/formatters/currency.svelte金額
<Percentage>$comp/formatters/percentage.svelteパーセント値
<DateMath>$comp/formatters/date-math.svelteElasticsearch の日付演算式

<DateTime value={event.date} />
<Bytes value={event.size} />


{formatDateTime(event.date)}
{new Date(event.date).toLocaleString()}

インポートエイリアス

import { Button } from "$comp/ui/button";       // shared components
import { User } from "$features/users/models";  // $lib/features
import { cn } from "$lib/utils";                // $lib

プロジェクトの Svelte ルール

  • 計算状態には $derived を、副作用には $effect を優先して使用してください。
  • リアクティブなループを避ける必要がある場合は、$effect 内で untrack() を使用してください。
  • ルートのクエリパラメーターのバインディングには、場当たり的な URL 解析ではなく、$shared/query-params の createQueryParameters を優先して使用してください。
  • 新しいコードでは onclick や oninput などの Svelte 5 のイベント属性を使用し、従来の on:click 構文は使用しないでください。
  • 新しいコンポーネントでは、スロットの代わりにスニペット({#snippet children(...)} / {@render children?.()})を使用してください。
  • 条件付きクラスには配列形式の class またはローカルの cn() ヘルパーを使用してください。

一貫性ルール

新しいものを作成する前に、Svelte アプリ内で既存のパターンを検索してください。

  1. 作成するものに最も近い Svelte の実装を見つけます。
  2. ファイル構成、命名、インポート、コンポーネントの構成をそれに合わせます。
  3. $shared/ および $comp/ の共有ユーティリティとコンポーネントを再利用します。
  4. 既存のユーティリティで必要なことをほぼ実現できる場合は、並行するものを作成せず、そのユーティリティを拡張してください。

従来の Angular アプリのアーキテクチャを Svelte にコピーしないでください。

TypeScript ルール

  • ファイルとディレクトリには kebab-case を使用してください。
  • 制御フロー文では必ず波括弧を使用してください。
  • 関数本体に文がある場合は、ブロック形式のアロー関数を使用してください。
  • 識別子を略さないでください。org ではなく organization、filt ではなく filter を使用してください。
  • 名前付きインポートを優先してください。Dialog、DropdownMenu、Field、Card などの shadcn 複合コンポーネントには、名前空間インポートを使用してもかまいません。
  • any は避けてください。生成された型、明示的なインターフェース、unknown、または型ガードを使用してください。
  • Promise は必ず await するか、意図的に fire-and-forget として処理してください。

UI コンポーネント

  • ボタン、入力欄、メニュー、ダイアログ、カード、バッジ、区切り線、空の状態、スケルトン、フォームフィールドには、$comp/ui/* の既存の shadcn-svelte コンポーネントを優先して使用してください。
  • ドキュメントの構造には、ネイティブのセマンティック要素(main、section、nav、form、table、アプリコンポーネントが不要な場合の button)も適切です。セマンティクスを汎用のスタイル付き div に置き換えないでください。
  • shadcn の詳細なコンポジションルールについては、shadcn-svelte スキルを使用してください。
  • Exceptionless の運用プロダクト UI に合わせてください。情報密度が高く、控えめで、ざっと見て把握しやすく、近くの画面と一貫性のあるデザインにします。アプリ内で、マーケティング風のヒーローレイアウトや装飾的なビジュアル表現を試すのは避けてください。

アクセシビリティ

  • セマンティックなランドマークと、明確な見出し階層を1つ使用してください。
  • すべてのフォームコントロールに、対応するラベルまたはアクセシブルな名前を設定してください。
  • アイコンのみのボタンには aria-label を設定し、装飾目的のアイコンには aria-hidden="true" を設定してください。
  • ダイアログには、視覚的に非表示の場合もタイトルが必要です。
  • エラー状態では aria-invalid を設定し、aria-describedby でヘルプテキストやエラーテキストに関連付けてください。
  • キーボードナビゲーションと、視認できるフォーカス状態を維持してください。

フロントエンドテスト

  • ユニットテスト/コンポーネントテストには Vitest と Testing Library を使用し、.test.ts または .spec.ts として対象のコードと同じ場所に配置してください。
  • アクセシブルなクエリを優先してください。まず getByRole、次に getByLabelText、その後に表示テキストを使います。セマンティクスだけでは不十分な場合に限り、テスト ID を使用してください。
  • E2E テストには Playwright を使用し、ローカルのアプリ URL のみを対象にしてください。CSS セレクターより、ロール/ラベルセレクターを優先してください。
  • 変更した動作に絞ったテストを追加し、タスクに関係のない範囲までテスト対象を広げないでください。
  • イテレーション中は、関連する最小限のテストまたは対象を絞った検証を実行してください。小さな編集のたびに、広範な Svelte 検証を実行しないでください。未プッシュのフロントエンド変更がある場合のプッシュ前/PR 前の検証、またはユーザーから明示的に求められた場合にのみ npm run validate を実行してください。このコマンドはファイルをフォーマットするため、実行後に git status を確認し、フォーマットによる変更があれば同じコミットに含めてください。

ナビゲーションの優先事項

onclick/goto よりも href によるナビゲーションを優先してください。onclick は、非同期処理(例:保存してから移動する処理)が必要な場合にのみ使用してください。

複合コンポーネントのパターン

新しいコンポーネントを作成する前に、近くにある機能コンポーネントを確認してください。共有する選択肢のセットには options.ts を使用し、ダイアログ/メニュー/カード/フィールドには shadcn の複合コンポーネントインポートを使用し、フォームには tanstack-form スキルを使用してください。

コメント