Amazon CodeWhispererでWebフロントエンドの開発を助けてもらう

:::note info
これは [ZOZO Advent Calendar 2022](https://qiita.com/advent-calendar/2022/zozo) カレンダー Vol.2 の 10 日目の記事です。昨日の投稿は @curry_on_a_rice さんの「[pre-commit と GitHub Actions で実行する flake8 と black の設定を共有する方法](https://qiita.com/curry_on_a_rice/items/9c7a96324d76761d98c6)」でした。
:::


# 背景
今年は[Stable Diffusion](https://stability.ai/blog/stable-diffusion-v2-release)や[ChatGPT](https://chat.openai.com/chat)といったさまざまなAIが注目を集めています。
ChatGPTに関してはシンプルな会話だけではなく、コードも書いてくれるということでTwitterでも話題になっていますね。

AIによるコード生成は[GitHub Copilot](https://github.com/features/copilot)など今までも存在していましたが、ついにAWSの[Amazon CodeWhisperer](https://aws.amazon.com/jp/codewhisperer/faqs/)がFree Previewとなりました。今回はフロントエンド周りのコードを色々と生成してみようと思います。

# Amazon CodeWhispererとは
AIによるコード補完システムで、以下の特徴を持ちます。
- コメントや関数名から続きのコードをサジェストしてくれる
- VSCodeなど主要なIDEに拡張機能として対応
- サジェストがライセンスに触れていそうな場合は警告を出してくれる

一般的なコード補完システムだと言えますが、ライセンスの警告周りは最近のAIの風当たりを感じますね

# 使い方
[公式ドキュメント](https://aws.amazon.com/jp/codewhisperer/)や[クラスメソッドさん](https://dev.classmethod.jp/articles/amazon-codewhisperer/)の記事が分かりやすくまとまっていますし、そちらを参照ください。
1つポイントとしてはサジェストが欲しいタイミングで走らなかったりするので、手動で走らせるコマンドを知っておくと便利です。（Mac + VSCodeの場合はOption + C）


# コード生成結果
TypeScriptに対応ということで、TypeScriptかつブラウザやSSGとして実行されるコードを試しました。

## 新規ファイルで関数生成
まずは関数名から内容を作ってもらいます。色がついている部分は筆者が入力、灰色の部分はCodeWhispererによる入力です。

<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/cb9e663d-8643-93c3-3904-a9fc559a465b.png">

これは流石に余裕ですね。ちゃんと型も指定しているのはありがたいです。ちなみに採用した後は、勝手に他のソートもサジェストしてくれました。

![スクリーンショット 2022-12-09 12.58.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/aaaf2c1c-21ec-4ad2-62b4-cfa09980b53d.png)

次にちょっと複雑なファイルアップロードです。例によって関数名だけ指定します。

<img width="320px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/af390e3b-d547-6648-1f51-8362271ceca0.png">

引数だけだと判断できないので、続きを入力してもらうと

![スクリーンショット 2022-12-09 13.09.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/89cd01fb-c923-024b-4eda-45afd76f3a00.png)

`require`や`promise`は気になりますが、どうやら動きそうなコードが返ってきました。また、学習に使ったであろうコードのライセンスも提示しています。

CodeWhispererは続きを補完してくれるシステムです。つまり関数名から始めると事前にimportなどが行われないのでは？と思い、コメントから始めてみました。

<img width="240px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/0f246b55-faaf-860b-5772-06792316c0bd.png">

上記のコメントのみを書くとサジェストが1行ずつ現れました。全てスクショすると大変なのでまとめて貼るとこのようなコードが生成されました。

![スクリーンショット 2022-12-09 13.19.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/a26d4c81-1606-f15b-779b-8d4684d4b712.png)

![スクリーンショット 2022-12-09 13.17.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/b9f88344-83f5-b0de-682e-66a7d1ff2490.png)

引数が途切れているのはご容赦ください。想定通り事前にしっかりimportしてからコメント付きで関数を定義してくれています。どうやらNodeサーバーだと認識したようですが、ログも考慮してくれています。

S3だけだと得意分野な気がするので、限定せずに画像をアップロードしてもらいます。

<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/ceff20cc-d1fe-def2-29bc-39a58ee1c508.png">

![スクリーンショット 2022-12-09 13.26.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/9afbafd3-cab8-0f7f-fbfb-75a977a9df3c.png)

隠しましたが、がっつりIDなどを含む結果が返ってきました。細かい指定がない場合でも動きそうな結果が返ってきます。


## 既存ファイルで関数生成
Amazon CodeWhispererは具体的な関数名やコメントがあると精度が上がるようです。なので、すでにプロダクションで動いているコードに追記するとどうなるかを試しました。

microCMSと接続しているコードのファイルで、新しい記事を取得する関数を生成します。


![スクリーンショット 2022-12-09 13.35.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/68f99010-e4ea-b8ca-b5cd-c67afdbdfa69.png)

![スクリーンショット 2022-12-09 13.36.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/50aae657-db2b-427d-e8a0-4c9726814f78.png)

なんとすでに作成してある`News`という型や、`getEndpoint`を含む関数の書き方が綺麗に引き継がれています。きっと私が新しく関数を追加したとしてもこの形になったでしょう。

`limit`を指定したくなったので、引数を追加しても大丈夫でした。

![スクリーンショット 2022-12-09 13.37.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/9d4e3737-e7c0-3235-30b7-342bc49fadf1.png)

しっかりmicroCMSの仕様に従い、最新の記事を持ってきているのも素晴らしいです。しかし、最新記事での並び替えは他のコードですでに行っていたので、古い順に取得してもらいます。

![スクリーンショット 2022-12-09 13.38.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/7647b00d-2f73-36f9-04e7-646fec13e905.png)

しっかり対応してきました。びっくりですね。悔しいので、既存のコードからでは推測できないであろうフィルターを使った検索も実装してもらいます。

![スクリーンショット 2022-12-09 13.42.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/a9085529-4add-fd0d-d059-428f92a822c7.png)

フィルターという言葉が直接出てこないであろう`search`から始まる関数名なのに、しっかりmicroCMSの仕様に従って実装してきて脱帽です。と思っていたのですが若干間違っていまして、本当は`title[contains]$(query)` が正しく`match`という指定は存在しません。ただ、ほぼ合っていますし`title`で検索することも指定していなかったので、よくできていると思います。

既存のコードに新しい機能を追加するときは非常に強い力を発揮しそうです。


## コンポーネントの追加
フロントエンドと言いながらシンプルな関数やAPIリクエストばかりだったので、今度はReactを書いてもらいます。

まずはシンプルなところでボタンを作ってもらいます。


<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/7571fd67-2c9f-05fe-9af5-2cd503468de8.png">

まさかのSVGが返ってきました。これは本当にCloseっぽいSVGなんだろうかと表示してみたら、しっかりCloseでした。

<img width="120px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/714fe3a2-ea04-d29e-801a-2faafea68e74.png">

ちなみにFavoriteやLikeなども指定しましたが、それはサジェストが出てきませんでした。Closeは共通のイメージがあるせいかもしれません。

ただこれはSVGであり期待していたHTMLとは違うので、今度はログインフォームを作ってもらいます。


<img width="240px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/42ad17b8-59cb-3ef9-05e3-fdf1f75e4947.png">

これはきっと、雑に指定した私が悪いのでしょう。「続きを補完する」と「他のコードを参照する」という仕組みから、`import`を事前に書いてみました。

![スクリーンショット 2022-12-09 14.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/08854751-97b1-4bba-1737-6fdd9ad63a2a.png)

しっかり`react-hook-form`かつ`useFormContext`を使える形にしています。しかし、未知のコンポーネントを出してきたのでそれも責任を持って実装してもらいます。

<img width="440px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102044/e43c87ca-6f69-8228-1f8d-6764bc613af7.png">

最低限のコードではありますが、`useFormContext`を利用したコードをしっかり書いています。`register`を使っていないところはマイナスですが、ログインっぽい見た目にはなっていそうです。


# まとめ
思ったよりも実用的なコードを出力してくれるなと感じました。特に既存のコードへの機能追加は出力してもらった結果を手直しすれば、実際に運用に使えるコードになりそうです。この機能によりエンジニアのコーディング時間が劇的に減ることはなさそうですが、IDEのサジェストぐらいの効果は得られると思います。

# 最後に

[ZOZO NEXT](https://zozonext.com)でもエンジニアは積極的に採用中です。特にAIやVRなど新しい技術に興味がある方は気軽に応募してください。お待ちしております。

https://hrmos.co/pages/zozotech/jobs/0000182

明日は @kurosuke1117 さんによる投稿となります。お楽しみに