ViteのプロジェクトにAmplifyの設定を適用する方法

aws-cli等を経由してローカルのPCでAmplifyを利用した開発の環境を構築する方法の[前回の続き](https://qiita.com/maejima_f/items/8618c08eb96f80579a1b)です。
この記事ではViteのプロジェクトにAmplifyの設定を適用する手順をまとめています。


# Viteのプロジェクトの作成

`React`+`TypeScript`の構成が前提です。

```shell
$ yarn create vite
yarn create v1.22.10

success Installed "create-vite@2.6.6" with binaries:
      - create-vite
      - cva
✔ Project name: … vite-test
✔ Select a framework: › react
✔ Select a variant: › react-ts

Scaffolding project in /Users/userName/path/vite-test...

Done. Now run:

  cd vite-test
  yarn
  yarn dev

✨  Done in 22.98s.

```

## アプリケーションへのamplifyの設定

`amplify init`コマンドを実行して設定の初期化を行います。

*実行後に作成される`amplify`ディレクトリに秘匿情報が含まれるている為、`amplify`ディレクトリを`gitignore`に入れておきましょう。


```Shell-session
$ amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project amplifytest
The following configuration will be applied:

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

? Initialize the project with the above configuration? No
? Enter a name for the environment dev
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: dist
? Build Command:  npm run-script build
? Start Command: npm run-script start
Using default provider  awscloudformation

? Select the authentication method you want to use: AWS profile

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html

? Please choose the profile you want to use profile_name
Adding backend environment dev to AWS Amplify Console app: xxxxxxxxxxx
⠼ Initializing project in the cloud...

Initialized your environment successfully.

Your project has been successfully initialized and connected to the cloud!

Some next steps:
"amplify status" will show you what you've added already and if it's locally configured or deployed
"amplify add <category>" will allow you to add features like user login or a backend API
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify console" to open the Amplify Console and view your project status
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud

Pro tip:
Try "amplify add api" to create a backend API and then "amplify publish" to deploy everything

```

この時点でクラウド上に`Amplify`にアプリケーションが、`CloudFormation`にスタックが、`S3`にバックエンド用のバケットが作成されている段階です。

`amplify init`で行った設定はプロジェクトフォルダ内の`amplify/.config/local-env-info.json`と`amplify/.config/project-config.json`で確認出来ます。

gitの管理対象外になっていないかつvscodeなどでは表示されない為注意が必要です。


```Shell-session
$ cat amplify/.config/local-env-info.json
{
  "projectPath": "/path/amplify-test",
  "defaultEditor": "vscode",
  "envName": "dev"
}
```

```Shell-session
$ cat amplify/.config/project-config.json
{
  "projectName": "amplifytest",
  "version": "3.1",
  "frontend": "javascript",
  "javascript": {
    "framework": "react",
    "config": {
      "SourceDir": "src",
      "DistributionDir": "dist",
      "BuildCommand": "npm run-script build",
      "StartCommand": "npm run-script start"
    }
  },
  "providers": [
    "awscloudformation"
  ]
}
```

また、`/src/aws-exports.js`が作成される為設定を追加する前に同ファイルをコピーしてts拡張子に変更したファイルを用意するとmain.tsxやApp.tsxなどで参照しやすくなります。
(aws-exports.jsは設定を追加する度に更新される為これも`gitignore`に追加すると良いでしょう)。

---

## reactアプリケーションにamplifyを適用する

以前は`aws-amplify-react`をインストールする旨が記載されていたのですが2022年現在では`@aws-amplify/ui-react`をインストールする方が良いです。
今後はこちらを更新していく方針の様だからです。

また、`@aws-amplify/ui-react`単体だとCSSが無い旨等のエラーが発生する為、`@aws-amplify/ui`もインストールしておきます。

```Shell-session
$ yarn add aws-amplify @aws-amplify/ui-react @aws-amplify/ui
```


参考

[Amplify Docs](https://docs.amplify.aws/ui/q/framework/react/)

[Amplify UI](https://ui.docs.amplify.aws/)

[aws-amplify/amplify-ui](https://github.com/aws-amplify/amplify-ui)


## App.tsxに設定の追加

最小限の設定としては下記の様な形で基本のログインフォームの表示が可能になります。

```tsx
import React, { useState } from 'react'
import Amplify from 'aws-amplify'
import awsConfig from '@/aws-exports'
import { Authenticator } from '@aws-amplify/ui-react'
import '@aws-amplify/ui-react/styles.css'

// Amplifyの設定を行う
Amplify.configure(awsConfig)

function App() {
  return (
    <Authenticator>
      {({ signOut, user }) => (
        <div className="app">
          <!-- main contents -->
        </div>
      )}
    </Authenticator>
  )
}
```


---

## デフォルトの機能の修正

デフォルトのログインフォームを修正してみます。

日本語の設定をしたいのと、管理画面のログインフォームを想定した時にsign upとpassword resetはフォーム内に表示する必要無さそうですのでこれらを非表示にしていきます。

#### 修正内容
1. 日本語設定
2. sign out機能ハンドラー設定
3. sign up機能の非表示化
4. password reset機能の非表示化

設定情報などを編集する事でこの辺り柔軟に設定出来るかと思っていたのですが、実際やってみるとcssで非表示など地道な事も必要でした。

最小限の設定としては下記の様な実装で管理画面向けのフォームを作成する事が出来ます。

```tsx
import React, { useState } from 'react'
import Amplify from 'aws-amplify'
import awsConfig from '@/aws-exports'
import { Authenticator, View } from '@aws-amplify/ui-react'
import '@aws-amplify/ui-react/styles.css'

// 日本語化対応
import { translations } from '@aws-amplify/ui'
I18n.putVocabularies(translations)
I18n.setLanguage('ja')

import { AppRouter } from '@/AppRouter'
import { AuthGlobalHeader } from '@/components/global/GlobalHeader'

// Amplifyの設定を行う
Amplify.configure(awsConfig)

function App() {
  // 認証フォームコンポーネントの拡張設定
  const components = {
    // パスワードリセットフォームでの入力を防ぐ
    SignIn: {
      Footer() {
        return <View textAlign="center">*パスワードリセットは出来ません。</View>
      },
    },
    // sign up コンポーネントのフォームを設定しない事で入力を防ぐ
    SignUp: {
      FormFields() {
        return <View textAlign="center"></View>
      },
    },
  }

  return (
    <Authenticator variation="modal" components={components}>
      {({ signOut, user }) => (
        <div className="app">
          <GlobalHeader signOut={signOut} />
          <div>
            <!-- main contents -->
          </div>
        </div>
      )}
    </Authenticator>
  )
}

export default App

```

signIn & signUpのタブを非表示にする為に下記のCSS設定を追加する必要があります。

```scss
.amplify-tabs {
  display: none !important;
}
```


---

## amplifyプロジェクトのリポジトリをcloneした後の対応

`amplify`ディレクトリなどをソース管理していないプロジェクトをcloneして来た場合、`amplify pull ${AMPLIFY_APP_ID}`コマンドを打ってプロジェクト情報を取得する必要があります。

その為、AWS上で管理されているAmplify のAPP_IDだけはしっかり管理する必要があります。

```Shell-session
$ amplify pull ${AMPLIFY_APP_ID}
? Select the authentication method you want to use: AWS profile

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html

? Please choose the profile you want to use profile_name
? Which app are you working on? amplify_app_id
Backend environment 'dev' found. Initializing...
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: dist
? Build Command:  npm run-script build
? Start Command: npm run-script start
? Do you plan on modifying this backend? Yes
✔ Successfully pulled backend environment dev from the cloud.


Successfully pulled backend environment dev from the cloud.
Run 'amplify pull' to sync future upstream changes.
```

.gitignoreが更新されてしまうことがあるので元に戻しておくことを忘れないでください。


---

## amplify-cliを用いた開発の流れ

開発中のamplify-cliコマンドの基本的な使い方は下記の様な形です。
開発からデプロイまでCUIで完結出来る為これを使いこなして開発の効率を上げていければと考えております。

＊ホスティングとAPIの設定に`amplify add hosting`や`amplify add auth`、`amplify add api`の実行が事前に必要になります。

1. `amplify add xxx`でアプリケーションに必要なAWSのサービスを追加する。
2. `amplify push`で追加した機能を有効化させる(CloudFrontのテンプレートファイルを更新)。
3. `amplify publish`で静的リソースを`S3/CloudFront`にデプロイする。
4. `amplify delete`でinitで作成した環境を全て削除。
5. `amplify pull`で最新の状態の更新。
6. `amplify console`でブラウザのaws コンソール画面を開く(Amplify Studioも選べる)。

---

## troubleshooting

2022/03/13 現在

viteでamplifyを使う場合、下記に記載された対応が必要です。


[aws/aws-sdk-js/issues/3673](https://github.com/aws/aws-sdk-js/issues/3673)
[getting-started/installation?platform=vue#troubleshooting](https://ui.docs.amplify.aws/ui/getting-started/installation?platform=vue#troubleshooting)