見出し画像

ChatGPTにアプリの作り方を聞いてみた

アプリが作りたい!
でも、プログラム書くのってめんどくさいよね。
なので、ChatGPTに書いてもらいました。

開発環境

開発環境ですが、既にnodebrewでnodejsがインストールされている状態です。

$ node -v
v18.15.0
$ npm -v
9.5.0

こんな感じです。
早速ChatGPT君にアプリの作り方を聞いてみましょう。

ChatGTPに聞いてみた1
ChatGTPに聞いてみた2

早速コマンドを打ってみましょう。

$ npm install -g @vue/cli
npm WARN deprecated subscriptions-transport-ws@0.11.0: The `subscriptions-transport-ws` package is no longer maintained. We recommend you use `graphql-ws` instead. For help migrating Apollo software to `graphql-ws`, see https://www.apollographql.com/docs/apollo-server/data/subscriptions/#switching-from-subscriptions-transport-ws    For general help using `graphql-ws`, see https://github.com/enisdenjo/graphql-ws/blob/master/README.md
npm WARN deprecated apollo-reporting-protobuf@3.4.0: The `apollo-reporting-protobuf` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/usage-reporting-protobuf` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.
npm WARN deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
npm WARN deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
npm WARN deprecated apollo-server-plugin-base@3.7.2: The `apollo-server-plugin-base` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.
npm WARN deprecated apollo-datasource@3.3.2: The `apollo-datasource` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.
npm WARN deprecated apollo-server-errors@3.3.1: The `apollo-server-errors` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.
npm WARN deprecated apollo-server-types@3.8.0: The `apollo-server-types` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.
npm WARN deprecated apollo-server-express@3.12.0: The `apollo-server-express` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.
npm WARN deprecated apollo-server-env@4.2.1: The `apollo-server-env` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/utils.fetcher` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated apollo-server-core@3.12.0: The `apollo-server-core` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details.

added 278 packages, removed 528 packages, and changed 577 packages in 48s

64 packages are looking for funding
  run `npm fund` for details
npm notice 
npm notice New minor version of npm available! 9.5.0 -> 9.6.2
npm notice Changelog: https://github.com/npm/cli/releases/tag/v9.6.2
npm notice Run npm install -g npm@9.6.2 to update!
npm notice 

$ vue create my-app


Vue CLI v5.0.8
? Please pick a preset: Default ([Vue 3] babel, eslint)


Vue CLI v5.0.8
✨  Creating project in /Users/xxxxxxx/Documents/webapp/my-app.
🗃  Initializing git repository...
⚙️  Installing CLI plugins. This might take a while...


added 858 packages in 1m
🚀  Invoking generators...
📦  Installing additional dependencies...


added 102 packages in 7s
⚓  Running completion hooks...

📄  Generating README.md...

🎉  Successfully created project my-app.
👉  Get started with the following commands:

 $ cd my-app
 $ npm run serve

$ cd my-app/
$ npm install -D vite
$npm run dev

ほう、では早速npm run devしてみようじゃないか。

$ npm run dev
npm ERR! Missing script: "dev"
npm ERR! 
npm ERR! To see a list of scripts, run:
npm ERR!   npm run

npm ERR! A complete log of this run can be found in:

ですよね。
package.jsonのscriptsに"dev"がないので追加してあげます。

  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "dev": "vite" ← これを追加
  },

サイドnpm run devしたところ、サーバーが起動しました。
動いているか確認してみましょう。
ちなみに、ChatGPT君はhttp://localhost:3000を開くとアプリを確認できますって答えてくれているけど、Viteのデフォルトのポートは3000じゃないのでhttp://localhost:5173/を開きます。

しかし、ここでハプニング発生。
http://localhost:5173を開いてみても404でアプリが見つかりません。
ちょっとー、ChatGPT君、困るよー。
アプリ開けないじゃん。
念の為、localhost:3000を開いてみたりポート変えてみたりしたけどダメでした。
これ以上原因調査しているとアプリ作るの面倒なのでChatGPT君に書いてもらおうという最初の目的が果たせなそうなので原因調査は一旦やめて、最初から作り直します。

気を取り直してアプリを作り直し

そういえば先ほど、VueCliをインストールした時にnpmのバージョン低くないって指摘されてたのでバージョンをあげてみます。
nodejsのページで18.15.0が安定版だよって書いてあったのでそれにしたのですが、思い切って最新版にしますか。

