LoginSignup
1
1

More than 1 year has passed since last update.

【爆速】Vite+Vuejs+Amplify+AppSync(GraphQL)でリアルタイム掲示板作成+つまづいたところ

Last updated at Posted at 2022-02-18

Viteが凄すぎて感動した

Vite
あまりの速さに感動しました。なので何か作ってみようと思います。

掲示板アプリを爆速で作る

参考

やること

  • Vite + Vuejs + Vuetifyでシンプルなアプリを作る
  • Appsyncでバックエンドを作る
  • 結合する
  • Amplifyでデプロイする

できたもの

タイトルなし.gif

Vueのインストール

まずはyarnでViteアプリを作成

yarn create vite my-vue-app --template vue

フォルダを開いてyarn devで動くか確認

cd my-vue-app
yarn
yarn dev

localhost:3000で動いたのが見れたと思います。

AmplifyとAppsyncの準備

Amplify CLI

amplify init
? Enter a name for the project myvueapp
The following configuration will be applied:

Project information
| Name: myvueapp
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: vue
| Source Directory Path: src
| Distribution Directory Path: dist
| Build Command: npm run-script build
| Start Command: npm run-script serve

あらかじめVueのプロジェクトがあると、全て設定された状態で引き込まれました。すごい。
続いてAPIの登録

amplify add api
? Select from one of the below mentioned services: GraphQL
? Here is the GraphQL API that we will create. Select a setting to edit or continue Continue
? Choose a schema template: Blank Schema
✔ Do you want to edit the schema now? (Y/n) · yes
? Choose your default editor: Visual Studio Code

ブランクスキーマを選んで適当に追加します。

amplify/backend/api/myvueapp/schema.graphql
type Post @model {
  id: ID!
  name: String!
  content: String!
}

終わったらデプロイ

amplify push  

無事デプロイできたら、Appsyncにアプリが追加されていると思います。

image.png

試しにクエリを動かしたりして動作チェック

image.png

Vuejsに組み込む

CSSフレームワークにVuetify
日付を表示したかったのでdayjsも追加しています。

vue add vuetify
yarn add aws-amplify aws-amplify-vue
yarn add dayjs

main.jsでインポート
Appsyncをデプロイしたときに作成されるエンドポイントなどや認証情報などがsrc/aws-exports.jsにまとめて入っているので、そちらもインポートします。

src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify'
import { loadFonts } from './plugins/webfontloader'
import Amplify, * as AmplifyModules from "aws-amplify";
import { AmplifyPlugin } from "aws-amplify-vue";
import aws_exports from "./aws-exports";
Amplify.configure(aws_exports);

loadFonts()

createApp(App).use(vuetify, AmplifyPlugin, AmplifyModules).mount("#app");

実際に動く画面がわの実装。1ファイルに全部詰め込む形にしました。

src/App.vue
<template>
  <v-app>
    <v-main>
      <v-container>
        <form>
          <v-text-field
            v-model="name"
            :counter="10"
            label="Name"
            required
          ></v-text-field>
          <v-textarea solo v-model="content" name="content" label="content"></v-textarea>
          <v-btn class="mr-4" @click="submit"> submit </v-btn>
          <v-btn @click="clear"> clear </v-btn>
        </form>
        <hr class="my-3">
        <h1>Comments</h1>
        <v-list three-line>
          <template v-for="(item, index) in items"  :key="index">
            <v-list-item>
              <v-list-item-content>
                <v-list-item-title>{{item.name}} <small class="text-grey"> {{item.date}}</small></v-list-item-title>
                <div class="pl-3 mt-2" v-html="item.content"></div>
              </v-list-item-content>
            </v-list-item>
            <v-divider />
          </template>
        </v-list>
      </v-container>
    </v-main>
  </v-app>
</template>

<script>
import dayjs from 'dayjs'
import { API, graphqlOperation } from "aws-amplify";
import { createPost } from "./graphql/mutations";
import { listPosts } from "./graphql/queries";
import { onCreatePost } from "./graphql/subscriptions";
dayjs.locale("ja");

export default {
  name: "App",

  data: () => ({
    name: "",
    content: "",
    items: undefined,
  }),
  mounted() {
    this.getData();
    this.registerSubscription();
  },
  methods: {
    submit() {
      this.postData();
    },
    clear() {
      this.name = ""
      this.content = ""
    },
    getData: async function () {
      // データ取得
      await API.graphql(graphqlOperation(listPosts))
        .then((response) => {
          // 改行をタグに変換
          const items = response.data.listPosts.items.map( val => {
            val.content = val.content.replace(/\r?\n/g, '<br>')
            val.date = dayjs(val.createdAt).format('YYYY/MM/DD')
            return val
          })
          // テーブル表示
          this.items = response.data.listPosts.items.sort((a,b)=> a.createdAt < b.createdAt ? 1 : -1)
        })
        .catch((error) => {
          // テーブルリセット
          this.items = []
        })
    },
    registerSubscription: async function (){
      // サブスクリプション登録
      await API.graphql(
        graphqlOperation(onCreatePost)
      ).subscribe({
        next: (eventData) => {
          const res = eventData.value.data.onCreatePost
          const onCreatePost = {
            ...res,
            content:res.content.replace(/\r?\n/g, '<br>'),
            date: dayjs(res.createdAt).format('YYYY/MM/DD')
          }
          this.items.unshift(onCreatePost)
        }
      })
    },
    postData: async function () {
      // オプション
      const myInit = {
        name: String(this.name),
        content: String(this.content),
      };
      // データ登録
      await API.graphql(graphqlOperation(createPost, { input: myInit }))
        .then((response) => {
          console.log(response);
          this.clear();
        })
        .catch((error) => {
          console.log(error)![Something went wrong]()
;
        });
    },
  },
};
</script>

GithubからAmplifyへCDする

Githubに適当なリポジトリを作って、AWSのチュートリアルを見ながらAmplifyを設定。
ビルドコマンドやディレクトリなどは、あらかじめVuejsアプリを使ってからAmplify CLIを使うとほぼ全自動で設定されます。
うまくできたら、Githubのmasterブランチをコミットします。

image.png

完了まで行ったらデプロイアドレスから動作検証できます。
ものの1時間もかからずに出来ましたが、下記のようなつまづきポイントもありました。

つまづいたところ

Viteが邪魔してBuildが通らない

yarn devは通るのにyarn buildだとなぜかエラーが出るのでvite.config.jsを編集しました。

vite.config.js
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "src"),
      "./runtimeConfig": "./runtimeConfig.browser", // 追加
    },
  },

コンソールでエラーが出る

ブラウザのコンソールでglobal周りのエラーが出るのでindex.htmlのheaderに下記を追加しました。

index.html

    <script>
        var global = global || window;
        var Buffer = Buffer || [];
        var process = process || {
            env: { DEBUG: undefined },
            version: []
        };
    </script>

Viteの体感は0秒

編集から反映してページリロードまで本当に早くて素晴らしいです。
GraphQLのサブスクリプションならわざわざAPIをfetchしなくても、動作検証が続けられるので、相性も抜群ですね。
Appsyncもかなり簡単に使えました。Firebaseも簡単ですが、スキーマを設計してより強固なバックエンドに出来ると思います。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1