mcpField
A
angular-best-practices

angular-best-practices

github.com/boise-state-development開発22758 回インストール1 日前に更新
リポジトリ

angular-best-practices について

angular-best-practices は、Angular 21 アプリを開発する人向けのスキルです。TypeScript、コンポーネント、Signals、テンプレート、ルーティング、スタイル、アクセシビリティの指針をまとめています。

主な機能

  1. 01厳密な TypeScript とコンポーネントの指針
  2. 02Signals による状態管理と非同期リソース
  3. 03ネイティブなテンプレート制御フロー
  4. 04機能ルートの遅延読み込み
  5. 05画像、スタイル、アクセシビリティの指針

活用シーン

  1. 01新しい Angular プロジェクトの規約策定
  2. 02コンポーネントと状態パターンの確認
  3. 03非同期データと遅延ルートの実装

インストール

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

$npx skills add https://github.com/boise-state-development/agentcore-public-stack --skill angular-best-practices

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

同梱ファイルangular-best-practices.skillsignal-patterns.md

詳細

Angular 21 のベストプラクティス

TypeScript

  • 厳密な型チェックを使用します
  • 型が明らかな場合は型推論を優先します
  • any は避け、型が不明な場合は unknown を使用します

コンポーネント

  • 常にスタンドアロンコンポーネントを使用します(standalone: true は設定しないでください。v20 以降ではデフォルトです)
  • changeDetection: ChangeDetectionStrategy.OnPush を設定します
  • デコレーターの代わりに input() と output() 関数を使用します
  • 派生状態には computed() を使用します
  • コンポーネントは小さく、単一の責務を持たせます
  • 小さなコンポーネントにはインラインテンプレートを優先します
  • テンプレート駆動フォームよりリアクティブフォームを使用します
  • ngClass の代わりに class バインディングを使用します
  • ngStyle の代わりに style バインディングを使用します
  • 外部テンプレート/スタイルには、コンポーネントの TS ファイルからの相対パスを使用します
  • @HostBinding/@HostListener は使用せず、代わりにデコレーター内の host オブジェクトを使用します

Signals による状態管理

  • ローカルのコンポーネント状態にはシグナルを使用します
  • 派生状態には computed() を使用します
  • 状態の変換は純粋で予測可能なものにします
  • シグナルに mutate は使用せず、代わりに update または set を使用します

複雑な派生状態のパターンについては、references/signal-patterns.md を参照してください。

リソース(非同期データ)

シグナルを使った非同期データの取得には resource() を使用します:

const userResource = resource({
  params: () => ({ id: userId() }),
  loader: ({ params, abortSignal }) => fetch(`/api/users/${params.id}`, { signal: abortSignal }),
});

const userName = computed(() => userResource.hasValue() ? userResource.value().name : undefined);

主な resource パターン:

  • params が undefined を返すとローダーは実行されず、ステータスは 'idle' になります
  • 実行中のリクエストをキャンセルするには abortSignal を使用します
  • 読み込み/エラー状態に対応するため、value() にアクセスする前に hasValue() を確認します
  • ステータスの値:'idle'、'loading'、'reloading'、'resolved'、'error'、'local'

テンプレート

  • ネイティブの制御フロー(@if、@for、@switch)を使用します(*ngIf、*ngFor、*ngSwitch は使用しません)
  • オブザーバブルには非同期パイプを使用します
  • テンプレートはシンプルに保ちます。複雑なロジックは記述しません
  • テンプレート内でアロー関数を使用しないでください(サポートされていません)
  • new Date() などのグローバルが利用可能だと想定しないでください

サービス

  • サービスごとに責務を 1 つにします
  • シングルトンには providedIn: 'root' を使用します
  • コンストラクターインジェクションの代わりに inject() 関数を使用します
@Injectable({ providedIn: 'root' })
export class UserService {
  private readonly http = inject(HttpClient);
}

ルーティング

  • フィーチャールートには遅延読み込みを実装します:
export const routes: Routes = [
  {
    path: 'admin',
    loadComponent: () => import('./admin/admin.page').then(m => m.AdminPage),
  },
];

ファイル名

  • ルーティング可能なビューコンポーネント:file-name.page.ts、file-name.page.html、file-name.page.css
  • 通常のコンポーネント:file-name.component.ts
  • サービス:file-name.service.ts

アイコン(ng-icon)

import { NgIcon, provideIcons } from '@ng-icons/core';
import { heroSparkles, heroTrash } from '@ng-icons/heroicons/outline';

@Component({
  selector: 'app-example',
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [NgIcon],
  providers: [provideIcons({ heroSparkles, heroTrash })],
  template: `<ng-icon name="heroSparkles" />`,
})
export class ExampleComponent {}

画像

  • すべての静的画像に NgOptimizedImage を使用します
  • インラインの base64 画像では NgOptimizedImage は動作しません

スタイリング

  • CSS には Tailwind 4.1 を使用します(利用可能であれば Tailwind スキルを参照してください)
  • 必要に応じて Angular CDK を利用できます

アクセシビリティ

  • すべての AXE チェックに合格する必要があります
  • WCAG AA の最低要件(フォーカス管理、色のコントラスト、ARIA 属性)を満たす必要があります

コメント