Next.jsとTypeScriptとAWS Amplifyを使ってアプリケーションを開発するときにするべきただ1つのこと

tsconfig.jsonexcludeプロパティに"amplify"を追加するだけです。

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules", "amplify"]
}

なぜ?

Next.jsにはsrcディレクトリがありません。

そのため、Amplifyプロジェクトをセットアップするときには、Source directory path.(現在のディレクトリ)に設定します。

$ npx create-next-app@latest --typescript
$ cd my-app
$ amplify init
注: このコマンドはアプリのルートディレクトリから実行することをお勧めします
? プロジェクトの名前を入力してください myapp
以下の設定が適用されます:

プロジェクト情報
| 名前: myapp
| 環境: dev
| デフォルトのエディター: Visual Studio Code
| アプリのタイプ: javascript
| Javascriptのフレームワーク: react
| ソースディレクトリパス: src
| 配布ディレクトリパス: build
| ビルドコマンド: npm run-script build
| 開始コマンド: npm run-script start

? 上記の設定でプロジェクトを初期化しますか? No
? 環境の名前を入力してください dev
? デフォルトのエディターを選んでください Visual Studio Code
? あなたが作っているアプリのタイプを選んでください javascript
あなたのプロジェクトについて教えてください
? 使用しているJavascriptのフレームワークは? react
? ソースディレクトリパス:  .
? 配布ディレクトリパス: .next
? ビルドコマンド:  npm run build
? 開始コマンド: npm run start
デフォルトプロバイダとして awscloudformation を使用
? 使用する認証方法を選んでください: AWSプロファイル

AWSプロファイルに関する詳細はこちらでご覧になれます:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html

? 使用するプロファイルを選んでください default
AWS Amplify App: d3rkk8kj6rlblgにバックエンド環境devを追加
⠦ クラウドでプロジェクトを初期化中...

(省略)

$

Next.jsのビルド対象は、現在のディレクトリ内のファイルとディレクトリであり、amplifyディレクトリも含まれます。

ちなみに、amplify-cliでAWSリソースをオーバーライドすることができます。

オーバーライドオプションを使用すると、amplify-cliはamplifyディレクトリの下にoverride.tsを生成します。

そして、このファイルが予期せずNext.jsのビルド対象となってしまいます。

そのため、tsconfig.jsonexcludeプロパティに"amplify"を追加する必要があります。

以下の手順でエラーを確認することができます。

まず、apiを追加します。

$ amplify add api
? 以下のサービスから選んでください: GraphQL
? こちらが作成するGraphQL APIです。設定を編集するか続行してください 続行
? スキーマのテンプレートを選んでください: フィールドを持つ単一オブジェクト (例: “Todo”にはID, 名前, 説明)

⚠️  警告: 現在のGraphQL APIはAPIキー経由ですべてのモデルに対して公開の作成、読み取り、更新、削除アクセスを許可しています。本番環境に備えた承認ルールを設定するためには、こちらを確認してください: https://docs.amplify.aws/cli/graphql/authorization-rules

GraphQLスキーマが正しくコンパイルされました。

スキーマは/home/ec2-user/environment/my-app/amplify/backend/api/myapp/schema.graphql で編集するか、.graphql ファイルを/home/ec2-user/environment/my-app/amplify/backend/api/myapp/schemaのディレクトリに置いてください
✔ 今スキーマを編集しますか? (Y/n) · no
✅ リソースmyappをローカルに正常に追加しました

✅ 次のステップ:
"amplify push" でローカルのバックエンドリソースをすべてビルドし、クラウドに設定します
"amplify publish" でローカルのバックエンドとフロントエンドのリソースをすべてビルドし(ホスティングカテゴリーが追加されている場合)、クラウドに設定します

$

次に、apiをオーバーライドします。

$ amplify override api

⚠️  警告: 現在のGraphQL APIはAPIキー経由ですべてのモデルに対して公開の作成、読み取り、更新、削除アクセスを許可しています。本番環境に備えた承認ルールを設定するためには、こちらを確認してください: https://docs.amplify.aws/cli/graphql/authorization-rules

GraphQLスキーマが正しくコンパイルされました。

スキーマは/home/ec2-user/environment/my-app/amplify/backend/api/myapp/schema.graphql で編集するか、.graphql ファイルを/home/ec2-user/environment/my-app/amplify/backend/api/myapp/schemaのディレクトリに置いてください
✅ "override.ts" フォルダを/home/ec2-user/environment/my-app/amplify/backend/api/myappに正常に生成しました
✔ 今override.tsファイルを編集しますか? (Y/n) · no
$ 

そして、override.tsを編集します。

import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper';

export function override(resources: AmplifyApiGraphQlResourceStackTemplate) {
  resources.models["Todo"].modelDDBTable.timeToLiveSpecification = {
    attributeName: "ttl",
    enabled: true
  }
}

最後に、このプロジェクトをビルドしてエラーを捉えます。

$ npm run build

> my-app@0.1.0 build
> next build

Failed to compile.

./amplify/backend/api/myapp/override.ts:4:3
Type error: Object is possibly 'undefined'.

  2 | 
  3 | export function override(resources: AmplifyApiGraphQlResourceStackTemplate) {
> 4 |   resources.models["Todo"].modelDDBTable.timeToLiveSpecification = {
    |   ^
  5 |     attributeName: "ttl",
  6 |     enabled: true
  7 |   }
情報  - 型の有効性をチェックしています。
$

環境