Amplify リモート開発の環境構築 (Vue.js + TypeScript)

# 要約
- Visual Studio Code(VSCode) と Docker で再現性のあるクリーンな開発環境をつくる
- プロジェクトごと開発環境を保持できる
- 手軽に再構築と共有ができる
![](https://storage.googleapis.com/zenn-user-upload/19f39cf38708-20220307.jpg)

## はじめに
※2022/3に書いた記事を2022/11に更新しています。（この間もかなり激しく更新がありました。）
[JAWS-UG浜松](https://jawsug-hamamatsu.doorkeeper.jp/)で活動しています。オンライン勉強会の会もあるのでぜひご参加ください。よろしくお願いします。

Amplifyを使うことになり、一通りチュートリアルを行いました。
Next Stepとして、何か作ってみようとしたところ、鬼のようにアップデートのあるライブラリと、たくさんのAmplifyという言葉に惑わされました。
他にもmockが不安定な動きをしたり、amplify pushが失敗したりと七転八倒を繰り返し、開発環境自体を再構築をするようになりました。
Vueの開発についてもバージョンの違いにより、環境側(nodejsとvue）の設定の共有が必要です。

## 環境例

ファイル構成
```
amplify-vuejs-docker
├── .devcontainer/
│   ├── devcontainer.json
│   ├── docker-compose.yml
│   └── web/
│  	  └── Dockerfile
└── server/
```
### 1. docker-compose.yml
※今回はvuetify+viteを使うので3000番を開けました。20002はモック用です。
windows環境ではこの設定をしなくても大丈夫です。
```yml:docker-compose.yml
version: '3.8'

services:
  amplify:
    build: ./web
    ports:
      # yarn dev
      - 3000:3000
      # mock api
      - 20002:20002
    stdin_open: true
    working_dir: '/app'
    volumes:
      - ../server:/app
      # credential,configを保管したい人向け
      # - ../dev/aws/:/root/.aws/
    tty: true
```
### 2. Dockerfile
Amplify Mocking(ローカルモック)を使うためにjavaを入れます。
Amazon Correttoを使ってみます。
Nodeは安定板の最新のDockerを使うようにしています。
大事なことはバージョン指定をすることです。
```Dockerfile:Dockerfile
FROM node:18.12.1
# java for Amplify Mock
RUN apt update; apt install -y wget software-properties-common apt-transport-https
RUN wget -O- https://apt.corretto.aws/corretto.key | apt-key add - 
RUN add-apt-repository 'deb https://apt.corretto.aws stable main'
RUN apt update; apt-get install -y java-18-amazon-corretto-jdk
# git-flow
RUN apt install git-flow
# amplify
RUN yarn global add @aws-amplify/cli@10.5.1
```
### 3. devcontainer.json
VSCodeの設定を共有します。
Vueは3.xを使う場合volarを使うことになります。(misterj.vue-volar-extention-pack)
あとは共有したい環境情報などを入れておきます。
```json:devcontainer.json
{
  "name": "Amplify Vue3",
  "dockerComposeFile": "docker-compose.yml",
  "service": "amplify",
  "workspaceFolder": "/app",
  "extensions": [
    "misterj.vue-volar-extention-pack",
    "aws-amplify.aws-amplify-vscode",
    "GraphQL.vscode-graphql",
    "oderwat.indent-rainbow",
    "mhutchie.git-graph",
    "eamodio.gitlens"
  ],
  "settings": {
    "eslint.options": {
      "extensions": [".js", ".vue", ".ts"]
    },
    "eslint.validate": ["typescript", "javascript", "vue"],
    "editor.codeActionsOnSave": {
      "source.organizeImports": false,
      "source.fixAll.eslint": true,
      "source.fixAll": true
    },
    "typescript.preferences.importModuleSpecifierEnding": "minimal",
    "eslint.format.enable": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "prettier.trailingComma": "all",
    "prettier.useEditorConfig": false,
    "prettier.jsxSingleQuote": true,
    "prettier.printWidth": 100,
    "prettier.semi": true,
    "prettier.singleQuote": true,
    "prettier.tabWidth": 2
  }
}
```
## 使い方

1. Dockerをインストールします

2. VSCodeをインストールします

3. VSCodeに拡張機能Remote Developmentをインストールします

4. リポジトリをクローンします
```bash
git clone https://github.com/covasue/amplify-vuejs-docker
```

クローンした`amplify-vuejs-docker`に移動します
```bash
cd amplify-vuejs-docker
```
※ここで環境を整えます。
VSCodeを起動して Reopen in container をクリックします
```bash
code .
```

初回はコンテナの構築があるので4～5分かかりますが、2回目以降は4～5秒でコンテナ（開発環境）が立ち上がります。
VSCodeを閉じるとコンテナが自動終了します。

### Windowsの場合はWSL2から実行する

爆速で開発できるはずがリモート開発を実装するとやたら遅いのと
webpack5(vue/cli@5)でホットリロードしない現象が起きてしまいました。
調べたところFileSystemを混ぜちゃダメとのことでした。
こちらのサイトに丁寧に書かれています。
https://levelup.gitconnected.com/docker-desktop-on-wsl2-the-problem-with-mixing-file-systems-a8b5dcd79b22
yarn dev や buildが、なんならDocker使う前より早いんじゃないかと思えるようになりました。

## 上記環境でよいところ
- Amplify CLIとVue CLIとMockの必須条件のJDKをそれぞれバージョン指定した状態でインストールした状態になる。
- 構築作業を終えると、VSCodeのワークスペースを開くだけで、Docker操作を特に意識することなくコンテナに入り、ローカル環境のようにVSCodeからターミナルをたたくことができる
- git clone ,git checkout xxx, amplify init ,yarn　概ね4ステップで環境再現
- VSCodeの設定を共有できる。例えばセミコロン、クォーテーションなどの設定を保持できる

## 公式チュートリアルをTypeScriptでやってみます
### Prerequisites(Step1)
![](https://storage.googleapis.com/zenn-user-upload/4b25206f6e6b-20220311.jpg)

まずAmplify CLI のコマンド amplify configureでIAMユーザーを作成します。
途中Webコンソールにアクセスしますので、Webコンソールにアクセスできる準備をお願いします。

#### 1. amplify configureで新しいIAMユーザーを作成します。
```bash
amplify configure
```
#### 2. 対話形式で聞かれるのでガイダンス通りに入力します。
リージョンは東京リージョン(ap-northeast-1)をお勧めします。
```
Specify the AWS Region
? region:  # Your preferred region 
Specify the username of the new IAM user:
? user name:  # User name for Amplify IAM user
Complete the user creation using the AWS console
```

#### 3. ブラウザが開きユーザー作成を促されます。
最後にAccess keyとSecret Access keyを保存しておきます。


#### 4. 続きを入力します。
```
Enter the access key of the newly created user:
? accessKeyId:  # YOUR_ACCESS_KEY_ID　さきほど保存したAccess key
? secretAccessKey:  # YOUR_SECRET_ACCESS_KEY さきほど保存した Secret Access key
This would update/create the AWS Profile in your local machine
? Profile Name:  # (default) 何か名前を付けましょう。 

Successfully set up the new user.
```
これでStep1は完了です。
Access keyとSecret Access keyはStep2でも使います。

### Set up fullstack project(Step2)
![](https://storage.googleapis.com/zenn-user-upload/37c97e1c8831-20220311.jpg)

このステップではVueプロジェクトの作成、Amplify Librariesと Amplify UI Componentsのインストール,Amplify LibrariesをVueに読み込みまで行います。

@vue/cliは開発環境が前回と同じの場合、インストール済みなので飛ばします。
#### 1. Vue のプロジェクトを作成します。(※Vuetify方式)
```bash
yarn create vuetify
```
myamplifyprojectはプロジェクト名です。
```? Please pick a preset: (Use arrow keys)
yarn create v1.22.19[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...

success Installed "create-vuetify@1.0.4" with binaries:
      - create-vuetify
[#######################################] 39/39
Vuetify.js - Material Component Framework for Vue

✔ Project name: … myamplifyproject
✔ Use TypeScript? … No / Yes
✔ Would you like to install dependencies with yarn, npm, or pnpm? › yarn
```

選択後、しばらくプロジェクトの作成を待ちます。作成が終了したらディレクトリに移動します。
```bash
cd myamplifyproject
```

正しくVueのプロジェクトが作られているか確認でサーバーを起動します。
ポート3000番が開き、驚くほどのスピードでVuetifyとVueの環境が立ち上がります。
```bash
yarn dev
```

Ctrl + Cでサーバーを止めます。

#### 2. Initialize a new backend

Amplify CLIのコマンド amplify initを行います。
先ほどのconfigure はどちらかというとアカウント(IAMユーザー）の作成です。
今回のinitはプロジェクトの（初期）設定です。
プロジェクトのディレクトリに移動していることを確認してからコマンドを入力しましょう
※例　root@farwq13fa:/app/myamplifyproject#　amplify init
```bash
amplify init
```

バックエンドを作成するプロジェクト名を設定します。
リソースを作成するときの接頭語に使用されるので分かりやすい名前が望ましいです。
```
? Enter a name for the project (myamplifyproject) todo
```

上の例ではtodoと名前をつけています。
次は公式サイトと異なり下記のような表示になります。
![](https://storage.googleapis.com/zenn-user-upload/df9a2fb539f0-20220310.png)
特に変更する必要はないです。
javascriptの表記がありますが、TypeScriptの選択肢はないので問題ありません。
Yを押しましょう。

続いてこのプロジェクトで使うIAMユーザーの設定を行います。
AWS profileを使うかどうか聞かれます。わたしは先ほど取得したAccess keyとSecret Access keyを使います。
```
? Do you want to use an AWS profile? (Y/n)
```

nを入力します。
```
? accessKeyId:  (<YOUR_ACCESS_KEY_ID>) #さきほど保存したAccess key
? secretAccessKey:  (<YOUR_SECRET_ACCESS_KEY>) #さきほど保存した Secret Access key
```

続いてリージョンの選択をします。
```
? region:  (Use arrow keys)
❯ us-east-1 
  us-east-2 
  us-west-2 
  eu-west-1 
  eu-west-2 
  eu-central-1 
  ap-northeast-1 
(Move up and down to reveal more choices)
```
Step1で選択したリージョンを選びましょう。東京の場合  ap-northeast-1 です。
プロジェクト内の初期化が行われます。初期化が終わるまでしばらく待ちましょう。
終わると下記処理が完了されています。
- amplifyディレクトリが作成されます。バックエンドの定義が入っています。
- srcディレクトリにaws-exports.jsが作成されます。
- リポジトリで共有しないほうが良いファイルについて.gitignoreに追記されます。

#### 3. Install Amplify libraries
Amplify LibrariesとAmplify UI Components(Vue3版)をインストールします。
UI ComponentsはVue2の場合異なりますので注意しましょう。
```bash
yarn add aws-amplify@^5.0.4 @aws-amplify/ui-vue@3.0.2
```

#### 4. Set up frontend
インストールしたAmplify LibrariesをVueに組み込みます。
src/main.tsを開き下記ソースコードを追加しましょう。
```ts:src/main.ts
// Components
import App from './App.vue';

// Composables
import { createApp } from 'vue';

// Plugins
import { registerPlugins } from '@/plugins';
//追加ここから
import { Amplify } from 'aws-amplify';
import awsExports from './aws-exports';
Amplify.configure(awsExports);
//追加ここまで
const app = createApp(App);

registerPlugins(app);

app.mount('#app');
```

##### Vue Vite Config
ViteでAmplifyを使う際以下の設定が必要です。
このあたりが初心者が躓くポイントです。

###### 4.2.1 `index.html`にスクリプトタグを追加します。
```html:index.html
...
  <script>
        window.global = window;
        var exports = {};
  </script>
</body>
```

Viteのindex.htmlはpublic/ではなく、直下にあります。
###### 4.2.2 `vite.config.ts`の `defineConfig({})`に解決オブジェクトを追加します。
```ts:vite.config.ts
...
export default defineConfig({
...
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
      //追加
      './runtimeConfig': './runtimeConfig.browser',
      //追加ここまで    },
...
```

###### 4.2.3 TypeScriptを使っている場合は`tsconfig.json`の`compilerOptions`に`skipLibCheck: true`を追加します。
```json:tsconfig.json
{
  "compilerOptions": {
    "baseUrl": "./",
    "target": "esnext",
    "useDefineForClassFields": true,
    "allowSyntheticDefaultImports": true,
    "composite": true,
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": false,
    "noImplicitThis": true,
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "lib": ["esnext", "dom"],
    "types": ["vuetify"],
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": [
    "env.d.ts",
    "src/**/*",
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "vite.config.ts"
  ]
}
```
###### 4.2.4 その他ファイルの追加
src/aws-exports.d.tsとsrc/shims-vue.d.tsを追加します。

```ts:src/aws-exports.d.ts
declare const awsmobile: Record<string, any>;
export default awsmobile;
```

```ts:src/shims-vue.d.ts
declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<Record<string,unknown>, Record<string,unknown>, unknown>
  export default component
}
```
##### Gitなどバージョン管理に入れてよいファイルか？
[Files and Folders](https://docs.amplify.aws/cli/reference/files/#gitignore)を参照しましょう。
基本的に共有してはいけないファイルは.gitignore に自動で入ります。
publicなリポジトリはteam-provider-info.jsonを公開しないようにしましょう。

*オプション ここまでの工程がうまくいっているか確認のためにサーバーを起動してみましょう。
```bash
yarn dev
```
先ほど変わらない結果が表示されていればOKです。
次はGraphQLを使ってデータベースに接続します。

### Connect API and database to the app(Step3)
![](https://storage.googleapis.com/zenn-user-upload/1949c01544a4-20220311.jpg)
このステップではAmplify CLIコマンドを使ってAWSのリソース(AppSync + DynamoDB)を作成後、Amplify Librariesを使ってリソースにアクセスし、データベースのRead/Writeを行います。
チュートリアルのメインの項目といってよいほどボリュームがあります。
Amplify　CLIコマンドは amplify add （使うリソース）を設定後、amplify pushを叩くことでAWS上にリソースが作成されます。

#### 1. Create GraphQL API and database
Amplify CLIコマンドで amplify add apiを叩きます。
```bash
amplify add api
```
GraphQLを選択します。
対話形式はひとまず下記のようなデフォルトのままでよいです。
```
? 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: Single object with fields (e.g., “Todo” with ID, name, description)
```

最後にスキーマーを編集するをYesを選択しているので
コードエディタがgraphqlのスキーマーを開きます。
特に編集する必要はありません。

```graphql:amplify/backend/api/todo/schema.graphql
type Todo @model {
  id: ID!
  name: String!
  description: String
}
```

@modelと書くことにより、DynamoDBにテーブルが作成されgraphQL(AppSync)を介して操作するようになります。

#### 2. Deploy your GraphQL API

Amplify CLIコマンド amplify push を叩くことによりAWS上に構築をします。
しばらく待つと
3.Generate frontend code for the GraphQL API に進みます。
```bash
amplify push
```

#### 3. Generate frontend code for the GraphQL API

いくつか対話形式で聞かれるので同じように入力します。
```
? Do you want to generate code for your newly created GraphQL API Yes
? Choose the code generation language target typescript
? Enter the file name pattern of graphql queries, mutations and subscriptions src/graphql/**/*.ts
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions Yes
? Enter maximum statement depth [increase from default if your schema is deeply nested] 2
? Enter the file name for the generated code src/API.ts
```

処理が終わるまでしばらく待ちます。
処理が終わったら正常におこなわれているかAmplify CLIでamplify statusで状況を確認します。

```bash
amplify status
```

以下と同じ表示であればOKです。

```
Current Environment: dev
    
┌──────────┬───────────────┬───────────┬───────────────────┐
│ Category │ Resource name │ Operation │ Provider plugin   │
├──────────┼───────────────┼───────────┼───────────────────┤
│ Api      │ todo          │ No Change │ awscloudformation │
└──────────┴───────────────┴───────────┴───────────────────┘
```


#### 4. Connect frontend to API

graphqlを使ってDynamoDBをRead/Writeする処理をコーディングします。
Vue(src/App.vue)を編集しましょう。

最初にcreateTodoを使ってTodoを入力できる機能を作ります。
この時点では入力の機能のみです。
```vue:src/App.vue
<template>
  <div id="app">
    <h1>Todo App</h1>
    <input type="text" v-model="name" placeholder="Todo name" />
    <input type="text" v-model="description" placeholder="Todo description" />
    <button v-on:click="createTodo">Create Todo</button>
  </div>
</template>

<script lang="ts">
import { API } from 'aws-amplify';
import { createTodo } from './graphql/mutations';

export default {
  name: 'app',
  data() {
    return {
      name: '',
      description: '',
    };
  },
  methods: {
    async createTodo() {
      const { name, description } = this;
      if (!name || !description) return;
      const todo = { name, description };
      await API.graphql({
        query: createTodo,
        variables: { input: todo },
      });
      this.name = '';
      this.description = '';
    },
  },
};
</script>
```

サーバーを立ち上げて、動作確認します。

```bash
yarn dev 
```
入力できることを確認したらCtrl + cでサーバーを停止します。

Amplfiyとは関係ありませんが、折角なのでVuetifyのコンポーネントを使ってみます。
```vue:src/App.vue<template>
  <v-app id="app">
    <v-main>
      <v-container>
        <h1>Todo App</h1>
        <v-text-field type="text" v-model="name" label="Todo name" />
        <v-text-field type="text" v-model="description" label="Todo description" />
        <v-btn color="primary" @click="handleClickCreateTodo">Create Todo</v-btn>
      </v-container>
    </v-main>
  </v-app>
</template>
...
```

続いてscriptをsetupに変えます。
開発を進めていくとsetupのほうがコードの可読性が上がりやすいと思います。
```vue:src/App.vue
...
<script setup lang="ts">
import { API } from 'aws-amplify';
import { ref } from 'vue';
import { createTodo } from './graphql/mutations';

const name = ref('');
const description = ref('');
const handleClickCreateTodo = async () => {
  if (!name.value || !description.value) return;
  const todo = { name: name.value, description: description.value };
  await API.graphql({
    query: createTodo,
    variables: { input: todo },
  });
  name.value = '';
  description.value = '';
};
</script>
```

#### 5. Reading data with GraphQL queries

続いてlistTodosを使って入力した内容を表示します。
```vue:src/App.vue
<template>
  <v-app id="app">
    <v-main>
      <v-container>
        <h1>Todo App</h1>
        <v-text-field type="text" v-model="name" label="Todo name" />
        <v-text-field type="text" v-model="description" label="Todo description" />
        <v-btn color="primary" @click="handleClickCreateTodo">Create Todo</v-btn>
        <div v-for="item in todos" :key="item.id">
          <h3>{{ item.name }}</h3>
          <p>{{ item.description }}</p>
        </div>
      </v-container>
    </v-main>
  </v-app>
</template>

<script setup lang="ts">
import { GraphQLResult } from '@aws-amplify/api';
import { API } from 'aws-amplify';
import { ref } from 'vue';
import { ListTodosQuery, Todo } from './API';
import { createTodo } from './graphql/mutations';
import { listTodos } from './graphql/queries';

const name = ref('');
const description = ref('');
const todos = ref<Todo[]>([]);
const handleClickCreateTodo = async () => {
  if (!name.value || !description.value) return;
  const todo = { name: name.value, description: description.value };
  await API.graphql({
    query: createTodo,
    variables: { input: todo },
  });
  name.value = '';
  description.value = '';
  getTodos();
};
const getTodos = async () => {
  const result = (await API.graphql({
    query: listTodos,
  })) as GraphQLResult<ListTodosQuery>;
  if (result.data?.listTodos) {
    todos.value = result.data.listTodos.items as Todo[];
  } else {
    todos.value = [];
  }
};
getTodos();
</script>
```
こちらも先ほどと同じように正しく動いているか確認しましょう。
4.で入力した内容が表示されます。
```bash
yarn dev
```

#### 6. Real-time data with GraphQL subscriptions

最後にサブスクリプションの例を掲載します。
TypeScriptで書くとちょっといろいろ大変です。

```vue:src/App.vue
...
<script setup lang="ts">
import { graphqlOperation, GraphQLResult } from '@aws-amplify/api';
import { API } from 'aws-amplify';
import { ref } from 'vue';
import { ListTodosQuery, OnCreateTodoSubscription, Todo } from './API';
import { createTodo } from './graphql/mutations';
import { listTodos } from './graphql/queries';
import { onCreateTodo } from './graphql/subscriptions';
type OnCreateTodoSubscriptionEvent = {
  value: { data: OnCreateTodoSubscription };
};
...
const handleClickCreateTodo = async () => {
  if (!name.value || !description.value) return;
  const todo = { name: name.value, description: description.value };
  await API.graphql({
    query: createTodo,
    variables: { input: todo },
  });
  name.value = '';
  description.value = '';
  //subscribeでとるので不要
  //getTodos();
};
...
const subscribe = () => {
  const observe = API.graphql(graphqlOperation(onCreateTodo));
  if ('subscribe' in observe) {
    observe.subscribe({
      next: (eventData: OnCreateTodoSubscriptionEvent) => {
        const todo = eventData.value.data.onCreateTodo;
        if (todo?.name) {
          if (todos.value.some((item) => item.name === todo.name)) return; // remove duplications
          todos.value.push(todo);
        }
      },
    });
  }
};
getTodos();
subscribe();
</script>

```
### Add authentication(Step4)
![](https://storage.googleapis.com/zenn-user-upload/40acf566649f-20220311.jpg)

このステップでは認証を構築します。Amplify CLIで認証を作成後、Amplify UI Componentsを使って爆速で認証コンポーネントを作成します。

#### 1. Create authentication service

Amplify CLIコマンドで amplify add authを叩きます。

```bash
amplify add auth
```
以下の通り対話形式の選択を行ってください。
これによりAWS Cognitoを認証プロバイダーとして使用できます。
Cognitoはユーザーの登録、認証、パスワードの設定など堅牢なユーザー管理サービスを提供します。
```
? Do you want to use the default authentication and security configuration? Default configuration
? How do you want users to be able to sign in? Username
? Do you want to configure advanced settings?  No, I am done.
```
apiの時と同じく、Amplify CLIコマンド amplify push を叩くことによりAWS上に構築をします。
```bash
amplify push
```
続いて対話形式で処理を続けるか聞かれるのでYesを選択してください。
```
? Are you sure you want to continue? Y
```
#### 2. Create login UI
Step2でインストールしたAmplify UIをここで使います。
tsとしてはimportのみ、htmlはタグ(authenticator)で囲むだけです。
以下がソースコード例になります。
```vue:src/App.vue
<template>
  <v-app id="app">
    <v-main>
      <v-container>
        <authenticator>
          <h1>Todo App</h1>
          <v-text-field type="text" v-model="name" label="Todo name" />
          <v-text-field type="text" v-model="description" label="Todo description" />
          <v-btn color="primary" @click="handleClickCreateTodo">Create Todo</v-btn>
          <div v-for="item in todos" :key="item.id">
            <h3>{{ item.name }}</h3>
            <p>{{ item.description }}</p>
          </div>
        </authenticator>
      </v-container>
    </v-main>
  </v-app>
</template>

<script setup lang="ts">
import { Authenticator } from '@aws-amplify/ui-vue';
import '@aws-amplify/ui-vue/styles.css';
...
</script>
```
Amplify UI ComponentsのAuthenticatorを使います。
authenticatorタグで挟むことにより、認証機能が実装されます。
認証後に今までの画面が表示されることになります。
サーバーを立ち上げて動作確認をしましょう。
```bash
yarn dev
```
![](https://storage.googleapis.com/zenn-user-upload/b0022989b804-20220311.png)
上記の画面が表示されます。
右のCreate Accountタブをクリックしてアカウントを作成しましょう。
![](https://storage.googleapis.com/zenn-user-upload/efa81795e119-20220311.png)
入力したメールアドレスに認証コードなどが行われ、メールアドレスの確認が取れるとアカウント登録は完了です。
ログインはメールアドレスではなくUsernameなので気を付けましょう。
今まで通りの画面が表示されたらOKです。
続いてusernameとSignOut機能を実装します。
html部のみの変更でOKです。
```vue:src/App.vue
<template>
  <div id="app">
    <authenticator>
      <template v-slot="{ user, signOut }">
        <h2>Hello {{ user.username }}!</h2>
        <v-btn color="info" @click="signOut">Sign Out</v-btn>
        ...
      </template>
    </authenticator>
  </div>
</template>
```
動作確認しましょう。signOutがあっという間に実装できたと思います。
```bash
yarn dev
```
### Deploy and host app(Step5)
![](https://storage.googleapis.com/zenn-user-upload/2f489bba82db-20220311.jpg)

最後にAmplify Hostingを使ってWebサービスをインターネットに公開します。（ホストにデプロイします。）
#### 1. Add hosting to your app
Amplify CLIコマンドで amplify add hostingを叩きます。

```bash
amplify add hosting
```
以下のように対話形式の選択を行ってください。
```
? Select the plugin module to execute: # Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
? Choose a type: # Manual Deployment
```

#### 2. Publish your app
Amplify CLIコマンドで amplify publishでWebサイトを公開します。

pushではないので注意しましょう。
```bash
amplify publish
```
しばらく待つと。
(任意の文字列).amplifyapp.comでwebサイトが公開されます。
ブラウザで開いて動作を確認しましょう。

Step4で作成したユーザーでログインしましょう。
今まで作成したTodoリストが表示されるはずです。
これはAWSリソース（Cognito,DynamoDB）を使っているので同じ内容になります。
IAMユーザーを作るとき以外はAWSのコンソールに入ることなくDBを使い、認証を伴う、WEBサービスを作成することが確認できたと思います。
おめでとうございます！

ある程度確認して満足したらさみしいですが
Amplify CLIコマンドの amplify deleteでAWSリソースを削除します。
```bash
amplify delete
```
本当に削除してよいですか？と対話形式で聞かれるのでYを選択しましょう。
アプリケーションに使ったすべてのリソースが削除されます。
とても便利ですね。
※IAMユーザーは消えてないので必要がなければ削除しましょう。

## Amplify でハマったところ
- AmplifyあるいはAWS Amplifyから始まる言葉多すぎ。あと意味変わりすぎ。
- 破壊的変更が多くビビる。
- 公式の半年前のチュートリアルが動かないことがある。(ライブラリのバージョン指定がないサンプルは動かないと考える。バージョン指定がある場合は必ず合わせる)


### たくさんのAmplifyから始まる言葉について


#### Amplify Framework
 * Amplifyの仕組み全体を示します。
 * 当初はフロントエンドのライブラリのことを意味していました。
 そのためLibrriesとUIのことを意味していることもあります←罠です。

#### Amplify CLI
 * バックエンド構築をCLIで行う(amplify add *** 等）
 * 公式ドキュメントが見やすい。うまくいかないときはgithubのissueをチェックしよう
 * Amplify CLIのAPI(GraphQL)≒AppSyncのAmplify CLI版

#### Amplify Console
 * WebのConsole画面のこと
 * Hostingことを意味している場合もある

#### Amplify Librries
 * javascript/iOS/Android/Flutter別のライブラリを通してAWSのリソースを使う仕組み
 * フロントエンド側からAmplify CLIを使っていない既存のバックエンドリソースを使うことができる

#### Amplify UI Components
 * https://ui.docs.amplify.aws/
 * Framework別(開発におけるアプリケーションの枠組み)のコンポーネント
主にReactのものが多い

#### Amplify Hosting
 * 単純なホスティングあるいはリポジトリに接続してCI/CDを行う仕組み
 * たまに単純なホスティングのことをAmplifyと略していることがある

#### Amplify Studio(旧Admin UI)
 * ノンプログラミングとかローコードとかノーコードとかいろいろ言われていますがそれだけではない
 * FigmaからReactコンポーネント作れます
 * AWSのアカウントを持っていなくてもAmplifyで作ったバックエンドの設定をGUIでできます←とても便利

#### Amplify Mocking
 * ローカル環境でバックエンド環境を試すことができます
 * 爆速で開発できるという売りですが構築に4~5分かかることがしばしばあるため、トライアンドエラーで試すのはMockを使うのが良いと思います
 * Javaの環境が必要です

## 終わりに
Amplifyを使うことで環境の再構築が楽なりました。
Backendと管理が統合できるのも魅力の一つです。
それではよきAmplifyライフを！