AIダンジョンゲーム
モジュール1: モノレポのセットアップ
まず新しいモノレポを作成します。任意のディレクトリで以下のコマンドを実行してください:
npx create-nx-workspace@~20.6.3 dungeon-adventure --pm=pnpm --preset=ts --ci=skip --formatter=prettier
npx create-nx-workspace@~20.6.3 dungeon-adventure --pm=yarn --preset=ts --ci=skip --formatter=prettier
npx create-nx-workspace@~20.6.3 dungeon-adventure --pm=npm --preset=ts --ci=skip --formatter=prettier
npx create-nx-workspace@~20.6.3 dungeon-adventure --pm=bun --preset=ts --ci=skip --formatter=prettier
これによりdungeon-adventure
ディレクトリ内にNXモノレポがセットアップされ、vscodeで開けるようになります。ファイル構造は以下のようになります:
Directory.nx/
- …
Directory.vscode/
- …
Directorynode_modules/
- …
Directorypackages/ サブプロジェクトが配置される場所
- …
- .gitignore
- .npmrc
- .prettierignore
- .prettierrc
- nx.json Nx CLIとモノレポのデフォルト設定
- package.json 全Node依存関係の定義
- pnpm-lock.yaml または bun.lock, yarn.lock, package-lock.json(パッケージマネージャー依存)
- pnpm-workspace.yaml(pnpm使用時)
- README.md
- tsconfig.base.json 全Nodeベースサブプロジェクトが継承する設定
- tsconfig.json
@aws/nx-plugin
のコンポーネントをモノレポに追加するには、まず開発依存関係としてインストールする必要があります。dungeon-adventure
モノレポのルートで以下のコマンドを実行してください:
pnpm add -Dw @aws/nx-plugin
yarn add -D @aws/nx-plugin
npm install --legacy-peer-deps -D @aws/nx-plugin
bun install -D @aws/nx-plugin
これで@aws/nx-plugin
を使用してさまざまなサブプロジェクトを作成する準備が整いました。
ゲームAPI
まずGame APIを作成します。以下の手順でtRPC APIのGameApi
を作成します:
- インストール Nx Console VSCode Plugin まだインストールしていない場合
- VSCodeでNxコンソールを開く
- クリック
Generate (UI)
"Common Nx Commands"セクションで - 検索
@aws/nx-plugin - ts#trpc-api
- 必須パラメータを入力
- apiName: GameApi
- クリック
Generate
pnpm nx g @aws/nx-plugin:ts#trpc-api --apiName=GameApi --no-interactive
yarn nx g @aws/nx-plugin:ts#trpc-api --apiName=GameApi --no-interactive
npx nx g @aws/nx-plugin:ts#trpc-api --apiName=GameApi --no-interactive
bunx nx g @aws/nx-plugin:ts#trpc-api --apiName=GameApi --no-interactive
変更されるファイルを確認するためにドライランを実行することもできます
pnpm nx g @aws/nx-plugin:ts#trpc-api --apiName=GameApi --no-interactive --dry-run
yarn nx g @aws/nx-plugin:ts#trpc-api --apiName=GameApi --no-interactive --dry-run
npx nx g @aws/nx-plugin:ts#trpc-api --apiName=GameApi --no-interactive --dry-run
bunx nx g @aws/nx-plugin:ts#trpc-api --apiName=GameApi --no-interactive --dry-run
ファイルツリーに新しいファイルが生成されます。
ts#trpc-api 更新ファイル
ts#trpc-api
ジェネレーターが生成した主要ファイルの一覧です。ファイルツリー内の主要ファイルをいくつか確認します:
Directorypackages/
Directorycommon/
Directoryconstructs/
Directorysrc/
Directoryapp/ アプリ固有CDKコンストラクト
Directoryhttp-apis/
- game-api.ts tRPC API作成用CDKコンストラクト
- index.ts
- …
- index.ts
Directorycore/ 汎用CDKコンストラクト
- http-api.ts HTTPベースAPI用基底コンストラクト
- index.ts
- runtime-config.ts
- index.ts
- project.json
- …
Directorytypes/ 共有型定義
Directorysrc/
- index.ts
- runtime-config.ts CDKとWebサイトで使用するインターフェース定義
- project.json
- …
Directorygame-api/
Directorybackend/ tRPC実装コード
Directorysrc/
Directoryclient/ 機械間通信用バニラクライアント
- index.ts
- sigv4.ts
Directorymiddleware/ Powertools計装
- error.ts
- index.ts
- logger.ts
- metrics.ts
- tracer.ts
Directoryprocedures/ APIプロシージャ/ルート実装
- echo.ts
- index.ts
- init.ts コンテキストとミドルウェア設定
- local-server.ts ローカルtRPCサーバー実行用
- router.ts ラムダハンドラーのエントリポイント
- project.json
- …
Directoryschema/
Directorysrc/
Directoryprocedures/
- echo.ts
- index.ts
- project.json
- …
- eslint.config.mjs
- vitest.workspace.ts
主要ファイルの解説:
import { awsLambdaRequestHandler, CreateAWSLambdaContextOptions,} from '@trpc/server/adapters/aws-lambda';import { echo } from './procedures/echo.js';import { t } from './init.js';import { APIGatewayProxyEventV2WithIAMAuthorizer } from 'aws-lambda';
export const router = t.router;
export const appRouter = router({ echo,});
export const handler = awsLambdaRequestHandler({ router: appRouter, createContext: ( ctx: CreateAWSLambdaContextOptions<APIGatewayProxyEventV2WithIAMAuthorizer>, ) => ctx,});
export type AppRouter = typeof appRouter;
ルーターはtRPC APIのエントリポイントで、すべてのAPIメソッドを宣言する場所です。echo
メソッドの実装は./procedures/echo.ts
にあります。
import { publicProcedure } from '../init.js';import { EchoInputSchema, EchoOutputSchema,} from ':dungeon-adventure/game-api-schema';
export const echo = publicProcedure .input(EchoInputSchema) .output(EchoOutputSchema) .query((opts) => ({ result: opts.input.message }));
echo
メソッドの実装ファイルです。入力/出力データ構造を厳密に型定義し、:dungeon-adventure/game-api-schema
プロジェクトから定義をインポートしています。エイリアスを使用しています。
import { z } from 'zod';
export const EchoInputSchema = z.object({ message: z.string(),});
export type IEchoInput = z.TypeOf<typeof EchoInputSchema>;
export const EchoOutputSchema = z.object({ result: z.string(),});
export type IEchoOutput = z.TypeOf<typeof EchoOutputSchema>;
Zodを使用したtRPCスキーマ定義と型エクスポート。
import { Construct } from 'constructs';import * as url from 'url';import { HttpApi } from '../../core/http-api.js';import { HttpIamAuthorizer } from 'aws-cdk-lib/aws-apigatewayv2-authorizers';import { Runtime } from 'aws-cdk-lib/aws-lambda';
export class GameApi extends HttpApi { constructor(scope: Construct, id: string) { super(scope, id, { defaultAuthorizer: new HttpIamAuthorizer(), apiName: 'GameApi', runtime: Runtime.NODEJS_LATEST, handler: 'index.handler', handlerFilePath: url.fileURLToPath( new URL( '../../../../../../dist/packages/game-api/backend/bundle', import.meta.url, ), ), }); }}
GameApiを定義するCDKコンストラクト。ハンドラーファイルパスは事前バンドル済みパスを指しており、cdk synth
時にバンドリングが発生しません。
ストーリーAPI
Fast APIのStoryApi
を作成します:
- インストール Nx Console VSCode Plugin まだインストールしていない場合
- VSCodeでNxコンソールを開く
- クリック
Generate (UI)
"Common Nx Commands"セクションで - 検索
@aws/nx-plugin - py#fast-api
- 必須パラメータを入力
- name: StoryApi
- クリック
Generate
pnpm nx g @aws/nx-plugin:py#fast-api --name=StoryApi --no-interactive
yarn nx g @aws/nx-plugin:py#fast-api --name=StoryApi --no-interactive
npx nx g @aws/nx-plugin:py#fast-api --name=StoryApi --no-interactive
bunx nx g @aws/nx-plugin:py#fast-api --name=StoryApi --no-interactive
変更されるファイルを確認するためにドライランを実行することもできます
pnpm nx g @aws/nx-plugin:py#fast-api --name=StoryApi --no-interactive --dry-run
yarn nx g @aws/nx-plugin:py#fast-api --name=StoryApi --no-interactive --dry-run
npx nx g @aws/nx-plugin:py#fast-api --name=StoryApi --no-interactive --dry-run
bunx nx g @aws/nx-plugin:py#fast-api --name=StoryApi --no-interactive --dry-run
ファイルツリーに新しいファイルが生成されます。
py#fast-api 更新ファイル
py#fast-api
ジェネレーターが生成した主要ファイル:
Directory.venv/ モノレポ用仮想環境
- …
Directorypackages/
Directorycommon/
Directoryconstructs/
Directorysrc/
Directoryapp/
Directoryhttp-apis/
- story-api.ts Fast API用CDKコンストラクト
- index.ts(新規APIをエクスポートするよう更新)
- project.json(story_apiへのビルド依存関係追加)
Directorytypes/
Directorysrc/
- runtime-config.ts StoryApi追加
Directorystory_api/
Directorystory_api/ Pythonモジュール
- init.py Powertools/FastAPI初期化
- main.py ラムダエントリポイント
Directorytests/
- …
- .python-version
- project.json
- pyproject.toml
- .python-version Pythonバージョン固定
- pyproject.toml
- uv.lock
import { Construct } from 'constructs';import * as url from 'url';import { HttpApi } from '../../core/http-api.js';import { HttpIamAuthorizer } from 'aws-cdk-lib/aws-apigatewayv2-authorizers';import { Runtime } from 'aws-cdk-lib/aws-lambda';
export class StoryApi extends HttpApi { constructor(scope: Construct, id: string) { super(scope, id, { defaultAuthorizer: new HttpIamAuthorizer(), apiName: 'StoryApi', runtime: Runtime.PYTHON_3_12, handler: 'story_api.main.handler', handlerFilePath: url.fileURLToPath( new URL( '../../../../../../dist/packages/story_api/bundle', import.meta.url, ), ), }); }}
StoryApi用CDKコンストラクト。事前バンドル済みパスを使用。
export type ApiUrl = string;export interface IRuntimeConfig { httpApis: { GameApi: ApiUrl; StoryApi: ApiUrl; };}
AST変換により既存コードを保持しつつStoryApi
を追加。フロントエンドで型安全性を確保。
from .init import app, lambda_handler, tracer
handler = lambda_handler
@app.get("/")@tracer.capture_methoddef read_root(): return {"Hello": "World"}
APIメソッド定義場所。Pydanticで入出力を型定義可能。
ゲームUI: Webサイト
ゲーム操作用UIを作成します:
- インストール Nx Console VSCode Plugin まだインストールしていない場合
- VSCodeでNxコンソールを開く
- クリック
Generate (UI)
"Common Nx Commands"セクションで - 検索
@aws/nx-plugin - ts#cloudscape-website
- 必須パラメータを入力
- name: GameUI
- クリック
Generate
pnpm nx g @aws/nx-plugin:ts#cloudscape-website --name=GameUI --no-interactive
yarn nx g @aws/nx-plugin:ts#cloudscape-website --name=GameUI --no-interactive
npx nx g @aws/nx-plugin:ts#cloudscape-website --name=GameUI --no-interactive
bunx nx g @aws/nx-plugin:ts#cloudscape-website --name=GameUI --no-interactive
変更されるファイルを確認するためにドライランを実行することもできます
pnpm nx g @aws/nx-plugin:ts#cloudscape-website --name=GameUI --no-interactive --dry-run
yarn nx g @aws/nx-plugin:ts#cloudscape-website --name=GameUI --no-interactive --dry-run
npx nx g @aws/nx-plugin:ts#cloudscape-website --name=GameUI --no-interactive --dry-run
bunx nx g @aws/nx-plugin:ts#cloudscape-website --name=GameUI --no-interactive --dry-run
ファイルツリーに新しいファイルが生成されます。
ts#cloudscape-website 更新ファイル
ts#cloudscape-website
ジェネレーターが生成した主要ファイル:
Directorypackages/
Directorycommon/
Directoryconstructs/
Directorysrc/
Directoryapp/
Directorystatic-websites/
- game-ui.ts Game UI用CDKコンストラクト
Directorycore/
- static-website.ts 静的Webサイト汎用コンストラクト
Directorygame-ui/
Directorypublic/
- …
Directorysrc/
Directorycomponents/
DirectoryAppLayout/
- index.ts ページレイアウト
- navitems.ts サイドバーナビゲーション
Directoryhooks/
- useAppLayout.tsx ページスタイル動的設定
Directoryroutes/ ファイルベースルーティング
- index.tsx ルートページ
- __root.tsx ベースコンポーネント
Directorywelcome/
- index.tsx
- config.ts
- main.tsx Reactエントリポイント
- routeTree.gen.ts 自動生成ルート定義
- styles.css
- index.html
- project.json
- vite.config.ts
import * as url from 'url';import { Construct } from 'constructs';import { StaticWebsite } from '../../core/index.js';
export class GameUI extends StaticWebsite { constructor(scope: Construct, id: string) { super(scope, id, { websiteFilePath: url.fileURLToPath( new URL( '../../../../../../dist/packages/game-ui/bundle', import.meta.url, ), ), }); }}
Viteビルド成果物を使用するCDKコンストラクト。
import React from 'react';import { createRoot } from 'react-dom/client';import { I18nProvider } from '@cloudscape-design/components/i18n';import messages from '@cloudscape-design/components/i18n/messages/all.en';import { RouterProvider, createRouter } from '@tanstack/react-router';import { routeTree } from './routeTree.gen';
import '@cloudscape-design/global-styles/index.css';
const router = createRouter({ routeTree });
declare module '@tanstack/react-router' { interface Register { router: typeof router; }}
const root = document.getElementById('root');root && createRoot(root).render( <React.StrictMode> <I18nProvider locale="en" messages={[messages]}> <RouterProvider router={router} /> </I18nProvider> </React.StrictMode>, );
Reactエントリポイント。ファイルベースルーティングを採用。
import { ContentLayout, Header, SpaceBetween, Container,} from '@cloudscape-design/components';import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/welcome/')({ component: RouteComponent,});
function RouteComponent() { return ( <ContentLayout header={<Header>Welcome</Header>}> <SpaceBetween size="l"> <Container>Cloudscape Webサイトへようこそ!</Container> </SpaceBetween> </ContentLayout> );}
/welcome
ルート用コンポーネント。
ゲームUI: 認証
Amazon Cognitoによる認証を設定します:
- インストール Nx Console VSCode Plugin まだインストールしていない場合
- VSCodeでNxコンソールを開く
- クリック
Generate (UI)
"Common Nx Commands"セクションで - 検索
@aws/nx-plugin - ts#cloudscape-website#auth
- 必須パラメータを入力
- cognitoDomain: game-ui
- project: @dungeon-adventure/game-ui
- allowSignup: true
- クリック
Generate
pnpm nx g @aws/nx-plugin:ts#cloudscape-website#auth --cognitoDomain=game-ui --project=@dungeon-adventure/game-ui --allowSignup=true --no-interactive
yarn nx g @aws/nx-plugin:ts#cloudscape-website#auth --cognitoDomain=game-ui --project=@dungeon-adventure/game-ui --allowSignup=true --no-interactive
npx nx g @aws/nx-plugin:ts#cloudscape-website#auth --cognitoDomain=game-ui --project=@dungeon-adventure/game-ui --allowSignup=true --no-interactive
bunx nx g @aws/nx-plugin:ts#cloudscape-website#auth --cognitoDomain=game-ui --project=@dungeon-adventure/game-ui --allowSignup=true --no-interactive
変更されるファイルを確認するためにドライランを実行することもできます
pnpm nx g @aws/nx-plugin:ts#cloudscape-website#auth --cognitoDomain=game-ui --project=@dungeon-adventure/game-ui --allowSignup=true --no-interactive --dry-run
yarn nx g @aws/nx-plugin:ts#cloudscape-website#auth --cognitoDomain=game-ui --project=@dungeon-adventure/game-ui --allowSignup=true --no-interactive --dry-run
npx nx g @aws/nx-plugin:ts#cloudscape-website#auth --cognitoDomain=game-ui --project=@dungeon-adventure/game-ui --allowSignup=true --no-interactive --dry-run
bunx nx g @aws/nx-plugin:ts#cloudscape-website#auth --cognitoDomain=game-ui --project=@dungeon-adventure/game-ui --allowSignup=true --no-interactive --dry-run
ファイルツリーが更新されます。
ts#cloudscape-website#auth 更新ファイル
認証関連ファイルの更新内容:
Directorypackages/
Directorycommon/
Directoryconstructs/
Directorysrc/
Directorycore/
- user-identity.ts ユーザーIDプール用CDKコンストラクト
Directorytypes/
Directorysrc/
- runtime-config.ts Cognito設定追加
Directorygame-ui/
Directorysrc/
Directorycomponents/
DirectoryAppLayout/
- index.tsx ヘッダーに認証情報追加
DirectoryCognitoAuth/
- index.ts Cognito認証管理
DirectoryRuntimeConfig/
- index.tsx ランタイム設定取得
Directoryhooks/
- useRuntimeConfig.tsx
- main.tsx Cognito追加
import CognitoAuth from './components/CognitoAuth';import RuntimeConfigProvider from './components/RuntimeConfig';import React from 'react';import { createRoot } from 'react-dom/client';import { I18nProvider } from '@cloudscape-design/components/i18n';import messages from '@cloudscape-design/components/i18n/messages/all.en';import { RouterProvider, createRouter } from '@tanstack/react-router';import { routeTree } from './routeTree.gen';import '@cloudscape-design/global-styles/index.css';const router = createRouter({ routeTree });
declare module '@tanstack/react-router' { interface Register { router: typeof router; }}
const root = document.getElementById('root');root && createRoot(root).render( <React.StrictMode> <I18nProvider locale="en" messages={[messages]}> <RuntimeConfigProvider> <CognitoAuth> <RouterProvider router={router} /> </CognitoAuth> </RuntimeConfigProvider> </I18nProvider> </React.StrictMode>, );
AST変換による認証コンポーネントの追加。
ゲームUI: Story API接続
Story APIへの接続を設定します:
- インストール Nx Console VSCode Plugin まだインストールしていない場合
- VSCodeでNxコンソールを開く
- クリック
Generate (UI)
"Common Nx Commands"セクションで - 検索
@aws/nx-plugin - api-connection
- 必須パラメータを入力
- sourceProject: @dungeon-adventure/game-ui
- targetProject: dungeon_adventure.story_api
- クリック
Generate
pnpm nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=dungeon_adventure.story_api --no-interactive
yarn nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=dungeon_adventure.story_api --no-interactive
npx nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=dungeon_adventure.story_api --no-interactive
bunx nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=dungeon_adventure.story_api --no-interactive
変更されるファイルを確認するためにドライランを実行することもできます
pnpm nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=dungeon_adventure.story_api --no-interactive --dry-run
yarn nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=dungeon_adventure.story_api --no-interactive --dry-run
npx nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=dungeon_adventure.story_api --no-interactive --dry-run
bunx nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=dungeon_adventure.story_api --no-interactive --dry-run
ファイルツリーが更新されます。
UI -> FastAPI接続 更新ファイル
API接続関連ファイルの更新内容:
Directorypackages/
Directorygame-ui/
Directorysrc/
Directoryhooks/
- useSigV4.tsx リクエスト署名用
- useStoryApiClient.tsx APIクライアント生成
- useStoryApi.tsx TanStack Query統合
Directorycomponents/
- QueryClientProvider.tsx TanStack Queryプロバイダー
- StoryApiProvider.tsx APIプロバイダー
- main.tsx プロバイダー追加
- .gitignore 生成ファイル除外
- project.json OpenAPIフック生成ターゲット追加
Directorystory_api/
Directoryscripts/
- generate_open_api.py
- project.json OpenAPI.json生成設定
import { StoryApi } from '../generated/story-api/client.gen';import { useSigV4 } from './useSigV4';import { useRuntimeConfig } from './useRuntimeConfig';import { useMemo } from 'react';
export const useStoryApi = (): StoryApi => { const runtimeConfig = useRuntimeConfig(); const apiUrl = runtimeConfig.httpApis.StoryApi; const sigv4Client = useSigV4(); return useMemo( () => new StoryApi({ url: apiUrl, fetch: sigv4Client, }), [apiUrl, sigv4Client], );};
認証済みAPIリクエスト用フック。ビルド時に生成されるクライアントを使用。
import { createContext, FC, PropsWithChildren, useMemo } from 'react';import { useStoryApiClient } from '../hooks/useStoryApiClient';import { StoryApiOptionsProxy } from '../generated/story-api/options-proxy.gen';
export const StoryApiContext = createContext<StoryApiOptionsProxy | undefined>( undefined,);
export const StoryApiProvider: FC<PropsWithChildren> = ({ children }) => { const client = useStoryApiClient(); const optionsProxy = useMemo( () => new StoryApiOptionsProxy({ client }), [client], );
return ( <StoryApiContext.Provider value={optionsProxy}> {children} </StoryApiContext.Provider> );};
TanStack Queryオプション管理用プロバイダー。
ゲームUI: Game API接続
Game APIへの接続を設定します:
- インストール Nx Console VSCode Plugin まだインストールしていない場合
- VSCodeでNxコンソールを開く
- クリック
Generate (UI)
"Common Nx Commands"セクションで - 検索
@aws/nx-plugin - api-connection
- 必須パラメータを入力
- sourceProject: @dungeon-adventure/game-ui
- targetProject: @dungeon-adventure/game-api-backend
- クリック
Generate
pnpm nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=@dungeon-adventure/game-api-backend --no-interactive
yarn nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=@dungeon-adventure/game-api-backend --no-interactive
npx nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=@dungeon-adventure/game-api-backend --no-interactive
bunx nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=@dungeon-adventure/game-api-backend --no-interactive
変更されるファイルを確認するためにドライランを実行することもできます
pnpm nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=@dungeon-adventure/game-api-backend --no-interactive --dry-run
yarn nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=@dungeon-adventure/game-api-backend --no-interactive --dry-run
npx nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=@dungeon-adventure/game-api-backend --no-interactive --dry-run
bunx nx g @aws/nx-plugin:api-connection --sourceProject=@dungeon-adventure/game-ui --targetProject=@dungeon-adventure/game-api-backend --no-interactive --dry-run
ファイルツリーが更新されます。
UI -> tRPC接続 更新ファイル
tRPC接続関連ファイルの更新内容:
Directorypackages/
Directorygame-ui/
Directorysrc/
Directorycomponents/
DirectoryTrpcClients/
- index.tsx
- TrpcApis.tsx tRPC API設定
- TrpcClientProviders.tsx クライアントプロバイダー
- TrpcProvider.tsx
Directoryhooks/
- useGameApi.tsx Game APIフック
- main.tsx tRPCプロバイダー追加
- package.json
import { TrpcApis } from '../components/TrpcClients';
export const useGameApi = () => TrpcApis.GameApi.useTRPC();
tRPCのReact Query統合を利用。
import TrpcClientProviders from './components/TrpcClients';import QueryClientProvider from './components/QueryClientProvider';import CognitoAuth from './components/CognitoAuth';import RuntimeConfigProvider from './components/RuntimeConfig';import React from 'react';import { createRoot } from 'react-dom/client';import { I18nProvider } from '@cloudscape-design/components/i18n';import messages from '@cloudscape-design/components/i18n/messages/all.en';import { RouterProvider, createRouter } from '@tanstack/react-router';import { routeTree } from './routeTree.gen';import '@cloudscape-design/global-styles/index.css';const router = createRouter({ routeTree });
declare module '@tanstack/react-router' { interface Register { router: typeof router; }}
const root = document.getElementById('root');root && createRoot(root).render( <React.StrictMode> <I18nProvider locale="en" messages={[messages]}> <RuntimeConfigProvider> <CognitoAuth> <QueryClientProvider> <TrpcClientProviders> <RouterProvider router={router} /> </TrpcClientProviders> </QueryClientProvider> </CognitoAuth> </RuntimeConfigProvider> </I18nProvider> </React.StrictMode>, );
tRPCプロバイダーの追加。
ゲームUI: インフラストラクチャ
CDKインフラ用サブプロジェクトを作成します:
- インストール Nx Console VSCode Plugin まだインストールしていない場合
- VSCodeでNxコンソールを開く
- クリック
Generate (UI)
"Common Nx Commands"セクションで - 検索
@aws/nx-plugin - ts#infra
- 必須パラメータを入力
- name: infra
- クリック
Generate
pnpm nx g @aws/nx-plugin:ts#infra --name=infra --no-interactive
yarn nx g @aws/nx-plugin:ts#infra --name=infra --no-interactive
npx nx g @aws/nx-plugin:ts#infra --name=infra --no-interactive
bunx nx g @aws/nx-plugin:ts#infra --name=infra --no-interactive
変更されるファイルを確認するためにドライランを実行することもできます
pnpm nx g @aws/nx-plugin:ts#infra --name=infra --no-interactive --dry-run
yarn nx g @aws/nx-plugin:ts#infra --name=infra --no-interactive --dry-run
npx nx g @aws/nx-plugin:ts#infra --name=infra --no-interactive --dry-run
bunx nx g @aws/nx-plugin:ts#infra --name=infra --no-interactive --dry-run
ファイルツリーが更新されます。
ts#infra 更新ファイル
インフラ関連ファイルの更新内容:
Directorypackages/
Directorycommon/
Directoryconstructs/
Directorysrc/
Directorycore/
Directorycfn-guard-rules/
- *.guard
- cfn-guard.ts
- index.ts
Directoryinfra
Directorysrc/
Directorystacks/
- application-stack.ts CDKリソース定義
- index.ts
- main.ts エントリポイント
- cdk.json
- project.json
- tsconfig.json 参照更新
- tsconfig.base.json エイリアス追加
import { ApplicationStack } from './stacks/application-stack.js';import { App, CfnGuardValidator, RuleSet,} from ':dungeon-adventure/common-constructs';
const app = new App({ policyValidationBeta1: [new CfnGuardValidator(RuleSet.AWS_PROTOTYPING)],});
new ApplicationStack(app, 'dungeon-adventure-infra-sandbox', { env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION, }, crossRegionReferences: true,});
app.synth();
CDKアプリケーションエントリポイント。cfn-guard
を使用したインフラ検証。
import * as cdk from 'aws-cdk-lib';import { Construct } from 'constructs';
export class ApplicationStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props);
// スタック定義コード }}
インフラリソース定義用スタック。
インフラストラクチャの更新
application-stack.ts
を以下のように更新します:
import { GameApi, GameUI, StoryApi, UserIdentity,} from ':dungeon-adventure/common-constructs';import * as cdk from 'aws-cdk-lib';import { Construct } from 'constructs';
export class ApplicationStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props);
const userIdentity = new UserIdentity(this, 'UserIdentity');
const gameApi = new GameApi(this, 'GameApi'); const storyApi = new StoryApi(this, 'StoryApi');
[storyApi, gameApi].forEach((api) => api.grantInvokeAccess(userIdentity.identityPool.authenticatedRole), );
new GameUI(this, 'GameUI'); }}
コードのビルド
Nxコマンド
単一/複数ターゲット実行
run-many
コマンドで全サブプロジェクトのビルド:
pnpm nx run-many --target build --all
yarn nx run-many --target build --all
npx nx run-many --target build --all
bunx nx run-many --target build --all
単一プロジェクトのビルド例:
pnpm nx run @dungeon-adventure/infra:build
yarn nx run @dungeon-adventure/infra:build
npx nx run @dungeon-adventure/infra:build
bunx nx run @dungeon-adventure/infra:build
依存関係の可視化
pnpm nx graph
yarn nx graph
npx nx graph
bunx nx graph

キャッシュ管理
キャッシュ無効化:
pnpm nx run @dungeon-adventure/infra:build --skip-nx-cache
yarn nx run @dungeon-adventure/infra:build --skip-nx-cache
npx nx run @dungeon-adventure/infra:build --skip-nx-cache
bunx nx run @dungeon-adventure/infra:build --skip-nx-cache
キャッシュクリア:
pnpm nx reset
yarn nx reset
npx nx reset
bunx nx reset
pnpm nx run-many --target build --all
yarn nx run-many --target build --all
npx nx run-many --target build --all
bunx nx run-many --target build --all
以下のプロンプトが表示されます:
NX ワークスペースが同期されていません
[@nx/js:typescript-sync]: TypeScript設定ファイルにプロジェクト参照が不足しています
? 同期してタスクを実行しますか? …はい、同期してタスクを実行いいえ、同期せずに実行
**「はい、同期してタスクを実行」**を選択してください。TypeScript参照が自動設定され、IDEエラーが解消されます。
ビルド成果物はdist/
フォルダに生成されます。クリーンアップ時はdist/
を削除してください。
おめでとうございます!ダンジョンアドベンチャーゲームのコア実装に必要な全サブプロジェクトの作成が完了しました。🎉🎉🎉