Sito Web React
Questo generatore crea un nuovo sito web React con shadcn/ui configurato di default, insieme all’infrastruttura AWS CDK o Terraform per distribuire il tuo sito web nel cloud come sito web statico ospitato in S3, servito da CloudFront e protetto da WAF.
L’applicazione generata utilizza Vite come strumento di build e bundler. Utilizza TanStack Router per il routing type-safe.
Utilizzo
Sezione intitolata “Utilizzo”Generare un sito web React
Sezione intitolata “Generare un sito web React”Puoi generare un nuovo sito web React in due modi:
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=reactPuoi anche eseguire una prova per vedere quali file verrebbero modificati
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- Installa il Nx Console VSCode Plugin se non l'hai già fatto
- Apri la console Nx in VSCode
- Clicca su
Generate (UI)nella sezione "Common Nx Commands" - Cerca
@aws/nx-plugin - ts#website - Compila i parametri richiesti
- framework: react
- Clicca su
Generate
Opzioni
Sezione intitolata “Opzioni”| Parametro | Tipo | Predefinito | Descrizione |
|---|---|---|---|
| name Obbligatorio | string | - | Il nome dell'applicazione. |
| framework | react | react | Il framework frontend da utilizzare. |
| directory | string | packages | La directory della nuova applicazione. |
| subDirectory | string | - | La sotto-directory in cui viene posizionato il progetto. Per impostazione predefinita corrisponde al nome del progetto. |
| ux | none | cloudscape | shadcn | shadcn | Il provider UX preferito. |
| tailwind | boolean | true | Abilita TailwindCSS per lo styling utility-first. |
| tanstackRouter | boolean | true | Abilita Tanstack router per il routing type-safe. |
| infra | cloudfront-s3 | none | cloudfront-s3 | Il tipo di infrastruttura con cui distribuire il tuo sito web. |
| iac | inherit | cdk | terraform | inherit | Il provider IaC preferito. Per impostazione predefinita viene ereditato dalla selezione iniziale. |
| preferInstallDependencies | boolean | true | Se preferire l'installazione delle dipendenze dopo l'esecuzione del generatore. Impostare su false per rimandare l'installazione quando si eseguono più generatori in batch (l'installazione viene comunque eseguita se necessaria affinché i generatori successivi possano calcolare il grafo dei progetti Nx); installare una volta alla fine. |
Output del generatore
Sezione intitolata “Output del generatore”Il generatore creerà la seguente struttura di progetto nella directory <directory>/<name>:
- index.html HTML entry point
- public Static assets
Directorysrc
- main.tsx Application entry point with React setup
- config.ts Application configuration (eg. logo)
Directorycomponents
- AppLayout Components for the overall layout and navigation bar
Directoryhooks
- useAppLayout.tsx Hook for adjusting the AppLayout from nested components (Cloudscape only)
Directoryroutes
- index.tsx Example route (or page) for TanStack Router
- styles.css Global styles
- vite.config.mts Vite and Vitest configuration
- tsconfig.json Base TypeScript configuration for source and tests
- tsconfig.app.json TypeScript configuration for source code
- tsconfig.spec.json TypeScript configuration for tests
- package.json Project manifest defining the project’s package name and dependencies
Infrastruttura
Sezione intitolata “Infrastruttura”Poiché questo generatore fornisce infrastruttura come codice basata sul tuo iac scelto, creerà un progetto in packages/common che include i costrutti CDK o i moduli Terraform pertinenti.
Il progetto comune di infrastruttura come codice è strutturato come segue:
Directorypackages/common/constructs
Directorysrc
Directoryapp/ Constructs for infrastructure specific to a project/generator
- …
Directorycore/ Generic constructs which are reused by constructs in
app- …
- index.ts Entry point exporting constructs from
app
- project.json Project build targets and configuration
Directorypackages/common/terraform
Directorysrc
Directoryapp/ Terraform modules for infrastructure specific to a project/generator
- …
Directorycore/ Generic modules which are reused by modules in
app- …
- project.json Project build targets and configuration
Il generatore crea infrastruttura come codice per distribuire il tuo sito web in base al tuo iac selezionato:
Directorypackages/common/constructs/src
Directoryapp
Directorystatic-websites
- <name>.ts Infrastructure specific to your website
Directorycore
- static-website.ts Generic StaticWebsite construct
Directorypackages/common/terraform/src
Directoryapp
Directorystatic-websites
Directory<name>
- <name>.tf Module specific to your website
Directorycore
Directorystatic-website
- static-website.tf Generic static website module
Architettura
Sezione intitolata “Architettura”Il sito web distribuito ha la seguente architettura:
Implementare il tuo sito web
Sezione intitolata “Implementare il tuo sito web”La documentazione React è un buon punto di partenza per imparare le basi della costruzione con React.
Puoi fare riferimento alla documentazione Cloudscape per dettagli sui componenti disponibili e su come utilizzarli.
Puoi fare riferimento alla documentazione shadcn/ui per dettagli sui componenti disponibili e su come utilizzarli.
Creare una route/pagina
Sezione intitolata “Creare una route/pagina”Il tuo sito web viene fornito con TanStack Router configurato di default. Questo rende facile aggiungere nuove route:
- Esegui il server di sviluppo locale
- Crea un nuovo file
<page-name>.tsxinsrc/routes, con la sua posizione nell’albero dei file che rappresenta il percorso - Nota che un
RouteeRouteComponentvengono generati automaticamente per te. Puoi iniziare a costruire la tua pagina qui!
Navigare tra le pagine
Sezione intitolata “Navigare tra le pagine”Puoi utilizzare il componente Link o l’hook useNavigate per navigare tra le pagine:
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> </> )};Per maggiori dettagli, consulta la documentazione di TanStack Router.
Distribuire il tuo sito web
Sezione intitolata “Distribuire il tuo sito web”Il generatore di siti web React crea infrastruttura come codice CDK o Terraform in base al tuo iac selezionato. Puoi utilizzarla per distribuire il tuo sito web.
Per distribuire il tuo sito web, consigliamo di utilizzare il generatore ts#infra per creare un’applicazione CDK.
Puoi utilizzare il costrutto CDK generato per te in packages/common/constructs per distribuire il tuo sito web.
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'); }}Questo configura:
- Un bucket S3 per ospitare i file del tuo sito web statico
- Distribuzione CloudFront per la distribuzione globale dei contenuti
- WAF Web ACL per la protezione della sicurezza
- Origin Access Control per l’accesso sicuro a S3
- Distribuzione automatica dei file del sito web e della configurazione runtime
Per distribuire il tuo sito web, consigliamo di utilizzare il generatore terraform#project per creare un progetto Terraform.
Puoi utilizzare il modulo Terraform generato per te in packages/common/terraform per distribuire il tuo sito web.
# Deploy websitemodule "my_website" { source = "../../common/terraform/src/app/static-websites/my-website"
providers = { aws.us_east_1 = aws.us_east_1 }}Questo configura:
- Un bucket S3 per ospitare i file del tuo sito web statico
- Distribuzione CloudFront per la distribuzione globale dei contenuti
- WAF Web ACL per la protezione della sicurezza (distribuito in us-east-1)
- Origin Access Control per l’accesso sicuro a S3
- Distribuzione automatica dei file del sito web e della configurazione runtime
Header di sicurezza
Sezione intitolata “Header di sicurezza”La distribuzione CloudFront applica una policy di header di risposta che imposta Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options: DENY, Referrer-Policy e una Content-Security-Policy su tutte le risposte.
Viene applicata una Content-Security-Policy predefinita. Essa limita gli script e il framing per mitigare XSS e clickjacking, consentendo al contempo connessioni HTTPS e WSS in modo che il sito web possa chiamare gli endpoint dei servizi AWS (come API Gateway, Cognito e Bedrock AgentCore) i cui URL sono noti solo al momento della distribuzione. Per regolare la policy (ad esempio per restringere connect-src alle tue origini specifiche), modifica il valore content_security_policy nel tuo static-website.ts (CDK) o static-website.tf (Terraform) generato.
runtime-config.json viene servito con Cache-Control: no-cache in modo che i browser recuperino sempre la configurazione più recente dopo una ridistribuzione, anziché utilizzare una copia cache obsoleta.
La distribuzione CloudFront è protetta da un AWS WAFv2 Web ACL di default. Il Web ACL utilizza il set di regole predefinito gestito da AWS (AWSManagedRulesCommonRuleSet e AWSManagedRulesKnownBadInputsRuleSet), fornendo protezione contro exploit web comuni inclusi OWASP Top 10.
Per disattivare, imposta enableWaf su false quando crei il tuo sito web:
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', ); }}Per disattivare, imposta enable_waf su 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}Crittografia del bucket
Sezione intitolata “Crittografia del bucket”Il bucket del sito web, il bucket dei log della distribuzione CloudFront e il gruppo CloudWatch Logs che riceve i loro log di accesso al server sono crittografati con una chiave AWS KMS gestita dal cliente di default. Questa chiave viene creata automaticamente per te, con la rotazione delle chiavi abilitata.
Se desideri utilizzare una configurazione di crittografia diversa, passa le proprietà encryption, encryptionKey e enableKeyRotation quando crei il tuo sito web:
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, }); }}Per utilizzare la tua chiave KMS invece di una creata automaticamente, passa encryptionKey:
new MyWebsite(this, 'MyWebsite', { encryptionKey: myKey,});enableKeyRotation (default true) si applica solo alla chiave creata automaticamente, cioè quando encryption è BucketEncryption.KMS (il default) e non viene fornita alcuna encryptionKey:
new MyWebsite(this, 'MyWebsite', { enableKeyRotation: false,});Se desideri utilizzare una configurazione di crittografia diversa, imposta le variabili encryption, kms_key_arn, create_kms_key e 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"}Per utilizzare la tua chiave KMS invece di una creata automaticamente, passa kms_key_arn e imposta create_kms_key su 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}Una chiave fornita dal cliente deve già concedere ai principali dei servizi CloudWatch Logs, S3 e CloudFront le autorizzazioni di cui hanno bisogno nella propria policy della chiave.
enable_key_rotation (default true) si applica solo alla chiave creata automaticamente, cioè quando encryption è "KMS" (il default) e 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}Dominio personalizzato e TLS
Sezione intitolata “Dominio personalizzato e TLS”Di default, la distribuzione utilizza il nome di dominio CloudFront predefinito (*.cloudfront.net) e il suo certificato predefinito, che non supporta l’applicazione di una versione TLS minima di 1.2. Per servire il tuo sito web dal tuo dominio, fornisci un certificato ACM (che deve risiedere in us-east-1 per l’uso con CloudFront) e i tuoi nomi di dominio. Viene quindi applicata una versione TLS minima di 1.2 per i visualizzatori:
Passa le proprietà certificate e domainNames quando crei il tuo sito web:
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/...'), }); }}Imposta le variabili custom_domain_names e 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/..."}Dovrai anche creare record DNS (ad esempio in Route 53) che puntano il tuo dominio alla distribuzione CloudFront.
Configurazione runtime
Sezione intitolata “Configurazione runtime”La configurazione dalla tua infrastruttura viene fornita al tuo sito web tramite Configurazione runtime. Questo consente al tuo sito web di accedere a dettagli come gli URL delle API che non sono noti fino a quando la tua applicazione non viene distribuita.
Infrastruttura
Sezione intitolata “Infrastruttura”Il costrutto CDK RuntimeConfig può essere utilizzato per aggiungere e recuperare la configurazione nella tua infrastruttura CDK. I costrutti CDK generati dai generatori @aws/nx-plugin (come ts#api e py#api) aggiungeranno automaticamente valori appropriati al RuntimeConfig.
Il tuo costrutto CDK del sito web distribuirà il namespace connection della configurazione runtime come file runtime-config.json nella radice del tuo bucket 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(), }); }}Con Terraform, la configurazione runtime viene gestita tramite i moduli runtime-config. I moduli Terraform generati dai generatori @aws/nx-plugin (come ts#api e py#api) aggiungeranno automaticamente valori appropriati alla configurazione runtime.
Il tuo modulo Terraform del sito web distribuirà il namespace connection della configurazione runtime come file runtime-config.json nella radice del tuo bucket 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]}Codice del sito web
Sezione intitolata “Codice del sito web”Nel tuo sito web, puoi utilizzare l’hook useRuntimeConfig per recuperare valori dalla configurazione runtime:
import { useRuntimeConfig } from '../hooks/useRuntimeConfig';
const MyComponent = () => { const runtimeConfig = useRuntimeConfig();
// Access values in the runtime config here const apiUrl = runtimeConfig.apis.MyApi;};Configurazione runtime locale
Sezione intitolata “Configurazione runtime locale”Quando esegui il server di sviluppo locale, avrai bisogno di un file runtime-config.json nella tua directory public affinché il tuo sito web locale conosca gli URL del backend, la configurazione dell’identità, ecc.
Il tuo progetto del sito web è configurato con un target load-runtime-config che puoi utilizzare per scaricare il file runtime-config.json da un’applicazione distribuita:
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>Server di sviluppo locale
Sezione intitolata “Server di sviluppo locale”Il comando canonico per lo sviluppo locale è dev, che avvia il tuo sito web (e qualsiasi server locale per le API a cui lo hai connesso) con un unico comando:
pnpm nx dev <my-website>yarn nx dev <my-website>npx nx dev <my-website>bunx nx dev <my-website>Il target serve è disponibile anche per quando hai bisogno di controllare quanto della tua applicazione viene eseguito localmente rispetto al puntamento all’infrastruttura AWS distribuita. Per una panoramica più ampia dello sviluppo locale tra progetti connessi, incluso come si comporta dev per progetti con più componenti, consulta la guida Sviluppo locale.
Target Serve
Sezione intitolata “Target Serve”Il target serve avvia un server di sviluppo locale per il tuo sito web. Questo target richiede che tu abbia distribuito qualsiasi infrastruttura di supporto con cui il sito web interagisce e che tu abbia caricato la configurazione runtime locale.
Puoi eseguire questo target con il seguente comando:
pnpm nx serve <my-website>yarn nx serve <my-website>npx nx serve <my-website>bunx nx serve <my-website>Questo target è utile per lavorare sulle modifiche del sito web puntando a API “reali” distribuite e ad altra infrastruttura.
Target Dev
Sezione intitolata “Target Dev”Il target dev avvia un server di sviluppo locale per il tuo sito web (con Vite MODE impostato su local-dev), oltre ad avviare qualsiasi server locale per le API a cui hai connesso il tuo sito web tramite il generatore Connection.
Quando il server del tuo sito web locale viene eseguito tramite questo target, runtime-config.json viene automaticamente sovrascritto per puntare agli URL delle tue API in esecuzione localmente.
Puoi eseguire questo target con il seguente comando:
pnpm nx dev <my-website>yarn nx dev <my-website>npx nx dev <my-website>bunx nx dev <my-website>Questo target è utile quando stai lavorando sul tuo sito web e sulla tua API e desideri iterare rapidamente senza distribuire la tua infrastruttura.
Autenticazione simulata
Quando viene eseguito in questa modalità e non è presente alcun runtime-config.json, se hai configurato l’autenticazione Cognito (tramite il generatore ts#website#auth), il login verrà saltato e le richieste ai tuoi server locali non includeranno header di autenticazione.
Per abilitare il login e l’autenticazione per dev, distribuisci la tua infrastruttura e carica la configurazione runtime.
Building
Sezione intitolata “Building”Puoi compilare il tuo sito web utilizzando il target build. Questo esegue i target bundle, compile, test e lint, effettuando il controllo dei tipi, il bundling, il testing e il linting del tuo sito web.
pnpm nx build <my-website>yarn nx build <my-website>npx nx build <my-website>bunx nx build <my-website>Il target bundle utilizza Vite per creare un bundle di produzione nella directory radice dist/packages/<my-website>/bundle. Questo è l’artefatto distribuibile consumato dalla tua infrastruttura del sito web. Puoi eseguirlo da solo:
pnpm nx bundle <my-website>yarn nx bundle <my-website>npx nx bundle <my-website>bunx nx bundle <my-website>Testing
Sezione intitolata “Testing”Testare il tuo sito web è molto simile a scrivere test in un progetto TypeScript standard, quindi fai riferimento alla guida al progetto TypeScript per maggiori dettagli.
Per i test specifici di React, React Testing Library è già installato e disponibile per scrivere test. Per maggiori dettagli sul suo utilizzo, fai riferimento alla documentazione di React Testing Library.
Puoi eseguire i tuoi test utilizzando il target test:
pnpm nx test <my-website>yarn nx test <my-website>npx nx test <my-website>bunx nx test <my-website>Connessioni
Sezione intitolata “Connessioni”Utilizza il generatore connection per integrare questo progetto con altri nel tuo workspace. Le seguenti connessioni coinvolgono questo progetto:
