🧠

Astro+Vercel で自分のポートフォリオサイトをつくってみた〜Cursorを添えて〜

2025/03/06に公開

そういえば自分に関する情報まとめたページって持ってなかったなぁと思って、Astro触ってみるがてら作ってみました。

ポートフォリオはこちら。
https://portfolio.chiilog.com/

GitHubリポジトリはこちら。
https://github.com/chiilog/portfolio

自分の技術スタック的にほぼWordPressが占めてる(できるとは言ってない)ので、他にもできること増やしておかないとなーくらいの軽い気持ちで始めました。

Astroは初めて触るので、まずはチュートリアルを一通りやって、概要に触れました。やっぱね、初めてはチュートリアルからですよ。

https://docs.astro.build/ja/tutorial/0-introduction/

書き方とかは自分の知ってる知識と組み合わせてどんどんやっていけそうだな〜と判断したので、より実践としてポートフォリオを作ることに。最初は自分で書いていくつもりだったんですが、ふと 「そうだAIにやらせてみよう」 と思い至り、課金したばっかりのCursorエディタを使ってやってみることにしました。

Cursorの設定

Rules for AI

日本語にして必要な拡張入れたくらいでまだ赤ちゃんな状態だったので、ルールをまず整備しました。
参考(丸パクリ)にしたのはこちら。

https://note.com/nike_cha_n/n/nd0f7566019ae

https://qiita.com/masakinihirota/items/4b55471205f7dd17482e

https://note.com/nobita2041/n/nbf9390e1878a

https://qiita.com/masakinihirota/items/1694715063247574467d

そうして設定したRules for AIはこちら。

重要な注意事項:
- Always respond in 日本語。
- 特に指定がない限りカジュアルに接してください。
- 不明点がある場合は、作業開始前に必ず確認を取ってください。
- 重要な判断が必要な場合は、その都度報告し、承認を得てください。
- 予期せぬ問題が発生した場合は、即座に報告し、対応策を提案してください。
- 3回エラーの解消に失敗したら、処理自体をやめて、何を失敗したのか教えてください。
- 秘匿情報はgitにコミットしないでください。
- 明示的に指示されていない変更は行わないでください。

振る舞い:
- TypeScript、Next.js (App Router)、React、Tailwind CSS、WordPressのエキスパートとして振る舞います。

コメント:
- コードの先頭にコメントを追加してください。形式は以下の通りです。
  - JavaScript: "JSDoc"
  - PHP: "PHPDoc"
- コメント内では、スクリプトの概要、主な仕様、制限事項を記載してください。
- すべてのファイル、クラス、メソッド、プロパティに日本語のコメントが、適切なタグとデータ型を伴って記される

コーディング:
- 効率よりも可読性を重視してください。
- プログラムの詳細は省略せず、冗長になっても理解しやすさを重視してください。
- 完了後、コード全体に矛盾がないか仕様と完全に一致しているかチェックします。
- コードを提供する際は、私のprettier設定を尊重してください。

そもそもこれはAIに厳密に伝わるのか?って疑問に思ったので、ChatGPTに聞いたらもうちょっと厳密にしてくれました。

### 重要な注意事項:
- 全ての応答は日本語で行うこと(例外なく)。
- 特に指示がない場合は、カジュアルな口調で対応すること。
- 不明点がある場合は、作業開始前に必ず確認を取ること。
- 重要な判断が必要な場合は、その都度報告し、承認を得ること。
- 予期せぬ問題が発生した場合は、即座に報告し、対応策を提案すること。
- 同じエラーの解消に3回失敗した場合は、処理を中断し、どのエラーが解消できなかったのか詳細な説明を行うこと。
- 環境変数やAPIキー、認証情報などの秘匿情報はGitにコミットしないこと。安全な管理方法を提案できる場合は提案すること。
- 明示的な指示がない限り、コードや設定の変更を行わないこと。ただし、明らかに誤りがある場合は報告のうえ修正を提案すること。

### 振る舞い:
- TypeScript、Next.js(App Router)、React、Tailwind CSS、WordPressのエキスパートとして、最善の設計・実装方法を提案し、質問には的確な解答を行うこと。

### コメント:
- 全てのコードの先頭に適切なコメントを追加すること。  
  - JavaScript: JSDoc  
  - PHP: PHPDoc  
- コメント内では、スクリプトの概要、主な仕様、制限事項を記載すること。
- 全てのファイル、クラス、メソッド、プロパティに日本語のコメントを付け、適切なタグ(例: `@param`、`@return`)とデータ型を記載すること。

### コーディング:
- 効率よりも可読性を重視すること。
- プログラムの詳細は省略せず、冗長になっても可読性を優先すること。ただし、適切に抽象化できる場合は適用すること。
- 完了後、コード全体に矛盾がないか仕様と完全に一致しているかチェックすること。
- コードを提供する際は、私のPrettier設定(インデント、改行、クオートスタイルなど)を厳守すること。

特にコメントまわりについてはこの指示を入れたことで劇的に改善されました。

