跳转到内容

React 网站

Filter this guidePick generator option values to hide sections that don't apply.

此生成器创建一个新的 React 网站,默认配置了 shadcn/ui,以及用于将网站部署到云端的 AWS CDK 或 Terraform 基础设施,作为托管在 S3 中的静态网站,由 CloudFront 提供服务,并受 WAF 保护。

生成的应用程序使用 Vite 作为构建工具和打包器。它使用 TanStack Router 进行类型安全的路由。

您可以通过两种方式生成新的 React 网站:

Terminal window
pnpm nx g @aws/nx-plugin:ts#website --framework=react
您还可以执行试运行以查看哪些文件会被更改
Terminal window
pnpm nx g @aws/nx-plugin:ts#website --framework=react --dry-run
参数类型默认值描述
name 必需string-应用程序的名称。
framework reactreact要使用的前端框架。
directory stringpackages新应用程序的目录。
subDirectory string-项目所在的子目录。默认情况下为项目名称。
ux none | cloudscape | shadcnshadcn首选的 UX 提供商。
tailwind booleantrue启用 TailwindCSS 以实现实用优先的样式设计。
tanstackRouter booleantrue启用 Tanstack router 以实现类型安全的路由。
infra cloudfront-s3 | nonecloudfront-s3用于部署网站的基础设施类型。
iac inherit | cdk | terraforminherit首选的 IaC 提供商。默认情况下,这将继承您的初始选择。
preferInstallDependencies booleantrue是否在生成器运行后优先安装依赖项。设置为 false 可在批量运行多个生成器时延迟安装(如果后续生成器需要计算 Nx 项目图,仍会运行安装);在最后统一安装一次。

生成器将在 <directory>/<name> 目录中创建以下项目结构:

  • index.html HTML 入口点
  • public 静态资源
  • 文件夹src
    • main.tsx 应用程序入口点,包含 React 设置
    • config.ts 应用程序配置(例如 logo)
    • 文件夹components
      • AppLayout 整体布局和导航栏的组件
    • 文件夹hooks
      • useAppLayout.tsx 用于从嵌套组件调整 AppLayout 的钩子(仅限 Cloudscape)
    • 文件夹routes
      • index.tsx TanStack Router 的示例路由(或页面)
    • styles.css 全局样式
  • vite.config.mts Vite 和 Vitest 配置
  • tsconfig.json 源代码和测试的基础 TypeScript 配置
  • tsconfig.app.json 源代码的 TypeScript 配置
  • tsconfig.spec.json 测试的 TypeScript 配置
  • package.json 定义项目包名称和依赖项的项目清单

由于此生成器根据您选择的 iac 提供基础设施即代码,它将在 packages/common 中创建一个项目,其中包含相关的 CDK 构造或 Terraform 模块。

通用基础设施即代码项目的结构如下:

  • 文件夹packages/common/constructs
    • 文件夹src
      • 文件夹app/ Constructs for infrastructure specific to a project/generator
      • 文件夹core/ Generic constructs which are reused by constructs in app
      • index.ts Entry point exporting constructs from app
    • project.json Project build targets and configuration

生成器根据您选择的 iac 创建用于部署网站的基础设施即代码:

  • 文件夹packages/common/constructs/src
    • 文件夹app
      • 文件夹static-websites
        • <name>.ts 特定于您网站的基础设施
    • 文件夹core
      • static-website.ts 通用 StaticWebsite 构造

部署的网站具有以下架构:

Web BrowserWAFCloudFrontStatic Assets(S3)

React 文档是学习使用 React 构建的基础知识的好地方。

ux = cloudscape

您可以参考 Cloudscape 文档了解可用组件的详细信息以及如何使用它们。

ux = shadcn

您可以参考 shadcn/ui 文档了解可用组件的详细信息以及如何使用它们。

您的网站默认配置了 TanStack Router。这使得添加新路由变得容易:

  1. 运行本地开发服务器
  2. src/routes 中创建一个新的 <page-name>.tsx 文件,其在文件树中的位置代表路径
  3. 注意 RouteRouteComponent 会自动为您生成。您可以在这里开始构建您的页面!

您可以使用 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 文档。

React 网站生成器根据您选择的 iac 创建 CDK 或 Terraform 基础设施即代码。您可以使用它来部署您的网站。

要部署您的网站,我们建议使用 ts#infra 生成器创建 CDK 应用程序。

您可以使用在 packages/common/constructs 中为您生成的 CDK 构造来部署您的网站。

packages/infra/src/stacks/application-stack.ts
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');
}
}

这将设置:

  1. 用于托管静态网站文件的 S3 存储桶
  2. 用于全球内容分发的 CloudFront 分配
  3. 用于安全保护的 WAF Web ACL
  4. 用于安全 S3 访问的源访问控制
  5. 自动部署网站文件和运行时配置

CloudFront 分配应用响应标头策略,在所有响应上设置 Strict-Transport-SecurityX-Content-Type-OptionsX-Frame-Options: DENYReferrer-PolicyContent-Security-Policy

强制执行默认的 Content-Security-Policy。它限制脚本和框架以减轻 XSS 和点击劫持,同时允许 HTTPS 和 WSS 连接,以便网站可以调用 AWS 服务端点(如 API Gateway、Cognito 和 Bedrock AgentCore),这些 URL 仅在部署时才知道。要调整策略(例如将 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 托管的默认规则集(AWSManagedRulesCommonRuleSetAWSManagedRulesKnownBadInputsRuleSet),提供针对常见 Web 漏洞(包括 OWASP Top 10)的保护。

要选择退出,在创建网站时将 enableWaf 设置为 false

packages/infra/src/stacks/application-stack.ts
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',
);
}
}

网站存储桶、CloudFront 分配日志存储桶以及接收其服务器访问日志的 CloudWatch Logs 组默认使用客户管理的 AWS KMS 密钥进行加密。此密钥会自动为您创建,并启用密钥轮换。

如果您想使用不同的加密配置,请在创建网站时传递 encryptionencryptionKeyenableKeyRotation 属性:

packages/infra/src/stacks/application-stack.ts
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)仅适用于自动创建的密钥,即当 encryptionBucketEncryption.KMS(默认值)且未提供 encryptionKey 时:

new MyWebsite(this, 'MyWebsite', {
enableKeyRotation: false,
});

默认情况下,分配使用默认的 CloudFront 域名(*.cloudfront.net)及其默认证书,不支持强制执行最低 TLS 版本 1.2。要从您自己的域名提供网站服务,请提供 ACM 证书(必须位于 us-east-1 才能与 CloudFront 一起使用)和您的域名。然后为查看者强制执行最低 TLS 版本 1.2:

在创建网站时传递 certificatedomainNames 属性:

packages/infra/src/stacks/application-stack.ts
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/...'),
});
}
}

您还需要创建 DNS 记录(例如在 Route 53 中)将您的域名指向 CloudFront 分配。

来自基础设施的配置通过运行时配置提供给您的网站。这允许您的网站访问诸如 API URL 之类的详细信息,这些信息在应用程序部署之前是未知的。

RuntimeConfig CDK 构造可用于在 CDK 基础设施中添加和检索配置。由 @aws/nx-plugin 生成器生成的 CDK 构造(如 ts#apipy#api)将自动向 RuntimeConfig 添加适当的值。

您的网站 CDK 构造将把运行时配置的 connection 命名空间作为 runtime-config.json 文件部署到 S3 存储桶的根目录。

packages/infra/src/stacks/application-stack.ts
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(),
});
}
}

在您的网站中,您可以使用 useRuntimeConfig 钩子从运行时配置中检索值:

import { useRuntimeConfig } from '../hooks/useRuntimeConfig';
const MyComponent = () => {
const runtimeConfig = useRuntimeConfig();
// Access values in the runtime config here
const apiUrl = runtimeConfig.apis.MyApi;
};

运行本地开发服务器时,您需要在 public 目录中有一个 runtime-config.json 文件,以便本地网站知道后端 URL、身份配置等。

您的网站项目配置了一个 load-runtime-config 目标,您可以使用它从已部署的应用程序中拉取 runtime-config.json 文件:

Terminal window
pnpm nx load-runtime-config <my-website>

本地开发的规范命令是 dev,它使用一个命令启动您的网站(以及您连接到它的任何 API 的本地服务器):

Terminal window
pnpm nx dev <my-website>

当您需要控制应用程序的多少部分在本地运行与指向已部署的 AWS 基础设施时,serve 目标也可用。有关跨连接项目的本地开发的更广泛概述,包括 dev 如何为具有多个组件的项目运行,请参阅本地开发指南。

serve 目标为您的网站启动本地开发服务器。此目标要求您已部署网站交互的任何支持基础设施,并已加载本地运行时配置

您可以使用以下命令运行此目标:

Terminal window
pnpm nx serve <my-website>

此目标对于在指向”真实”已部署的 API 和其他基础设施时处理网站更改很有用。

dev 目标为您的网站启动本地开发服务器(Vite MODE 设置为 local-dev),并为您通过连接生成器连接到网站的任何 API 启动本地服务器。

当您的本地网站服务器通过此目标运行时,runtime-config.json 会自动覆盖以指向您本地运行的 API URL。

您可以使用以下命令运行此目标:

Terminal window
pnpm nx dev <my-website>

当您跨网站和 API 工作并希望快速迭代而无需部署基础设施时,此目标很有用。

模拟身份验证

在此模式下运行且不存在 runtime-config.json 时,如果您已配置 Cognito 身份验证(通过 ts#website#auth 生成器),将跳过登录,并且对本地服务器的请求将不包含身份验证标头。

要为 dev 启用登录和身份验证,请部署您的基础设施并加载运行时配置。

您可以使用 build 目标构建您的网站。这会运行 bundlecompiletestlint 目标,对您的网站进行类型检查、打包、测试和 lint。

Terminal window
pnpm nx build <my-website>

bundle 目标使用 Vite 在根 dist/packages/<my-website>/bundle 目录中创建生产包。这是您的网站基础设施使用的可部署工件。您可以单独运行它:

Terminal window
pnpm nx bundle <my-website>

测试您的网站与在标准 TypeScript 项目中编写测试非常相似,因此请参阅 TypeScript 项目指南了解更多详细信息。

对于 React 特定的测试,React Testing Library 已经安装并可供您使用来编写测试。有关其用法的更多详细信息,请参阅 React Testing Library 文档

您可以使用 test 目标运行测试:

Terminal window
pnpm nx test <my-website>

使用 connection 生成器将此项目与工作区中的其他项目集成。以下连接涉及此项目:

tRPC
React 到 tRPC从 React 网站调用 tRPC API
FastAPI
React 到 FastAPI从 React 网站调用 Python FastAPI
Smithy
React 到 Smithy API从 React 网站调用 Smithy API
Strands AgentsPython
React 到 Python Agent从 React 网站调用 Python Agent
Strands AgentsTypeScript
React 到 TypeScript Agent从 React 网站调用 TypeScript Agent
CopilotKit
React 到 AG-UI Agent通过 CopilotKit 从 React 网站调用公开 AG-UI 协议的 Agent
Amazon Bedrock AgentCore Gateway
React 网站到 AgentCore Gateway通过 AgentCore Gateway 将 React 网站连接到代理