$ node -v
v19.8.1
$ npm -v
9.5.1

いや、これ以上はちょっと難しい。
指摘されているバージョンは9.6.2ですが、これってこの記事を書いている時点の3日前にリリースされたばかりのバージョンでnodebrewであげれるのはこれが限界みたいです。(私がやり方知らないだけかもしれませんが)
なのでこのバージョンで行きます。

$ npm create vite@latest my-vue-app -- --template vue-ts

Done. Now run:

  cd my-vue-app
  npm install
  npm run dev

コマンド。
表示された指示通りにコマンドを打つとローカルホストでサーバーが立ち上がりました🎉
下準備は整いましたさっそくアプリを作っていきましょう。
アプリの内容は以前、Reactでアプリを作ろうとして断念したランチ営業している飲食店を検索するアプリを作ろうと思います。

さっそく、どんな画面が必要かChatGPT君に聞いてみました。

ChatGTPに聞いてみた3
ChatGTPに聞いてみた4

なるほど。
では早速新規登録画面を作ってもらいましょうか。

ChatGTPに聞いてみた5
ChatGTPに聞いてみた5
ChatGTPに聞いてみた6
ChatGTPに聞いてみた7

なるほど。
これは私の聞き方が悪かったですね。
コンポーネントとかテンプレートを作ってくださいとお願いするのが正しかったですね。
あと、私の好みはCpmpositionAPIなので再度お願いしてみます。

ChatGTPに聞いてみた8
ChatGTPに聞いてみた9
ChatGTPに聞いてみた10

いい感じですね!
早速コピーしてフォームのコンポーネントを作ってみましょう。


   <script lang="ts">
  import { defineComponent, reactive } from 'vue';
  
  interface RegisterFormData {
    username: string;
    email: string;
    password: string;
    confirmPassword: string;
  }
  
  export default defineComponent({
    name: 'RegisterForm',
    setup() {
      const formData = reactive<RegisterFormData>({
        username: '',
        email: '',
        password: '',
        confirmPassword: ''
      });
  
      function register() {
        // ここに登録処理を実装する
      }
  
      return {
        formData,
        register
      };
    }
  });
  </script>
  <template>
    <v-form>
      <v-text-field label="ユーザー名" v-model="formData.username" />
      <v-text-field label="メールアドレス" v-model="formData.email" />
      <v-text-field label="パスワード" v-model="formData.password" type="password" />
      <v-text-field label="確認用パスワード" v-model="formData.confirmPassword" type="password" />
      <v-btn color="primary" @click="register">登録</v-btn>
    </v-form>
  </template>
  

少々手直ししましたが、9割型そのままでよさそうな気がします。
一旦、これでよしとしてデザインは後で考えるとします。
では、次。

ChatGTPに聞いてみた11
ChatGTPに聞いてみた12
ChatGTPに聞いてみた13
<script lang="ts">
import { defineComponent, reactive } from 'vue';

interface LoginFormData {
email: string;
password: string;
}

export default defineComponent({
name: 'LoginForm',
setup() {
    const formData = reactive<LoginFormData>({
    email: '',
    password: ''
    });

    function login() {
    // ここにログイン処理を実装する
    }

    return {
    formData,
    login
    };
}
});
</script>
<template>
<v-form>
    <v-text-field label="メールアドレス" v-model="formData.email" />
    <v-text-field label="パスワード" v-model="formData.password" type="password" />
    <v-btn color="primary" @click="login">ログイン</v-btn>
</v-form>
</template>

同じ様にちょっと手直し。
さくさくっとコンポーネントを作っていきますか。

ChatGTPに聞いてみた14
ChatGTPに聞いてみた15
ChatGTPに聞いてみた16
<script lang="ts">
import { defineComponent, reactive } from 'vue';

interface SearchFormData {
    keyword: string;
    area: string;
}

export default defineComponent({
name: 'SearchForm',
setup() {
    const formData = reactive<SearchFormData>({
    keyword: '',
    area: ''
    });

    const areas = ['渋谷', '新宿', '池袋', '品川', '恵比寿'];

    function search() {
    // ここに検索処理を実装する
    }

    return {
    formData,
    areas,
    search
    };
}
});
</script>
<template>
<v-form>
    <v-text-field label="キーワード" v-model="formData.keyword" />
    <v-select label="エリア" v-model="formData.area" :items="areas" />
    <v-btn color="primary" @click="search">検索</v-btn>