同じエラーの解消に3回失敗した場合は、処理を中断し、どのエラーが解消できなかったのか詳細な説明を行うこと。 というのはあとから追加しました。処理中に同じエラーでずーっとループして止まらないことがあったので、3回はあの手この手で解消に努めてもらい、ダメならやめてねって方針を。まだこのコメントを入れてからエラーループに陥ってないので、うまく動作するか今からどきどきしています。

ルール考えるのが面白すぎて作業が止まったのはご愛嬌…(こういう作業大好き)

使用している言語モデル

基本的に claude-3.7-sonnetを使っています。必要に応じて defaultに変えたりもします。私は重度のラストエリクサー症候群を患っているので、プレミアムモデル使うのは毎回どきどきしています😇

Cursorダウンロードから1週間?とかで 0.46.8 に変わり、それからはAgentモードを使用しています。実装されたコードで「なんでこの実装?」ってときはAskモードに切り替えたり、そもそも使用された関数とかを調べたい時はドキュメント開きつつ別窓でChatGPTに聞いたりしています。(これってこういう理解で合ってる?っていう壁打ち)

実際の進め方

環境設定

Astroの環境設定等は自分でやりました。(コマンド叩くだけだし)
次にやったのはLint周りの設定だったかな。この辺、いつもWordPressの設定をextendsして使っているので、自分で一から書いていくのはあんまり経験がなくて、コード書くより時間がかかりました。

読み漁ったのはこのあたり

https://eslint.org/docs/latest/use/configure/configuration-files

https://r4ai.dev/posts/migrate-eslint-to-v9/

https://qiita.com/cieloazul310/items/e88d1bbb10119788e77e

https://zenn.dev/suree/articles/71591ec903463d

prettierが変な挙動したりしてキレ散らかしながら整備しました。Lintの設定…奥が深い……。

ベースのHTMLを作る

index.astro ファイルで、

  • ヒーローイメージ
  • ブログ記事一覧
  • プロダクト紹介
  • 職務経歴(あとから追加)
  • プロフィール(あとから追加)

をそれぞれ生成してもらいました。
最初からRSSだコンポーネント化だとかはやっていません。(一気に検証したくない)

サイトのプライマリーカラー等は自分でcssファイルに設定しています。というのも、案の定というかTailwind v4の設定がわかってなくて、毎回「Tailwind v4で」って書いてもtailwind.config.jsが生成されるんですよね。Docs参照しても同じだったのでここは早々に諦めました。

共通パーツのコンポーネント化

  • セクション要素のコンポーネント化
  • ブログのarticleのコンポーネント化
  • プロダクトのarticleのコンポーネント化

などなど、繰り返し使うパーツのコンポーネント化を行いました。これ地味〜に面倒なのでAIがやってくれると助かりますね。とはいえ、生成された中には気を遣いすぎやね…ってコードも多少あったので、気をつけてレビューする必要はあるかなと思いました。

例:

  • 技術スタックのアイコンを、わざわざ配列に入れて技術名でデザインを振り分ける
    • 技術名をslotにして、習得レベル(自分比)で出し分ければいい
  • 職務経歴の背景色の違いを変数にして出す
    • 偶数が薄いグレーであればよく、変数でカラーコード指定したり、JSで出しわけたりする必要がない

ブログをzennのRSSから取得する

最近ブログはもっぱらzennでしか書いてないので、zennのRSSから取得するように処理を変更してもらいました。事前にどういう方法でRSSに変えるのがいいのか一通り調べてから実装依頼しています。

https://zenn.dev/hrkmtsmt/articles/fa7d8y9crypnib

https://zenn.dev/kazuki_tam/articles/f7d3c0f1074969

また、RSSから取得するだけだと毎回ビルドしないと更新できないので、SSRに変更するのもやってもらいました。特に毎日ブログ書くわけではないのでキャッシュ時間は相談して長め(12時間)に変更。

https://zenn.dev/thirosue/books/6fa991650c5767/viewer/06399d

こうやって対話しながら実装できるのはありがたいですね。対人だったら「後出しやんけ!!!!」ってことも気兼ねなく出せるのがいいです。(対人でやらないように気をつけようと戒める)

おまけ:Gemini Code AssistでPRのレビューをしてもらう

https://codeassist.google/

https://zenn.dev/yamazaking/articles/gemini-code-assistant-tutorial

これもやってみたかったので入れてみました。

https://github.com/chiilog/portfolio/pull/1

自分のアカウントに入れたので、個人開発ではばんばんAIにレビューしてもらうつもりです。

生成AIとどう付き合っていくか

新しい家電は説明書読んでから使うという私のマインド的に、しばらくは

  • 実装方法に検討がついていて
  • もしおかしいコードが出てきたら自分で直せる or 直し方を指示できる

コードに限って使っていこうかな…?という感じです。とはいえ、この先際限なくどんどん賢くなっていくだろう分野なので、もっと注視していこうと思います。

Discussion