React Website
このジェネレーターは、デフォルトでshadcn/uiが設定された新しいReactウェブサイトと、S3でホストされ、CloudFrontで配信され、WAFで保護される静的ウェブサイトとしてクラウドにデプロイするためのAWS CDKまたはTerraformインフラストラクチャを作成します。
生成されたアプリケーションは、ビルドツールおよびバンドラーとしてViteを使用します。型安全なルーティングにはTanStack Routerを使用します。
React Websiteの生成
Section titled “React Websiteの生成”新しいReact Websiteは2つの方法で生成できます:
pnpm nx g @aws/nx-plugin:ts#website --framework=reactyarn nx g @aws/nx-plugin:ts#website --framework=reactnpx nx g @aws/nx-plugin:ts#website --framework=reactbunx nx g @aws/nx-plugin:ts#website --framework=react変更されるファイルを確認するためにドライランを実行することもできます
pnpm nx g @aws/nx-plugin:ts#website --framework=react --dry-runyarn nx g @aws/nx-plugin:ts#website --framework=react --dry-runnpx nx g @aws/nx-plugin:ts#website --framework=react --dry-runbunx nx g @aws/nx-plugin:ts#website --framework=react --dry-run- インストール Nx Console VSCode Plugin まだインストールしていない場合
- VSCodeでNxコンソールを開く
- クリック
Generate (UI)"Common Nx Commands"セクションで - 検索
@aws/nx-plugin - ts#website - 必須パラメータを入力
- framework: react
- クリック
Generate
| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
| name 必須 | string | - | アプリケーションの名前。 |
| framework | react | react | 使用するフロントエンドフレームワーク。 |
| directory | string | packages | 新しいアプリケーションのディレクトリ。 |
| subDirectory | string | - | プロジェクトが配置されるサブディレクトリ。デフォルトではプロジェクト名になります。 |
| ux | none | cloudscape | shadcn | shadcn | 優先するUXプロバイダー。 |
| tailwind | boolean | true | ユーティリティファーストのスタイリングのためにTailwindCSSを有効にします。 |
| tanstackRouter | boolean | true | 型安全なルーティングのためにTanstackルーターを有効にします。 |
| infra | cloudfront-s3 | none | cloudfront-s3 | ウェブサイトをデプロイするインフラストラクチャのタイプ。 |
| iac | inherit | cdk | terraform | inherit | 優先するIaCプロバイダー。デフォルトでは、初期選択から継承されます。 |
| preferInstallDependencies | boolean | true | ジェネレーター実行後に依存関係のインストールを優先するかどうか。複数のジェネレーターをバッチ処理する際にインストールを延期する場合はfalseに設定します(後続のジェネレーターがNxプロジェクトグラフを計算できるよう、必要に応じてインストールは実行されます)。最後に一度だけインストールします。 |
ジェネレーターの出力
Section titled “ジェネレーターの出力”ジェネレーターは<directory>/<name>ディレクトリに以下のプロジェクト構造を作成します:
- index.html HTMLエントリーポイント
- public 静的アセット
Directorysrc
- main.tsx Reactセットアップを含むアプリケーションエントリーポイント
- config.ts アプリケーション設定(例:ロゴ)
Directorycomponents
- AppLayout 全体のレイアウトとナビゲーションバーのコンポーネント
Directoryhooks
- useAppLayout.tsx ネストされたコンポーネントからAppLayoutを調整するためのフック(Cloudscapeのみ)
Directoryroutes
- index.tsx TanStack Routerのルート(またはページ)の例
- styles.css グローバルスタイル
- vite.config.mts ViteとVitestの設定
- tsconfig.json ソースとテストのベースTypeScript設定
- tsconfig.app.json ソースコード用のTypeScript設定
- tsconfig.spec.json テスト用のTypeScript設定
- package.json プロジェクトのパッケージ名と依存関係を定義するプロジェクトマニフェスト
インフラストラクチャ
Section titled “インフラストラクチャ”このジェネレーターは、選択した iac に基づいてインフラストラクチャをコードとして提供するため、関連する CDK コンストラクトまたは Terraform モジュールを含む packages/common にプロジェクトを作成します。
共通のインフラストラクチャコードプロジェクトは、次のように構成されています:
Directorypackages/common/constructs
Directorysrc
Directoryapp/ プロジェクト/ジェネレーター固有のインフラストラクチャ用のコンストラクト
- …
Directorycore/
app内のコンストラクトによって再利用される汎用コンストラクト- …
- index.ts
appからコンストラクトをエクスポートするエントリーポイント
- project.json プロジェクトのビルドターゲットと設定
Directorypackages/common/terraform
Directorysrc
Directoryapp/ プロジェクト/ジェネレーター固有のインフラストラクチャ用の Terraform モジュール
- …
Directorycore/
app内のモジュールによって再利用される汎用モジュール- …
- project.json プロジェクトのビルドターゲットと設定
ジェネレーターは、選択したiacに基づいてウェブサイトをデプロイするためのコードとしてのインフラストラクチャを作成します:
Directorypackages/common/constructs/src
Directoryapp
Directorystatic-websites
- <name>.ts ウェブサイト固有のインフラストラクチャ
Directorycore
- static-website.ts 汎用StaticWebsiteコンストラクト
Directorypackages/common/terraform/src
Directoryapp
Directorystatic-websites
Directory<name>
- <name>.tf ウェブサイト固有のモジュール
Directorycore
Directorystatic-website
- static-website.tf 汎用静的ウェブサイトモジュール
アーキテクチャ
Section titled “アーキテクチャ”デプロイされたウェブサイトは以下のアーキテクチャを持ちます:
ウェブサイトの実装
Section titled “ウェブサイトの実装”Reactドキュメントは、Reactでの構築の基本を学ぶための良い出発点です。
利用可能なコンポーネントとその使用方法の詳細については、Cloudscapeドキュメントを参照してください。
利用可能なコンポーネントとその使用方法の詳細については、shadcn/uiドキュメントを参照してください。
ルート/ページの作成
Section titled “ルート/ページの作成”ウェブサイトにはデフォルトでTanStack Routerが設定されています。これにより、新しいルートを簡単に追加できます:
- ローカル開発サーバーを実行
src/routesに新しい<page-name>.tsxファイルを作成します。ファイルツリー内の位置がパスを表しますRouteとRouteComponentが自動的に生成されることに注目してください。ここでページの構築を開始できます!
ページ間のナビゲーション
Section titled “ページ間のナビゲーション”ページ間を移動するには、LinkコンポーネントまたはuseNavigateフックを使用できます:
import { Link, useNavigate } from '@tanstack/react-router';
export const MyComponent = () => { const navigate = useNavigate();
const submit = async () => { const id = await ... // Use `navigate` for redirecting after some asynchronous action navigate({ to: '/products/$id', { params: { id }} }); };
return ( <> <Link to="/products">Cancel</Link> <Button onClick={submit}>Submit</Button> </> )};詳細については、TanStack Routerドキュメントを確認してください。
ウェブサイトのデプロイ
Section titled “ウェブサイトのデプロイ”React websiteジェネレーターは、選択したiacに基づいてCDKまたはTerraformのコードとしてのインフラストラクチャを作成します。これを使用してウェブサイトをデプロイできます。
ウェブサイトをデプロイするには、ts#infraジェネレーターを使用してCDKアプリケーションを作成することをお勧めします。
packages/common/constructsに生成されたCDKコンストラクトを使用してウェブサイトをデプロイできます。
import { Stack } from 'aws-cdk-lib';import { Construct } from 'constructs';import { MyWebsite } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack { constructor(scope: Construct, id: string) { super(scope, id);
new MyWebsite(this, 'MyWebsite'); }}これにより以下が設定されます:
- 静的ウェブサイトファイルをホストするためのS3バケット
- グローバルコンテンツ配信のためのCloudFrontディストリビューション
- セキュリティ保護のためのWAF Web ACL
- 安全なS3アクセスのためのOrigin Access Control
- ウェブサイトファイルとランタイム設定の自動デプロイ
ウェブサイトをデプロイするには、terraform#projectジェネレーターを使用してTerraformプロジェクトを作成することをお勧めします。
packages/common/terraformに生成されたTerraformモジュールを使用してウェブサイトをデプロイできます。
# Deploy websitemodule "my_website" { source = "../../common/terraform/src/app/static-websites/my-website"
providers = { aws.us_east_1 = aws.us_east_1 }}これにより以下が設定されます:
- 静的ウェブサイトファイルをホストするためのS3バケット
- グローバルコンテンツ配信のためのCloudFrontディストリビューション
- セキュリティ保護のためのWAF Web ACL(us-east-1にデプロイ)
- 安全なS3アクセスのためのOrigin Access Control
- ウェブサイトファイルとランタイム設定の自動デプロイ
セキュリティヘッダー
Section titled “セキュリティヘッダー”CloudFrontディストリビューションは、すべてのレスポンスにStrict-Transport-Security、X-Content-Type-Options、X-Frame-Options: DENY、Referrer-Policy、およびContent-Security-Policyを設定するレスポンスヘッダーポリシーを適用します。
デフォルトのContent-Security-Policyが適用されます。これは、XSSやクリックジャッキングを軽減するためにスクリプトとフレーミングを制限しながら、ウェブサイトがデプロイ時にのみURLが判明するAWSサービスエンドポイント(API Gateway、Cognito、Bedrock AgentCoreなど)を呼び出せるようにHTTPSおよびWSS接続を許可します。ポリシーを調整する(例えば、connect-srcを特定のオリジンに絞り込む)には、生成されたstatic-website.ts(CDK)またはstatic-website.tf(Terraform)のcontent_security_policy値を編集してください。
runtime-config.jsonはCache-Control: no-cacheで提供されるため、ブラウザは再デプロイ後に古いキャッシュされたコピーを使用するのではなく、常に最新の設定を取得します。
CloudFrontディストリビューションは、デフォルトでAWS WAFv2 Web ACLによって保護されています。Web ACLは、AWSマネージドデフォルトルールセット(AWSManagedRulesCommonRuleSetおよびAWSManagedRulesKnownBadInputsRuleSet)を使用し、OWASP Top 10を含む一般的なWebエクスプロイトに対する保護を提供します。
オプトアウトするには、ウェブサイトを作成する際にenableWafをfalseに設定します:
import { Stack } from 'aws-cdk-lib';import { Construct } from 'constructs';import { MyWebsite, suppressRules } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack { constructor(scope: Construct, id: string) { super(scope, id);
const website = new MyWebsite(this, 'MyWebsite', { enableWaf: false, });
// Disabling WAF fails the checkov CKV_AWS_68 check ("CloudFront // Distribution should have WAF enabled"). Suppress it explicitly. suppressRules( website.cloudFrontDistribution, ['CKV_AWS_68'], 'WAF is intentionally disabled for this distribution', ); }}オプトアウトするには、enable_wafをfalseに設定します:
module "my_website" { source = "../../common/terraform/src/app/static-websites/my-website"
providers = { aws.us_east_1 = aws.us_east_1 } enable_waf = false}バケット暗号化
Section titled “バケット暗号化”ウェブサイトバケット、CloudFrontディストリビューションログバケット、およびそれらのサーバーアクセスログを受信するCloudWatch Logsグループは、デフォルトで顧客管理のAWS KMSキーで暗号化されます。このキーは自動的に作成され、キーローテーションが有効になっています。
異なる暗号化設定を使用する場合は、ウェブサイトを作成する際にencryption、encryptionKey、およびenableKeyRotationプロパティを渡します:
import { Stack } from 'aws-cdk-lib';import { Construct } from 'constructs';import { BucketEncryption } from 'aws-cdk-lib/aws-s3';import { MyWebsite } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack { constructor(scope: Construct, id: string) { super(scope, id);
new MyWebsite(this, 'MyWebsite', { encryption: BucketEncryption.S3_MANAGED, }); }}自動的に作成されるキーの代わりに独自のKMSキーを使用するには、encryptionKeyを渡します:
new MyWebsite(this, 'MyWebsite', { encryptionKey: myKey,});enableKeyRotation(デフォルトtrue)は、自動的に作成されたキーにのみ適用されます。つまり、encryptionがBucketEncryption.KMS(デフォルト)で、encryptionKeyが提供されていない場合です:
new MyWebsite(this, 'MyWebsite', { enableKeyRotation: false,});異なる暗号化設定を使用する場合は、encryption、kms_key_arn、create_kms_key、およびenable_key_rotation変数を設定します:
module "my_website" { source = "../../common/terraform/src/app/static-websites/my-website"
providers = { aws.us_east_1 = aws.us_east_1 } encryption = "S3_MANAGED"}自動的に作成されるキーの代わりに独自のKMSキーを使用するには、kms_key_arnを渡し、create_kms_keyをfalseに設定します:
module "my_website" { source = "../../common/terraform/src/app/static-websites/my-website"
providers = { aws.us_east_1 = aws.us_east_1 } kms_key_arn = aws_kms_key.website.arn create_kms_key = false}顧客提供のキーは、独自のキーポリシーでCloudWatch Logs、S3、CloudFrontサービスプリンシパルに必要な権限を既に付与している必要があります。
enable_key_rotation(デフォルトtrue)は、自動的に作成されたキーにのみ適用されます。つまり、encryptionが"KMS"(デフォルト)で、create_kms_keyがtrueの場合です:
module "my_website" { source = "../../common/terraform/src/app/static-websites/my-website"
providers = { aws.us_east_1 = aws.us_east_1 } enable_key_rotation = false}カスタムドメインとTLS
Section titled “カスタムドメインとTLS”デフォルトでは、ディストリビューションはデフォルトのCloudFrontドメイン名(*.cloudfront.net)とそのデフォルト証明書を使用します。これは最小TLSバージョン1.2の強制をサポートしていません。独自のドメインからウェブサイトを提供するには、ACM証明書(CloudFrontで使用するにはus-east-1に存在する必要があります)とドメイン名を提供します。その後、ビューアーに対して最小TLSバージョン1.2が強制されます:
ウェブサイトを作成する際にcertificateとdomainNamesプロパティを渡します:
import { Stack } from 'aws-cdk-lib';import { Construct } from 'constructs';import { Certificate } from 'aws-cdk-lib/aws-certificatemanager';import { MyWebsite } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack { constructor(scope: Construct, id: string) { super(scope, id);
new MyWebsite(this, 'MyWebsite', { domainNames: ['www.example.com'], certificate: Certificate.fromCertificateArn(this, 'Cert', 'arn:aws:acm:us-east-1:123456789012:certificate/...'), }); }}custom_domain_namesとacm_certificate_arn変数を設定します:
module "my_website" { source = "../../common/terraform/src/app/static-websites/my-website"
providers = { aws.us_east_1 = aws.us_east_1 } custom_domain_names = ["www.example.com"] acm_certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/..."}また、CloudFrontディストリビューションを指すDNSレコード(例:Route 53)を作成する必要があります。
ランタイム設定
Section titled “ランタイム設定”インフラストラクチャからの設定は、ランタイム設定を介してウェブサイトに提供されます。これにより、ウェブサイトはアプリケーションがデプロイされるまで不明なAPI URLなどの詳細にアクセスできます。
インフラストラクチャ
Section titled “インフラストラクチャ”RuntimeConfig CDKコンストラクトを使用して、CDKインフラストラクチャで設定を追加および取得できます。@aws/nx-pluginジェネレーター(ts#apiやpy#apiなど)によって生成されたCDKコンストラクトは、自動的に適切な値をRuntimeConfigに追加します。
ウェブサイトCDKコンストラクトは、ランタイム設定のconnection名前空間をruntime-config.jsonファイルとしてS3バケットのルートにデプロイします。
import { Stack } from 'aws-cdk-lib';import { Construct } from 'constructs';import { MyWebsite, MyApi } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack { constructor(scope: Construct, id: string) { super(scope, id);
// Website can be declared at any point, since runtime config is resolved lazily new MyWebsite(this, 'MyWebsite');
// Automatically adds values to the RuntimeConfig new MyApi(this, 'MyApi', { integrations: MyApi.defaultIntegrations(this).build(), }); }}Terraformでは、ランタイム設定はruntime-configモジュールを通じて管理されます。@aws/nx-pluginジェネレーター(ts#apiやpy#apiなど)によって生成されたTerraformモジュールは、自動的に適切な値をランタイム設定に追加します。
ウェブサイトTerraformモジュールは、ランタイム設定のconnection名前空間をruntime-config.jsonファイルとしてS3バケットのルートにデプロイします。
module "asset_bucket" { source = "../../common/terraform/src/core/asset-bucket"}
# Automatically adds values to runtime configmodule "my_api" { source = "../../common/terraform/src/app/apis/my-api"
asset_bucket_name = module.asset_bucket.bucket_name}
# Automatically deploys the runtime config to runtime-config.jsonmodule "my_website" { source = "../../common/terraform/src/app/static-websites/my-website"
providers = { aws.us_east_1 = aws.us_east_1 }
# Ensure API is deployed first to add to runtime config depends_on = [module.my_api]}ウェブサイトコード
Section titled “ウェブサイトコード”ウェブサイトでは、useRuntimeConfigフックを使用してランタイム設定から値を取得できます:
import { useRuntimeConfig } from '../hooks/useRuntimeConfig';
const MyComponent = () => { const runtimeConfig = useRuntimeConfig();
// Access values in the runtime config here const apiUrl = runtimeConfig.apis.MyApi;};ローカルランタイム設定
Section titled “ローカルランタイム設定”ローカル開発サーバーを実行する場合、ローカルウェブサイトがバックエンドURL、ID設定などを知るために、publicディレクトリにruntime-config.jsonファイルが必要です。
ウェブサイトプロジェクトには、デプロイされたアプリケーションからruntime-config.jsonファイルをダウンロードするために使用できるload-runtime-configターゲットが設定されています:
pnpm nx load-runtime-config <my-website>yarn nx load-runtime-config <my-website>npx nx load-runtime-config <my-website>bunx nx load-runtime-config <my-website>ローカル開発サーバー
Section titled “ローカル開発サーバー”ローカル開発の標準的なコマンドはdevで、1つのコマンドでウェブサイト(および接続したAPIのローカルサーバー)を起動します:
pnpm nx dev <my-website>yarn nx dev <my-website>npx nx dev <my-website>bunx nx dev <my-website>serveターゲットは、デプロイされたAWSインフラストラクチャを指すのではなく、アプリケーションのどの部分をローカルで実行するかを制御する必要がある場合にも利用できます。複数のコンポーネントを持つプロジェクト全体でのローカル開発の広範な概要(devが複数のコンポーネントでどのように動作するかを含む)については、ローカル開発ガイドを参照してください。
Serveターゲット
Section titled “Serveターゲット”serveターゲットは、ウェブサイトのローカル開発サーバーを起動します。このターゲットでは、ウェブサイトが対話するサポートインフラストラクチャをデプロイし、ローカルランタイム設定をロードしている必要があります。
このターゲットは以下のコマンドで実行できます:
pnpm nx serve <my-website>yarn nx serve <my-website>npx nx serve <my-website>bunx nx serve <my-website>このターゲットは、「実際の」デプロイされたAPIやその他のインフラストラクチャを指しながらウェブサイトの変更を行う場合に便利です。
Devターゲット
Section titled “Devターゲット”devターゲットは、ウェブサイトのローカル開発サーバー(Vite MODEをlocal-devに設定)を起動し、Connectionジェネレーターを介してウェブサイトに接続したAPIのローカルサーバーも起動します。
このターゲットを介してローカルウェブサイトサーバーを実行すると、runtime-config.jsonは自動的にローカルで実行されているAPI URLを指すようにオーバーライドされます。
このターゲットは以下のコマンドで実行できます:
pnpm nx dev <my-website>yarn nx dev <my-website>npx nx dev <my-website>bunx nx dev <my-website>このターゲットは、ウェブサイトとAPIを横断して作業し、インフラストラクチャをデプロイせずに迅速に反復したい場合に便利です。
モック認証
このモードで実行され、runtime-config.jsonが存在しない場合、Cognito認証を設定している場合(ts#website#authジェネレーター経由)、ログインはスキップされ、ローカルサーバーへのリクエストには認証ヘッダーが含まれません。
devでログインと認証を有効にするには、インフラストラクチャをデプロイしてランタイム設定をロードしてください。
buildターゲットを使用してウェブサイトをビルドできます。これにより、bundle、compile、test、およびlintターゲットが実行され、ウェブサイトの型チェック、バンドル、テスト、およびリントが行われます。
pnpm nx build <my-website>yarn nx build <my-website>npx nx build <my-website>bunx nx build <my-website>bundleターゲットは、Viteを使用してルートdist/packages/<my-website>/bundleディレクトリに本番バンドルを作成します。これは、ウェブサイトインフラストラクチャによって消費されるデプロイ可能なアーティファクトです。単独で実行できます:
pnpm nx bundle <my-website>yarn nx bundle <my-website>npx nx bundle <my-website>bunx nx bundle <my-website>ウェブサイトのテストは、標準的なTypeScriptプロジェクトでのテストの記述とよく似ているため、詳細についてはTypeScriptプロジェクトガイドを参照してください。
React固有のテストについては、React Testing Libraryが既にインストールされており、テストを記述するために使用できます。使用方法の詳細については、React Testing Libraryドキュメントを参照してください。
testターゲットを使用してテストを実行できます:
pnpm nx test <my-website>yarn nx test <my-website>npx nx test <my-website>bunx nx test <my-website>connectionジェネレーターを使用して、このプロジェクトをワークスペース内の他のプロジェクトと統合します。このプロジェクトに関連する接続は以下の通りです:
