とんかつ時々あんどーなつ

〜たとえ低空でも飛行していられるように〜

Hello Angular x Claude Code

はじめに

流行りの Claude Code を使って Angular アプリケーションを作ってみる。 アプリケーションを作るところがメインなので、Claude Code の準備などは割愛する。

事前準備

Angular CLI があり、ゼロから Claude Code に頼ることもないので最低限の準備をする。

アプリケーションの作成

Angular CLI を使って新規作成する。Angular ESLint や Prettier もインストールした。

CLAUDE.md の用意

Claude Code は CLAUDE.md を用意しておくと起動時に読み込んでくれる。そのため毎回意識してほしい知識はここに書いておく。 Angular を使った開発をするうえでよく使うルールは公式のドキュメントにも用意されている。

LLM prompts and AI IDE setup • Angular

今回はこれを日本語に直して、プロジェクトのルートに配置した。

# CLAUDE.md

このファイルは、Claude Code (claude.ai/code) がこのリポジトリでコードを扱う際のガイダンスを提供します。

あなたはTypeScript、Angular、スケーラブルなWebアプリケーション開発の専門家です。AngularとTypeScriptのベストプラクティスに従って、保守性、パフォーマンス、アクセシビリティに優れたコードを書きます。

## TypeScript ベストプラクティス

- 厳格な型チェックを使用する
- 型が明確な場合は型推論を優先する
- `any` 型を避ける;型が不確実な場合は `unknown` を使用する

## Angular ベストプラクティス

- NgModulesではなく常にスタンドアロンコンポーネントを使用する
- 明示的な `standalone: true` を使用しない(デフォルトで暗黙的に設定される)
- 状態管理にはシグナルを使用する
- フィーチャールートには遅延読み込みを実装する
- すべての静的画像には `NgOptimizedImage` を使用する

## コンポーネント

- コンポーネントは小さく、単一の責務に集中させる
- デコレータの代わりに `input()``output()` 関数を使用する
- 派生状態には `computed()` を使用する
- `@Component` デコレータで `changeDetection: ChangeDetectionStrategy.OnPush` を設定する
- 小さなコンポーネントにはインラインテンプレートを優先する
- テンプレート駆動フォームではなくリアクティブフォームを優先する
- `ngClass` を使用せず、`class` バインディングを使用する
- `ngStyle` を使用せず、`style` バインディングを使用する

## 状態管理

- ローカルコンポーネント状態にはシグナルを使用する
- 派生状態には `computed()` を使用する
- 状態の変換は純粋で予測可能に保つ

## テンプレート

- テンプレートはシンプルに保ち、複雑なロジックを避ける
- `*ngIf``*ngFor``*ngSwitch` の代わりにネイティブ制御フロー(`@if``@for``@switch`)を使用する
- Observableを扱うためにasyncパイプを使用する

## サービス

- サービスは単一の責務を中心に設計する
- シングルトンサービスには `providedIn: 'root'` オプションを使用する
- コンストラクタインジェクションの代わりに `inject()` 関数を使用する

実装開始

最初の指示

まずはユーザー一覧を表示するアプリケーションを作ってもらうことにした。 今回必要になる API{JSON} Placeholder を使っている。

最初に与えたプロンプトは次のものである。

> ユーザー一覧画面を作ってください。
  ユーザー一覧を取得する API は https://jsonplaceholder.typicode.com/users を使ってください。
  アプリケーションアーキテクチャはレイヤードアーキテクチャを意識してください。全部終わったら以下を実行して pass 
  することを確認してください。
   - npm run build
   - npm run test
   - npm run lint
   - npm run format

Claude Code は自ら TODO リストを作りそれを順番に実行するようになっている。Claude Code が作ってきた TODO リストが以下。

⏺ ユーザー一覧画面を作成します。レイヤードアーキテクチャに従って実装し、最後にテストとビルドを実行します。

⏺ Update Todos
  ⎿ ☐ プロジェクト構造を確認し、既存のファイルを調査する
     ☐ ユーザーモデル(型定義)を作成する
     ☐ ユーザーAPIサービス(データアクセス層)を作成する
     ☐ ユーザー一覧コンポーネントを作成する
     ☐ ルーティング設定を更新する
     ☐ npm run build を実行してビルドを確認する
     ☐ npm run test を実行してテストを確認する
     ☐ npm run lint を実行してlintを確認する
     ☐ npm run format を実行してフォーマットを確認する

ファイルを作成したり、更新する前に許可を求めてくるので内容を確認して適宜 Yes を選択していった。 最初の段階では lint の通らないコードを生成していたが、TODO リストに lint の確認を入れていたため、Claude Code が自ら実行し、lint が通るようにコードを修正していた。

なかなかよさそうである。すべての TODO が完了したところで、改めて serve してアプリケーションを動かしてみる。

最初のテンプレートが残ってはいたもののユーザー一覧は表示されている。

コードレビュー

ここまで自動で作ることに驚きながらもいくつか気になる点が出た。

ひとつ目は指示が悪かったかもしれないが、レイヤードアーキテクチャを意識させたために src/app/ 配下に components, models, services のディレクトリが作られた。が、これは最新のスタイルガイドに反する構成になってしまった。

Style Guide • Angular

ふたつ目は作成された component や service にテストファイルが用意されていない。これは CLAUDE.md に追記したほうがよさそうである。

CLAUDE.md の更新

TypeScript ファイルを作成したときに spec ファイルを作成するように更新する。また build や test の実行を毎回指示するのは大変なので、こちらも合わせて追加する。

diff --git a/CLAUDE.md b/CLAUDE.md
index 15d997c..6a18504 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -46,3 +46,16 @@
 - サービスは単一の責務を中心に設計する
 - シングルトンサービスには `providedIn: 'root'` オプションを使用する
 - コンストラクタインジェクションの代わりに `inject()` 関数を使用する
+
+## テストファイルの用意
+
+- TypeScript ファイル (\*.ts) を作成したときは、それと対になるテストファイル (\*.spec.ts) も作成する
+
+## コマンド
+
+コードの作成や更新、削除をおこなったときには次のコマンドを実行してすべてパスすることを確認する
+
+- npm run build
+- npm run test
+- npm run lint
+- npm run format

次の指示

次にユーザー詳細画面を作成する。与えたプロンプトは次の通りである。

> 次はユーザーの詳細画面を作ってください。
新しいルーティングを追加し、指定した id のユーザー情報が確認できます。このページへはユーザー一覧から任意のユーザーをクリックすることで遷移します。
全体をフォームにして、情報の更新もできるようにしてください。
ここではインラインテンプレートは使わないでください。

生成された TODO リストは以下の通り。

⏺ ユーザー詳細画面を作成します。フォーム機能付きで、ユーザー一覧からの遷移とルーティングを実装します。

⏺ Update Todos
  ⎿ ☐ ユーザー詳細コンポーネントのファイル構造を作成する    
     ☐ ユーザーサービスにgetUserById メソッドを追加する
     ☐ ユーザー詳細コンポーネントのHTMLテンプレートを作成する
     ☐ ユーザー詳細コンポーネントのCSSスタイルを作成する
     ☐ ユーザー詳細コンポーネントのTypeScriptを作成する
     ☐ ユーザー詳細画面のルーティングを追加する
     ☐ ユーザー一覧画面にリンクを追加する
     ☐ ユーザー詳細コンポーネントのテストファイルを作成する
     ☐ npm run build を実行してビルドを確認する
     ☐ npm run test を実行してテストを確認する
     ☐ npm run lint を実行してlintを確認する
     ☐ npm run format を実行してフォーマットを確認する

今度は TypeScript ファイルだけでなく、HTML や CSS を追加するようになっている。また CLAUDE.md を更新したことで、新規コンポーネントに対するテストファイルの追加や build / test の実行もプロンプトでは与えていないにも関わらず実行するようになっている。

コードレビュー

まず気になったのはデザインである。最初のユーザー一覧画面とあっていないデザインで作られた。指示としても与えていないので仕方ないのかもしれないが、なんと伝えればよかったのかもあまりわかっていない。

ユーザー一覧 ユーザー詳細

また、一覧から詳細にリンクするようになったが、a タグで作成されず div にそのまま routerLink をつけている。申し訳程度に cursor: pointer のスタイルを指定しているのがまたなんとも言えない…

詳細から一覧に戻るボタンもあるが、ここでは navigateByUrl ではなく location.back が使われている。 こういったところも少し期待値とズレている。

おわりに

Angular CLI で init だけされたアプリケーションを Claude Code でどこまで作れるのかを見てみた。 コードの生成は確かに早いが、設計思想などを伝えるのがなかなか難しいと感じた。

一方で CLAUDE.md はなかなか便利で書いたことは忠実に守られている印象を受けた。 また、Angular が用意しているルールもあるので CLAUDE.md に何を書いたらいいかわからない人もまずはここから始められるので敷居は低いように感じた。

今回は Hello world という感じなので、使っていく中でノウハウを溜めていきたい。