以前、ChatGPTでBootstrapを使ったHTMLのモックを作ってみる - QiitaをやってみてChatGPTでモックが作れることを知りました。
しかし、HTMLだと実際の開発では「作り直しが大変」「見た目がかなり違う」などが起こりやすいのでNext.jsでモックを作ろうと思います。
とはいえ、モック用に環境を作るのも面倒くさいので環境構築もChatGPTにお手伝いしてもらいました。
今回は有料版の「ChatGPT 4」でやってみました。
1. ChatGPTにdocker-compose.ymlを作ってもらう
まずは、ChatGPTに環境の要件を伝えてdocker-compose.ymlと使い方を聞きます。
以下のdocker-compose.ymlを作って
- Next.jsを使用する
- Node.jsは最新バージョンを使う
- npmとNext.jsのインストールもやる
- ホストでのポートは9300
- コンテナを作ってからプロジェクトを手動で作成する
GhatGPTの出力結果
コンテナを作成した後で手動でNext.jsプロジェクトを作成するためのdocker-compose.ymlファイルは以下のようになります。
version: '3.8'
services:
nextjs:
image: node:latest
working_dir: /app
volumes:
- ./nextjs-app:/app
ports:
- "9300:3000"
command: bash -c "sleep infinity"
この設定では、Node.jsの最新バージョンを使用してコンテナを作成し、sleep infinityコマンドを使用してコンテナを起動したままにします。これにより、コンテナ内で手動でNext.jsプロジェクトを作成することができます。
プロジェクトをセットアップするには、次のステップを実行します:
- 上記のdocker-compose.ymlファイルを作成します。
- nextjs-appディレクトリを作成します(このディレクトリは空で構いません)。
- Dockerコンテナを起動するために、次のコマンドを実行します:
docker-compose up -d
- コンテナ内でNext.jsプロジェクトを作成するために、次のコマンドを実行します:
docker-compose exec nextjs npx create-next-app .
- 開発サーバーを起動するために、次のコマンドを実行します:
docker-compose exec nextjs npm run dev
- ブラウザで
http://localhost:9300
にアクセスして、Next.jsアプリケーションが動作していることを確認します。
2. DockerコンテナとNext.jsプロジェクトを作成する
- ChatGPTの指示に従い、docker-compose.ymlとnextjs-appディレクトリを作成し、コンテナを作成
- ChatGPTの指示に従い、Next.jsプロジェクトを作成して起動
- 本当は、コンテナを作成時に一気にやりたかったのですが、プロジェクト作成は対話形式なので断念しました。
# コンテナを作成する
$ docker-compose up -d
[+] Running 9/9
# ...省略...
✔ Container downloads-nextjs-1 Started
# プロジェクトを作成する
$ docker-compose exec nextjs npx create-next-app .
Need to install the following packages:
create-next-app@14.1.4
Ok to proceed? (y) y
✔ Would you like to use TypeScript? … No / Yes
# ...省略...プロジェクト作成時の設定はお好みで
Success! Created app at /app
npm notice
npm notice New patch version of npm available! 10.5.0 -> 10.5.1
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.5.1
npm notice Run npm install -g npm@10.5.1 to update!
npm notice
# 起動する
$ docker-compose exec nextjs npm run dev
ChatGPTの指示に従い、http://localhost:9300 にアクセスすると起動していることが確認できました。
3. ChatGPTにdocker-compose.ymlを再作成してもらう
最初のdocker-compose.ymlでは、command: bash -c "sleep infinity"
でコンテナを起動したままにさせてプロジェクト作成をしました。
プロジェクト作成を完了したので、これからは「コンテナの再起動すればアプリも再起動」するように作り直します。
以下のdocker-compose.ymlを作って
- Next.jsを使用する
- Node.jsは最新バージョンを使う
- npmとNext.jsのインストールもやる
- ホストでのポートは9300
- コンテナを作成したら開発サーバを起動する
GhatGPTの出力結果
以下のdocker-compose.ymlファイルは、指定された要件に基づいて構成されています。
version: '3.8'
services:
nextjs:
image: node:latest
working_dir: /app
volumes:
- ./nextjs-app:/app
ports:
- "9300:3000"
command: bash -c "npm install && npm run dev"
この設定では、Node.jsの最新バージョンを使用してコンテナを作成し、Next.jsプロジェクトの依存関係をインストールした後、開発サーバーを起動します。ホストマシンのポート9300がコンテナのポート3000にマッピングされ、Next.jsの開発サーバーにアクセスできるようになります。
プロジェクトをセットアップするには、次のステップを実行します:
- 上記のdocker-compose.ymlファイルを作成します。
- nextjs-appディレクトリを作成し、その中にNext.jsプロジェクトのファイルを配置します(例えば、package.jsonなど)。
- Dockerコンテナをビルドして実行するために、次のコマンドを実行します:
docker-compose up --build
- ブラウザで
http://localhost:9300
にアクセスして、Next.jsアプリケーションが動作していることを確認します。
4. Dockerコンテナを再作成する
ChatGPTが教えてくれた内容で先ほど作ったdocker-compose.ymlを上書き保存します。
そして、リビルドして起動します。
# リビルドして起動する
$ docker-compose up --build nextjs
[+] Building 0.0s (0/0) docker:default
# ...省略...
downloads-nextjs-1 | ✓ Compiled in 211ms (233 modules)
http://localhost:9300 にアクセスすると起動していることが確認できました。
5. モックを表示する
5-1. ChatGPTにコードを作ってもらう
モックでまだインストールしていないなライブラリを使うことがあるので「使うライブラリはpackage.jsonに書く」を要件の1つとしてChatGPTに伝えます。
ファイルアップロード画面をNext.jsのTSXで出力して。
- 使うライブラリはpackage.jsonに書く
- UIライブラリにMantineを使用する
- Dropzoneコンポーネントは@mantine/dropzoneからインポートする
- tailwindcssを使う
- ドラックアンドドロップでアップロードできるようにする
- アップロード後に「登録」ボタンでアップロード履歴に履歴を表示する
- 「登録」ボタンは右端に表示する
- 「登録」はファイルがアップロードされていない場合は非活性にする
- アップロード履歴を下に一覧で表示する
- アップロード履歴には「ファイル名」「アップロード日時」「状態」を表示する
- 状態には「アップロード中」「成功」「失敗」がある
- アップロード履歴にはサンプルデータを表示して
- アップロード欄には選択したファイル名を表示する
- 「登録」ボタンを押下したらアップロード欄のファイル名はクリアする
- アップロード履歴はアップロード日時の降順で表示する
- 「アップロード日時」の表示フォーマットは「YYYY-mm-dd HH:MM:DD」
GhatGPTの出力結果
以下は、指定された要件に基づいたNext.jsのTSXでのファイルアップロード画面の実装例です。package.jsonに必要なライブラリを追加し、MantineとTailwind CSSを使用してUIを構築しています。
package.jsonの依存関係に以下を追加してください:
{
"dependencies": {
"@mantine/core": "^5.0.0",
"@mantine/dropzone": "^5.0.0",
"@mantine/hooks": "^5.0.0",
"date-fns": "^2.28.0",
"next": "^12.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"tailwindcss": "^3.0.0"
}
}
次に、pages/index.tsxファイルに次のコードを追加します。
// pages/index.tsx
import { useState } from 'react';
import { format } from 'date-fns';
import { Button, Text, Table, Paper } from '@mantine/core';
import { Dropzone } from '@mantine/dropzone';
import { useListState } from '@mantine/hooks';
import 'tailwindcss/tailwind.css';
interface UploadHistoryItem {
fileName: string;
uploadDate: string;
status: 'アップロード中' | '成功' | '失敗';
}
const initialHistory: UploadHistoryItem[] = [
{ fileName: 'sample1.txt', uploadDate: '2024-04-10 12:00:00', status: '成功' },
{ fileName: 'sample2.txt', uploadDate: '2024-04-09 15:30:00', status: '失敗' },
];
export default function FileUploadPage() {
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const [uploadHistory, uploadHistoryHandlers] = useListState<UploadHistoryItem>(initialHistory);
const handleDrop = (files: File[]) => {
if (files.length > 0) {
setSelectedFile(files[0]);
}
};
const handleRegister = () => {
if (selectedFile) {
const newHistoryItem: UploadHistoryItem = {
fileName: selectedFile.name,
uploadDate: format(new Date(), 'yyyy-MM-dd HH:mm:ss'),
status: 'アップロード中',
};
uploadHistoryHandlers.prepend(newHistoryItem);
setSelectedFile(null);
}
};
return (
<div className="container mx-auto p-4">
<Text className="text-4xl mb-6">ファイルアップロード</Text>
<Paper className="p-4 mb-4 border-2 border-dashed cursor-pointer" shadow="sm">
<Dropzone onDrop={handleDrop} className="flex justify-center items-center h-32">
<Text align="center">
{selectedFile ? selectedFile.name : 'ドラッグアンドドロップまたはクリックしてファイルをアップロード'}
</Text>
</Dropzone>
</Paper>
<div className="float-right mb-6">
<Button
onClick={handleRegister}
disabled={!selectedFile}
>
登録
</Button>
</div>
<div className="clear-both">
<Text className="text-2xl mb-4">アップロード履歴</Text>
<Table striped className="w-full">
<thead>
<tr>
<th>ファイル名</th>
<th>アップロード日時</th>
<th>状態</th>
</tr>
</thead>
<tbody>
{uploadHistory.map((item, index) => (
<tr key={index}>
<td>{item.fileName}</td>
<td>{item.uploadDate}</td>
<td>{item.status}</td>
</tr>
))}
</tbody>
</Table>
</div>
</div>
);
}
このコードは、指定された要件に従ってファイルアップロード画面を作成します。
Dropzoneコンポーネントを使用してファイルをドラッグアンドドロップでアップロードできるようにし、Tailwind CSSでスタイリングしています。また、ファイル選択後に「登録」ボタンをクリックすると、選択されたファイルの情報がアップロード履歴の一番上に追加され、アップロード履歴は最新のものが上に表示されるようになっています。date-fnsライブラリを使用して日付をフォーマットし、MantineのuseListStateフックを使用してアップロード履歴の状態を管理しています。
上記のコードには、サンプルデータを含む初期アップロード履歴が設定されており、ページが読み込まれるとすぐに表示されます。また、アップロード履歴はアップロード日時の降順で表示されます。
このコードを使用することで、指定された要件に基づいたファイルアップロード画面をNext.jsのTSXで出力することができます。
5-2. Dockerコンテナをリビルドして起動する
- コンテナが実行中であれば停止する
- {プロジェクトディレクトリパス}/pages/index.tsx をChatGPTが出力した内容で上書き保存する
- {プロジェクトディレクトリパス}/package.json にChatGPTが出力した内容で不足しているライブラリを追記する
- コンテナをリビルドして起動する
- http://localhost:9300 にアクセスするして画面を確認する
# 実行中の場合は「Ctrl+C」で停止する
Gracefully stopping... (press Ctrl+C again to force)
Aborting on container exit...
[+] Stopping 1/1
✔ Container downloads-nextjs-1 Stopped 0.9s
canceled
# index.tsxとpackage.jsonを更新する
# コンテナをリビルドして起動する
$ docker-compose up --build nextjs
[+] Building 0.0s (0/0)
# ...省略...
さいごに
Next.jsやReactのコードをChatGPTに作ってもらうのは、HTMLよりも難しいとわかりました。
「どんなライブラリを使用するかの指定で見た目が変わる」ことや「Layoutなしで1ファイルだけで見た目を作る」ことに苦戦しました。
ある程度のコードを作って、後は手動でコードを修正したほうが早いと思いました。
もしかしたら、HTMLを作ってChatGPTでNext.jsやReactのコードに変換するほうが効率的なのかもしれません。