</v-form>
</template>
  

さくさく。

ChatGTPに聞いてみた17
ChatGTPに聞いてみた18

こんなことまで教えてくれるんですね。
親切。
ルーターは入れてないのでこれも追々追加していきます。
ルーターがないのでエラーになっちゃいますので、固定値を表示してもらうようにお願いしてみました。

<template>
  <v-card>
    <v-card-title>検索結果</v-card-title>
    <v-list>
      <v-list-item v-for="result in results" :key="result.id">
        <v-list-item-title v-text="result.name" />
        <v-list-item-subtitle v-text="result.address" />
      </v-list-item>
    </v-list>
  </v-card>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'SearchResult',
  setup() {
    const results = [
      { id: 1, name: 'レストランA', address: '東京都渋谷区' },
      { id: 2, name: 'レストランB', address: '東京都新宿区' },
      { id: 3, name: 'レストランC', address: '東京都中央区' },
      { id: 4, name: 'レストランD', address: '東京都千代田区' },
      { id: 5, name: 'レストランE', address: '東京都港区' }
    ];

    return {
      results
    };
  }
});
</script>

ふむ。するとこんなエラーがでます。

ChatGTPに聞いてみた19

これについて問い詰めてみる。

ChatGTPに聞いてみた20

ふむ。
じゃあ使わないでくれるかな。

ChatGTPに聞いてみた21
ChatGTPに聞いてみた22

さっきはなかったdescriptionなんかのパラメータを追加してきやがった。
とりあえずコメントアウト。
こんな状態で落ち着きました。

<script lang="ts">
import { defineComponent, computed } from 'vue';
//   import { useRoute } from 'vue-router';
//   import { getSearchResults } from '@/api';

export default defineComponent({
name: 'SearchResult',
setup() {
//   const route = useRoute();

    // const results = computed(() => {
    // return getSearchResults(route.query.keyword, route.query.area);
    // });
    const results = [
        { id: 1, name: 'レストランA', address: '東京都渋谷区' },
        { id: 2, name: 'レストランB', address: '東京都新宿区' },
        { id: 3, name: 'レストランC', address: '東京都中央区' },
        { id: 4, name: 'レストランD', address: '東京都千代田区' },
        { id: 5, name: 'レストランE', address: '東京都港区' }
    ];
    return {
    results
    };
}
});
</script>
<template>
<v-card>
    <v-card-title>検索結果</v-card-title>
    <ul>
      <li v-for="(result, index) in results" :key="index">
        <h3>{{ result.name }}</h3>
        <!-- <p>{{ result.description }}</p> -->
        <p>{{ result.address }}</p>
        <!-- <p>{{ result.phone }}</p> -->
        <!-- <p>{{ result.business_hours }}</p> -->
      </li>
    </ul>
</v-card>
</template>


ChatGTPに聞いてみた23
ChatGTPに聞いてみた24

なるほど、どっかにレストランオブジェクトを持っとけってことなんですね。
ここまで作っておいてなんですが、コンポーネント作るより先にmodelを作っておけばよかったかなって思い始めました。
まぁ、提案されたコンポーネントはあと1つなのでさくっと作ってもらいましょう。

import { defineComponent } from 'vue';

export default defineComponent({
name: 'Favorites',
props: {
    favorites: {
    type: Array,
    required: true
    }
},
methods: {
    removeFavorite(favorite) {
    this.$emit('remove', favorite);
    }
}
});
</script>
<template>
<div>
    <h2>Favorites</h2>
    <ul>
    <li v-for="(favorite, index) in favorites" :key="index">
        <h3>{{ favorite.name }}</h3>
        <p>{{ favorite.description }}</p>
        <p>{{ favorite.address }}</p>
        <p>{{ favorite.phone }}</p>
        <p>{{ favorite.business_hours }}</p>
        <button @click="removeFavorite(favorite)">Remove</button>
    </li>
    </ul>
    <p v-if="favorites.length === 0">You have no favorites yet.</p>
</div>
</template>

<script>
  

ほいっと。
さくさくっと作成してくれましたね。

長くなっちゃったので一旦ここで区切りたいと思います。
また、そのうち続きをやれたらいいなと思います。

この記事が気に入ったらサポートをしてみませんか?