# @aws-amplify/hosting 中文文档

规范地址：https://npmcn.com/package/%40aws-amplify/hosting/

版本：1\.0\.1
npm 元数据更新时间：2026-09-18T13:54:06.031Z
中文译文更新时间：2026-11-07T11:16:25.851Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40aws-amplify/hosting
原文对照：https://npmcn.com/package/%40aws-amplify/hosting/?lang=original
项目主页：https://github.com/aws-amplify/amplify-backend#readme
源码仓库：https://github.com/aws-amplify/amplify-backend

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：693 kB，98 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：6 个
- peer 依赖：constructs ^10\.6\.0，aws-cdk-lib ^2\.257\.0，@opennextjs/aws \>=3\.10\.0
- 首次发布：2026-04-01T16:13:22.756Z
- 最新版本发布：2026-09-18T13:54:05.590Z
- 近 30 天下载量：168997（2026-10-07 至 2026-11-05，npm 官方下载统计）
- 已发布版本数：20（近 12 个月 20 个）

## 中文简介

使用 CloudFront + S3 + Lambda 向 AWS 部署静态站点,SPA 和 SSR 应用(Next.js, Nuxt, Astro, SvelteKit).

## 安装

```sh
npm install @aws-amplify/hosting
```

也可以使用：`pnpm add @aws-amplify/hosting`、`yarn add @aws-amplify/hosting`、`bun add @aws-amplify/hosting`

## README

# @aws-amplify/东道主

使用 CloudFront + S3 + Lambda 向 AWS 部署静态站点,SPA 和 SSR 应用(Next.js, Nuxt, Astro, SvelteKit).

## QQ 重要: 需要单独的文件

托管 **必须** 定义 `amplify/hosting.ts` ——从 `amplify/backend.ts`。这是因为主机作为独立的 CloudFormation 堆栈部署,允许您独立部署前端和后端.

```
amplify/
├── backend.ts      ← defineBackend() — auth, data, storage
├── hosting.ts      ← defineHosting() — CloudFront, S3, Lambda
└── ...
```

## 快速启动

### SPA (反应, Vue等)

```typescript
// amplify/hosting.ts
import { defineHosting } from '@aws-amplify/hosting';

defineHosting({
  framework: 'spa',
  buildCommand: 'npm run build',
});
```

> **说明:** `defineHosting()` 被设计为可扩展的CLI(`ampx deploy`) (中文(简体) ). 它只有在收到内部的 Cloud Formation 模板时才能合成 `'amplifySynth'` IPC电文来自CLI. 运行 `amplify/hosting.ts` 直接与 `npx cdk synth` 或者说 `node` 将 **没有** 生成 CloudFormation 模板。 如果您需要在独立的 CDK 应用程序中使用主机构造, 请使用 `AmplifyHostingConstruct` 从 `@aws-amplify/hosting/constructs` 相反——见 [独立的 CDK 使用](https://npmcn.com/package/%40aws-amplify/hosting/#readme-standalone-cdk-usage-no-amplify-cli) 见下文.

### Next.js (瑞典语)

```typescript
// amplify/hosting.ts
import { defineHosting } from '@aws-amplify/hosting';

defineHosting({
  framework: 'nextjs',
  buildCommand: 'npm run build',
});
```

> **说明:** 没错 **没有** 需要配置 `output: 'standalone'` 内 `next.config.js`。适配器使用 [@ opennextjs/ aws (帮助)](https://opennext.js.org/) 内部,它自动处理构建转换.

### 部署

```bash
# Deploy everything (backend + frontend)
npx ampx deploy --identifier prod

# Deploy only backend (auth, data, storage)
npx ampx deploy --identifier prod --backend

# Deploy only frontend (hosting) — requires backend deployed first
npx ampx deploy --identifier prod --frontend
```

## 常见错误

❌ **错误——不要添加主机定义备份 :**

```typescript
// amplify/backend.ts — THIS IS WRONG
import { defineBackend } from '@aws-amplify/backend';
import { hosting } from './hosting/resource';

defineBackend({ hosting }); // ❌ Will not work
```

✅ **CORRECT - 使用单独的扩展/主机文件 :**

```typescript
// amplify/hosting.ts — THIS IS CORRECT
import { defineHosting } from '@aws-amplify/hosting';

defineHosting({
  framework: 'spa',
  buildCommand: 'npm run build',
});
```

主机是一个独立的CDK入站点. CLI 发现 `amplify/hosting.ts` 并将其自动部署为单独的 Cloud Formation 堆栈.

## 建筑

主机包采用双层架构:

1.  **框架适配器** - 将特定框架的建设产出转变为通用产出 `DeployManifest`
2.  **L3 CDK 构造** ——解读AWS资源(S3,CloudFront,Lambda等)的明细表和规定

这种构造是完全框架不可知的。 它永远不知道是来自Next.js,Astro,还是自定义适配器.

> **执行情况说明:** 框架适配器和 L3 CDK 构造由 [`@aws-blocks/hosting`](https://www.npmjs.com/package/@aws-blocks/hosting)。 。 。 . `@aws-amplify/hosting` 重新出口这些物项(在《京都议定书》之下 `AmplifyHostingConstruct` 添加可放大特有胶水—— `defineHosting()`, (中文(简体) ), `definePipeline()`,以及后端-输出集成.

### 适配管道

```
┌─────────────────┐     ┌──────────────────┐     ┌─────────────────────┐
│  Framework      │     │  Deploy Manifest  │     │  AWS Resources      │
│  Build Output   │ ──► │  (generic JSON)   │ ──► │  (CDK L3 Construct) │
└─────────────────┘     └──────────────────┘     └─────────────────────┘
     adapter()                                      AmplifyHostingConstruct
```

### 内建适应器

| 适配器 | 说明 |
| --- | --- |
| **下一个.js** | 用途 [@ opennextjs/ aws (帮助)](https://opennext.js.org/) 用于处理 Next.js 构建输出。 支持 App 路由器, Pages 路由器, ISR, 中间软件, 图像优化, 以及响应流. |
| **硝基** | 硝基安全部门改革产出(`.output/`) (中文(简体) ). Nuxt和Astro的节点/Lambda目标背后的引擎. |
| **坚果** | Nuxt 3应用程序(由硝基适配器所建). |
| **天体** | 使用节点/Lambda适配器(由硝基适配器所建)的Astro SSR应用. |
| **斯维尔特基特** | SvelteKit 应用程序通过 `@sveltejs/adapter-node` (SSR)加上静态/前置输出. |
| **最高人民会议** | 静态单页应用(React,Vue,Angular等). 所有路线都服务 `index.html` 有客户端的路由. |

以上全部出口自 [`@aws-amplify/hosting/adapters`](https://npmcn.com/package/%40aws-amplify/hosting/src/adapters/index.ts) (单位:千美元)`nextjsAdapter`, (中文(简体) ), `nitroAdapter`, (中文(简体) ), `nuxtAdapter`, (中文(简体) ), `astroAdapter`, (中文(简体) ), `sveltekitAdapter`, (中文(简体) ), `spaAdapter`)和通过框架检测自动选择;您只需要一个不在此列出的框架的自定义适配器.

### 基础设施

-   **第3条**: 带有OAC(Origin访问控制)的私人桶. 所有公众访问被封锁.
-   **云纹**:HTTP/2 + HTTP/3,TLS 1.2+,gzip/brotli压缩,安全头(HSTS,CSP,X-Frame-options).
-   **兰布达** (SSR):有响应流的原生Lambda处理器,IAM认证函数URL,最小优先的IAM角色.
-   **兰布达@ Edge** (Middleware):用于请求/响应转换的边缘函数.
-   **图像优化**: 分离出 Lambda, 并有尖锐的按需图像再大小和格式转换.
-   **ISR 缓存**: S3缓存桶 + DynamoDB (基于tag的再验证) + SQS (同步再验证队列). 当适配器宣布缓存配置时自动提供 .
-   **原子部署**:每个部署在 S3. CloudFront 函数重写 URL 中创建一个新建的 ID 前缀. 零下断时.

## 特征

### ISR(递增静态再生)

Next.js 互联网档案馆的存檔,存档日期2013-12-02 `revalidateTag()` 财务报告和审定财务报表 `revalidatePath()` 获得充分支持。 适配器自动提供:

-   **S3 缓存桶** ——存储预发页
-   **迪纳摩DB 表格** —— 地图缓存标记为路径 `revalidateTag()`
-   **SQS 队列** ——处理合成再验证请求

不需要配置——如果您的 Next.js app 使用 ISR, 则基础设施会自动提供 .

### 图像优化

下一个.js `<Image>` 构成部分和 `next/image` 优化出框的工作。 专用的 Lambda 函数控件 :

-   按需调整大小到已配置大小
-   格式转换 (WebP, AVIF)
-   在 S3 中缓存优化图像

### 中间软件

Next.js 中间软件作为 Lambda@Edge 函数运行,支持:

-   请求/答复页眉操作
-   重定向和重写
-   边缘验证检查
-   基于地理位置的路由

### 反应

SSR响应使用Lambda响应流化(通过函数 URL)进行流化,将时间减少为服务器发送页面的第一个字节(TTFB).

## 部署期间发生了什么?

1.  **构建** ——您的构建命令运行(例如, `npm run build`(中文(简体) )
2.  **适配器** ——框架适配器将产出构建为 `DeployManifest` (下一步js在内部使用 OpenNext)
3.  **CDK 合成器** —— CDK 合成基于表单的 Cloud Formation 模板
4.  **云阵部署** - AWS规定/更新所有资源

**时间线 :**

-   **第一次部署:** ~15-20分(云花分发提供为瓶颈)
-   **其后部署:** ~5分钟(资产上传+缓存无效)
-   **堆叠删除 :** ~20-40分(云花在取出前必须完全禁用)

## 配置

| Prop | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `framework` | `'nextjs' | 'nitro' | 'nuxt' | 'astro' | 'sveltekit' | 'spa' | 'static' | string` | 自动检测 | 框架类型。 自动从包裹. json. |
| `buildCommand` | `string` | \- 说吧 | 在部署前建立运行命令 . |
| `buildOutputDir` | `string` | 自动检测 | 预建输出路径( SPA/ static) 。 已忽略 Next.js( OpenNext 构建) . |
| `environment` | `Record<string, string | ByoValue>` | \- 说吧 | Env vars被注射到SSR计算. 使用 `secret()`编号 :`config()`编号 :`byoSecret()`编号 :`byoConfig()` 敏感值或可旋转值——见 [密钥环境变量( E)](https://npmcn.com/package/%40aws-amplify/hosting/#readme-secrets--environment-variables)。 。 。 . |
| `secretStore` 编号 : `configStore` | `{ prefix?, stage? }` | 每个项目的默认 | 覆盖存储路径/名称空间 `secret()` 编号 : `config()` 数值. |
| `monitoring` | `{ enabled?, snsTopicArn? }` | `{ enabled: true }` | Cloud Watch 提醒 (5xx, Lambda errors/throttles, revalidation DLQ). 星洲网. **默认**;每个警报每月几分钱。 设定 `{ enabled: false }` 选择退出. |
| `skewProtection` | `{ enabled, maxAge? }` | `{ enabled: true }` | 滚动部署时基于 Cookie 的版本 skew 保护. **默认的.** |
| `domain` | `{ domainName, hostedZone }` | \- 说吧 | 自定义 SSL 域 。 需要53号公路托管区. |
| `waf` | `{ enabled, rateLimit? }` | \- 说吧 | 启用 AWS WAF 有管理规则 + 速率限制 。 加上~$5个月. |
| `customAdapter` | `FrameworkAdapterFn` | \- 说吧 | 不支持的框架自定义框架适配器 . |
| `compute` | `{ memorySize?, timeout?, logRetention?, reservedConcurrency? }` | `1024MB, 30s` | SSR的Lambda配置. |
| `cdn.priceClass` | `PriceClass` | `PRICE_CLASS_100` | 云花价类. 使用 `PRICE_CLASS_ALL` 全球分布. |
| `cdn.contentSecurityPolicy` | `string` | 限制性违约 | 自定义 CSP 头值 . |
| `cdn.geoRestriction` | `{ type, countries }` | \- 说吧 | 云龙分布的地理限制. |
| `storage.retainOnDelete` | `boolean` | `false` | 在堆栈删除时保留 S3 桶 . |
| `storage.encryption` | `'S3_MANAGED' | 'KMS'` | `'S3_MANAGED'` | 主机桶的加密类型 . |
| `logging.enabled` | `boolean` | `false` | 启用 CloudFront 访问日志到 S3 . |
| `logging.retentionDays` | `number` | `90` | 保存访问日志的天数 . |

> **生产警告:** 默认 `storage.retainOnDelete` 实值 `false`,这意味着S3桶和 **所有主机资产被永久删除** 当云形堆栈被摧毁时。 这是方便的 dev/测试,但 **生产风险**用于生产堆栈,设置 `storage: { retainOnDelete: true }` 用于保存堆栈删除中的桶。 在独立的 CDK 使用中,您也可以设置 `removalPolicy: RemovalPolicy.RETAIN` 在建筑桶上直接.

## 自定义域

需要同一 AWS 账户中的 Route53 主机区 。 通过DNS自动创建并验证ACM证书.

```typescript
// amplify/hosting.ts
import { defineHosting } from '@aws-amplify/hosting';

defineHosting({
  domain: {
    domainName: 'app.example.com',
    hostedZone: 'example.com',
  },
});
```

**第一次使用自定义域需要更长的时间** (2–5多分与Route53相接,与外接DNS可能更长)因为ACM证书验证屏蔽了CloudFormation堆栈直到证书签发.

**外部 DNS 用户 :** 您必须手动创建 CNAME 记录用于ACM 验证 。 CloudFormation将等待长达72小时的证书验证后,时间才会出来并滚回.

**建议:** 保持您所在的路由53区在同一 AWS 中最平滑的经验。 DNS验证记录是自动创建的.

### 更改您的自定义域

变化 `domainName` 初始部署原因后 **5-30分钟停机时间** ,同时替换证书并重新配置 CloudFront 。 对于零下行域迁移:

1.  创建一个带有新域的新堆栈
2.  核查新站点工程
3.  更新 DNS 以指向新的 CloudFront 分布
4.  删除旧堆栈

## WAF (Web 应用程序防火墙)

启用 AWS 管理规则(Common Rules set + Known Bad Introductions)和基于IP的费率限制(1000 req/5min/IP默认).

```typescript
// amplify/hosting.ts
import { defineHosting } from '@aws-amplify/hosting';

defineHosting({
  waf: { enabled: true, rateLimit: 1000 },
});
```

**费用:** ~5美元/月基数+100万美元/次请求。 用于具有安全要求的生产应用.

### WAF 区域要求

具有CloudFront射程的WAF需要部署到 `us-east-1`. 在其他区域部署允许的WAF将因明确错误信息而失败.

## 第二阶段部署

`ampx deploy` 采用两相部署模式:

1.  **后端阶段** (单位:千美元)`ampx deploy --backend`: 部署认证、数据和存储资源。 生成 `amplify_outputs.json`。 。 。 .
2.  **前端阶段** (单位:千美元)`ampx deploy --frontend`: 运行您的构建命令( 与 `amplify_outputs.json` 然后部署托管资源.

运行 `ampx deploy` 没有旗帜 相继部署两个阶段.

### 旗帜

| 旗帜 | 行为 |
| --- | --- |
| (无) | 部署后端 + 前端 |
| `--backend` | 只部署后端( skip 主机) |
| `--frontend` | 只部署前端( 需要先部署后端) |

**说明:** `--backend` 财务报告和审定财务报表 `--frontend` 两者相互排斥。 指定两者都是错误.

## 密钥环境变量( E)

这个 `environment` prop在您的 SSR 计算中注入值 。 支持三种类型:

-   **平地环境 vars** ——非敏感字,被烤入"云形"模板(从不在此放出秘密):
    
    ```typescript
    defineHosting({ environment: { APP_REGION: 'us-east-1' } });
    // read at runtime with process.env.APP_REGION
    ```
    
-   **秘诀** (单位:千美元)`secret()`)——存储在AWS保密管理器中的敏感值. 只有商店定位器被注入;该值从未输入模板.
    
-   **配置** (单位:千美元)`config()`) ——储存在SSM参数存储器中的非敏感但可旋转值.
    

```typescript
// amplify/hosting.ts
import { defineHosting, secret, config } from '@aws-amplify/hosting';

defineHosting({
  environment: {
    STRIPE_SECRET_KEY: secret('STRIPE_SECRET_KEY'), // → AWS Secrets Manager
    FEATURE_FLAGS: config('FEATURE_FLAGS'), // → SSM Parameter Store
  },
});
```

用 CLI 设置带外值( 两者都支持) `set` 编号 : `get` 编号 : `list` 编号 : `remove`:

```bash
npx ampx secret set STRIPE_SECRET_KEY sk_live_xxx
npx ampx config set FEATURE_FLAGS '{"newCheckout":true}'
```

在运行时间从 **无 CDK** 运行时间条目( e)`@aws-amplify/hosting/runtime` - 远离你的CDK/建设代码:

```typescript
import { getSecret, getConfig } from '@aws-amplify/hosting/runtime';

const key = await getSecret('STRIPE_SECRET_KEY');
const flags = JSON.parse(await getConfig('FEATURE_FLAGS'));
```

**参考现有资源** 指向您已经管理的秘密/参数( 无 CLI) `set` 页:1 `byoSecret()` (名称或ARN)和 `byoConfig()` (SSM 参数名):

```typescript
import { defineHosting, byoSecret, byoConfig } from '@aws-amplify/hosting';

defineHosting({
  environment: {
    DB_PASSWORD: byoSecret(
      'arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/db-AbCdEf',
    ),
    LD_ENV: byoConfig('/my-org/launchdarkly/prod'),
  },
});
```

默认情况下,每个工程的商店都会被命名为空格: 机密 : `/amplify/hosting/<project>/secrets/<KEY>`配置时 `/amplify/hosting/<project>/config/<KEY>`,通过 `secretStore` 编号 : `configStore`。 。 。 .

## 计算机/光盘 `definePipeline()`

`definePipeline()` 提供自动AWS代码Pipeline(V2)——每个分支一个管线——在每次推力上都部署你的应用,并有多阶段的推出,批准门,烘烤时间,以及每个阶段的配置打入. 定义它 `amplify/pipeline.ts` 并使用 `npx ampx deploy --pipeline` (此旗帜不能与 `--identifier`) (中文(简体) ).

```typescript
// amplify/pipeline.ts
import { definePipeline } from '@aws-amplify/hosting/pipeline';
import { Duration } from 'aws-cdk-lib';

export const pipeline = definePipeline({
  source: {
    repo: 'my-org/my-app',
    connectionArn:
      'arn:aws:codeconnections:us-east-1:123456789012:connection/abc-123',
    triggerOnPush: true,
    // triggerFilters: ['src/**', 'amplify/**'], // optional monorepo path filters
  },
  crossAccountKeys: true, // needed for cross-account stage targets
  branches: [
    {
      branch: 'main',
      stages: [
        {
          name: 'staging',
          config: { domain: 'staging.example.com' },
        },
        {
          name: 'prod',
          requireApproval: true,
          bakeTime: Duration.minutes(30),
          env: { account: '222222222222', region: 'us-west-2' },
          config: { domain: 'app.example.com' },
        },
      ],
    },
  ],
});
```

-   **`source`** —— 说 `repo` (单位:千美元)`owner/repo`),代码连接 `connectionArn` (平面字符串),可选 `triggerOnPush` 编号 : `triggerFilters`。 。 。 .
-   **`branches[].stages[]`** —— 说 `name`选项 `env` (单位:千美元)`{ account, region }`, (中文(简体) ), `requireApproval`, (中文(简体) ), `bakeTime` 联合国 `Duration`),并按阶段输入 `config`。 。 。 .
-   **`synth`** - 覆盖该建筑: `commands`, (中文(简体) ), `installCommands`, (中文(简体) ), `computeType` (单位:千美元)`ComputeType` (注), `env`, (中文(简体) ), `primaryOutputDirectory`。 。 。 .
-   **`crossAccountKeys`** 编号 : **`selfMutation`** ——交叉账户文物钥匙,管线是否更新 `amplify/pipeline.ts` 更改( 默认) `true`) (中文(简体) ).

读取当前舞台内部的配置 `amplify/hosting.ts` 与 `getStageConfig()`数字 :

```typescript
import { defineHosting } from '@aws-amplify/hosting';
import { getStageConfig } from '@aws-amplify/hosting/pipeline';

const stage = getStageConfig<{ domain: string }>();
defineHosting({
  domain: stage?.config?.domain
    ? { domainName: stage.config.domain, hostedZone: 'example.com' }
    : undefined,
});
```

`getStageConfig()` 返回时 `undefined` 管道之外(例如当地 `ampx deploy`)),因此守住进入.

## 限制

### 沙盒

`defineHosting` 不支持在 `ampx sandbox`。主机资源在沙盒开发过程中默默跳出。 使用 `ampx deploy --identifier <name>` 完全托管部署.

### 管理 `ampx pipeline-deploy`

`defineHosting` 不支持管理 `ampx pipeline-deploy` (放大托管分支部署). 对于CI/CD, 运行 `ampx deploy` 或使用内置的自管理代码Pipeline通过 [`definePipeline()`](https://npmcn.com/package/%40aws-amplify/hosting/#readme-cicd-with-definepipeline)。 。 。 .

### `HEAD` 请求 `Content-Length` 均等

A 类 `HEAD` 请求 SSR Lambda 返回 `Content-Length: 0` 而不是未来 `GET` 身体长度。 这是一个 Nitro / Lambda 函数 URL 上游限制: 框架的 HTTP 服务器不会预先计算一个 `HEAD` 并且AWS的响应-流式包装器通过任何框架集.

受影响:下载管理器,CDN Head预飞,RFC 9110§9.3.2严格客户端.

绕行:需要准确长度的客户应发行 `GET` 与 `Range: bytes=0-0` (返回第一个字节+) `Content-Range`改为 `HEAD`。 。 。 .

### 多区跨区导航缓存

当两个扩展主机部署在同一个域前(例如: `/` + 有关博客 `/blog/*` 通过跨区重写,在目前发射的区域之间进行导航 `Cache-Control: private, no-cache` 并在每次航行中回转两只蓝巴达.

工作:设定明确 `s-maxage=N` 通过您框架的跨区路径头 `headers()` 相会. 未来版本会浮出一出每道适配器的取号.

### `Range` 流出端点上的请求

流出安全部门改革路线(尼特罗) `nitro.awsLambda.streaming: true`, Astro 5, Next.js RSC)默默地忽略 `Range` 头- Lambda 函数 URL 流出前会缓冲整个正文. 使用非流端点或倒回静态 `Range`\- 能力来源(S3直接,单独的文件服务器Lambda).

## 自定义框架适配器

对于未在(Remix等——注 Nuxt、Astro和SvelteKit已建入)中构建的框架,提供自定义适配器,以返回 a `DeployManifest`数字 :

```typescript
// amplify/hosting.ts
import { defineHosting } from '@aws-amplify/hosting';
import type { FrameworkAdapterFn } from '@aws-amplify/hosting/adapters';
import type { DeployManifest } from '@aws-amplify/hosting';
import * as path from 'path';

const myAdapter: FrameworkAdapterFn = (projectDir): DeployManifest => ({
  version: 1,
  compute: {},
  staticAssets: { directory: path.join(projectDir, 'dist') },
  routes: [{ pattern: '/*', target: 'static' }],
});

defineHosting({
  customAdapter: myAdapter,
  buildCommand: 'npm run build',
});
```

### SSR 自定义适配器示例

```typescript
import type { DeployManifest } from '@aws-amplify/hosting';
import type { FrameworkAdapterFn } from '@aws-amplify/hosting/adapters';
import * as path from 'path';

const astroSSRAdapter: FrameworkAdapterFn = (projectDir): DeployManifest => ({
  version: 1,
  compute: {
    server: {
      type: 'handler',
      bundle: path.join(projectDir, 'dist/server'),
      handler: 'entry.handler',
      placement: 'regional',
      streaming: true,
      runtime: 'nodejs20.x',
      memorySize: 1024,
      timeout: 30,
    },
  },
  staticAssets: {
    directory: path.join(projectDir, 'dist/client'),
    cacheControl: 'public, max-age=31536000, immutable',
  },
  routes: [
    { pattern: '/_astro/*', target: 'static' },
    { pattern: '/favicon.ico', target: 'static' },
    { pattern: '/*', target: 'server' },
  ],
});
```

## 部署宣言司马

这个 `DeployManifest` 是框架适配器与 L3 构造之间的合同。 自定义适配器必须返回此形状 :

```typescript
type DeployManifest = {
  version: 1;

  /** Named compute resources */
  compute: Record<string, ComputeResource>;

  /** Static asset configuration */
  staticAssets: {
    directory: string;
    cacheControl?: string;
  };

  /** Route behaviors — maps URL patterns to compute or static */
  routes: RouteBehavior[];

  /** Cache infrastructure (auto-provisions S3 + DynamoDB + SQS) */
  cache?: CacheConfig;

  /** Image optimization (auto-provisions a separate Lambda) */
  imageOptimization?: ImageConfig;

  /** Middleware (deploys to Lambda@Edge) */
  middleware?: MiddlewareConfig;

  /** Redirects, rewrites, custom headers */
  redirects?: Redirect[];
  rewrites?: Rewrite[];
  headers?: CustomHeader[];

  /** Build ID for atomic deployments (auto-generated if omitted) */
  buildId?: string;
};

type ComputeResource = {
  type: 'handler' | 'http-server' | 'edge';
  bundle: string;
  handler?: string; // for type: 'handler'
  entrypoint?: string; // for type: 'http-server'
  port?: number; // for type: 'http-server'
  placement: 'regional' | 'global';
  streaming?: boolean;
  runtime?: string;
  memorySize?: number;
  timeout?: number;
  environment?: Record<string, string>;
};

type RouteBehavior = {
  pattern: string; // URL pattern (glob only — CloudFront wildcards * and ?)
  target: string; // compute resource name, or 'static'
  fallback?: string; // fallback target on error
};

type CacheConfig = {
  computeResource: string;
  tagRevalidation: boolean; // provisions DynamoDB
  revalidationQueue: boolean; // provisions SQS
};

type ImageConfig = {
  bundle: string;
  handler: string;
  formats: string[];
  sizes: number[];
};

type MiddlewareConfig = {
  bundle: string;
  handler: string;
  matchers: string[];
};
```

### 计算类型

| 类型 | 说明 | AWS 资源 |
| --- | --- | --- |
| `handler` | 本地Lambda 处理器( 最快冷起步) | 有函数 URL 的 Lambda |
| `http-server` | 用 Lambda Web 适配器包裹的 HTTP 服务器 | Lambda + 网络适应器层 |
| `edge` | 低相关性全局执行的边缘函数 | 兰布达@ Edge |

## Lambda 配置

自定义 SSR Lambda 设置 :

```typescript
// amplify/hosting.ts
import { defineHosting } from '@aws-amplify/hosting';

defineHosting({
  framework: 'nextjs',
  compute: {
    memorySize: 1024, // MB (default: 1024)
    timeout: 60, // seconds (default: 30)
    reservedConcurrency: 50, // concurrent executions (default: none)
  },
});
```

## 内容安全政策

默认的CSP是有意限制的:

```
default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:; media-src 'self'; object-src 'none'; frame-ancestors 'self'
```

**`unsafe-eval` 未包含** 在默认政策中。 这是一个蓄意的安全决定—— `eval()` 财务报告和审定财务报表 `new Function()` 是常见的 XSS 向量。 多数现代框架(包括Next.js)没有 `unsafe-eval`。 。 。 .

然而,一些库(例如某些模板引擎,更古老的图表库)要求 `eval()` 在运行时间。 如果你的应用程序需要它,使用 `cdn.contentSecurityPolicy` 要覆盖的道具 :

```typescript
// amplify/hosting.ts
import { defineHosting } from '@aws-amplify/hosting';

defineHosting({
  cdn: {
    contentSecurityPolicy:
      "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:; media-src 'self'; object-src 'none'; frame-ancestors 'self'",
  },
});
```

## 独立的 CDK 用法( 无扩展 CLI)

`AmplifyHostingConstruct` 在任何 CDK 项目中作为标准的 CDK L3 构造工作 —— 不 放大 CLI, 不 `defineHosting()`,没有 `amplify/` 需要目录 .

### 子路径导入

使用子路径导入来吸引您需要的 :

```typescript
// The construct itself
import { AmplifyHostingConstruct } from '@aws-amplify/hosting/constructs';

// Adapters for framework detection and build output transformation
import {
  spaAdapter,
  nextjsAdapter,
  detectFramework,
  getAdapter,
} from '@aws-amplify/hosting/adapters';

// Error type for catch clauses
import { HostingError } from '@aws-amplify/hosting/error';

// Manifest types for custom adapters
import type {
  DeployManifest,
  RouteBehavior,
  ComputeResource,
} from '@aws-amplify/hosting';
```

> **依赖说明 :** 子路径导入( :`/constructs`, (中文(简体) ), `/adapters`, (中文(简体) ), `/error`这样做 **没有** 导入任意 `@aws-amplify/*` 运行时的软件包。 只有主要切入点(`@aws-amplify/hosting`(b) 将 `defineHosting()` 工厂,取决于 `@aws-amplify/plugin-types` 和其他放大包。 如果您只使用子路径导入, 您的工程不需要安装任何扩展包 .

### SPA 示例( Vanilla CDK)

```typescript
import { App, Stack } from 'aws-cdk-lib';
import { AmplifyHostingConstruct } from '@aws-amplify/hosting/constructs';
import type { DeployManifest } from '@aws-amplify/hosting';
import * as path from 'path';

const app = new App();
const stack = new Stack(app, 'MySpaStack', {
  env: { account: '123456789012', region: 'us-east-1' },
});

const manifest: DeployManifest = {
  version: 1,
  compute: {},
  staticAssets: { directory: './dist' },
  routes: [{ pattern: '/*', target: 'static' }],
};

const hosting = new AmplifyHostingConstruct(stack, 'Hosting', {
  manifest,
});

// Access created resources for composition with other constructs
console.log(hosting.distributionUrl); // https://d111111abcdef8.cloudfront.net
console.log(hosting.bucket.bucketName); // auto-generated bucket name
```

### Next.js SSR 实例(万尼拉 CDK)

```typescript
import { App, Stack } from 'aws-cdk-lib';
import { AmplifyHostingConstruct } from '@aws-amplify/hosting/constructs';
import { nextjsAdapter } from '@aws-amplify/hosting/adapters';

const app = new App();
const stack = new Stack(app, 'MyNextjsStack', {
  env: { account: '123456789012', region: 'us-east-1' },
});

// Run the OpenNext adapter to produce a DeployManifest
const manifest = nextjsAdapter({ projectDir: process.cwd() });

new AmplifyHostingConstruct(stack, 'Hosting', {
  manifest,
  compute: {
    memorySize: 1024,
    timeout: 60,
  },
});
```

Next.js 适配器使用 `@opennextjs/aws` 内部处理构建输出,并用:

-   本地 Lambda 处理器(不需要网络适应器包装)
-   ISR 缓存配置(S3 + DynamoDB + SQS)
-   图像优化 Lambda
-   中间软件边缘功能( 如果适用)

### 使用 BYO 证书自定义域

```typescript
import { Certificate } from 'aws-cdk-lib/aws-certificatemanager';
import { AmplifyHostingConstruct } from '@aws-amplify/hosting/constructs';

// Certificate MUST be in us-east-1 — CloudFront requirement
const cert = Certificate.fromCertificateArn(
  stack,
  'MyCert',
  'arn:aws:acm:us-east-1:123456789012:certificate/abc-123',
);

new AmplifyHostingConstruct(stack, 'Hosting', {
  manifest,
  domain: {
    domainName: 'app.example.com',
    hostedZone: 'example.com',
    certificate: cert, // BYO cert — skips deprecated DnsValidatedCertificate
  },
});
```

> **重要内容:** CloudFront 需要ACM 证书 `us-east-1`。如果您提供了来自另一个区域的证书,则构造将丢入 `InvalidCertificateRegionError` 合成时间(混凝土ARN)。 对于跨存储符号ARN,CloudFront会在部署时拒绝证书.

### 写入自定义适配器

该建筑由 `DeployManifest`. 内置适配器(`spaAdapter`, (中文(简体) ), `nextjsAdapter`, (中文(简体) ), `nitroAdapter`, (中文(简体) ), `nuxtAdapter`, (中文(简体) ), `astroAdapter`, (中文(简体) ), `sveltekitAdapter`) 过程框架建立产出并制作此表。 您可以为上面没有覆盖的任何框架(Remix等)编写自己的适配器.

**自定义框架的 Skeleton 适配器 :**

```typescript
import * as fs from 'fs';
import * as path from 'path';
import type { DeployManifest, RouteBehavior } from '@aws-amplify/hosting';

/**
 * Custom adapter for Astro (example).
 * Scans Astro's build output and returns a DeployManifest.
 */
export const astroAdapter = (projectDir: string): DeployManifest => {
  const buildOutputDir = path.join(projectDir, 'dist');
  if (!fs.existsSync(buildOutputDir)) {
    throw new Error(`Build output not found at ${buildOutputDir}`);
  }

  const hasServerDir = fs.existsSync(path.join(buildOutputDir, 'server'));
  const routes: RouteBehavior[] = [];

  // Static assets with aggressive caching
  routes.push({
    pattern: '/_astro/*',
    target: 'static',
  });

  if (hasServerDir) {
    // SSR: catch-all goes to compute
    routes.push({ pattern: '/*', target: 'server' });

    return {
      version: 1,
      compute: {
        server: {
          type: 'handler',
          bundle: path.join(buildOutputDir, 'server'),
          handler: 'entry.handler',
          placement: 'regional',
          streaming: true,
          runtime: 'nodejs20.x',
        },
      },
      staticAssets: {
        directory: path.join(buildOutputDir, 'client'),
        cacheControl: 'public, max-age=31536000, immutable',
      },
      routes,
    };
  }

  // Static-only: all routes from S3
  routes.push({ pattern: '/*', target: 'static' });

  return {
    version: 1,
    compute: {},
    staticAssets: { directory: path.join(buildOutputDir, 'client') },
    routes,
  };
};
```

**使用带有构造的自定义适配器:**

```typescript
import { AmplifyHostingConstruct } from '@aws-amplify/hosting/constructs';
import { astroAdapter } from './astro-adapter';

const manifest = astroAdapter(process.cwd());

new AmplifyHostingConstruct(stack, 'Hosting', {
  manifest,
});
```

关键是 **可支持任何框架** 通过写入返回 a 的适配器 `DeployManifest`. 构造处理所有 AWS 资源创建(S3, CloudFront, Lambda, OAC等) 基于运算表.

## 解决问题

### 构建失败, 但错误消息不明

本地运行您的构建命令( R)`npm run build`),以查看全输出. 部署显示第一个1000+最后一个1000个字符.

### CloudFront 返回 403

这不应该发生在OAC桶政策上。 如果有,请检查S3桶政策是否包括CloudFront发行ARN.

### 部署时间很长

第一次部署会创建云纹分布(~15-20分). 随后的部署更快(~5分).

### ISR 页面没有重新验证

确保您的 Next.js 应用程序使用 App 路由器 `revalidateTag()` 或者说 `revalidatePath()`页: 1`revalidate: N` 内 `getStaticProps`)也通过基于时间的再验证支持.

### 图像优化返回 500

请检查access-date=中的日期值 (帮助) 图像优化 Lambda 有足够的内存(默认:1024MB). 大图像可能需要1024MB+. 通过 `compute` 配置 .

## 常见问题

### @aws-amplify/hosting 是什么？

使用 CloudFront \+ S3 \+ Lambda 向 AWS 部署静态站点,SPA 和 SSR 应用\(Next\.js, Nuxt, Astro, SvelteKit\)\.

### 如何安装 @aws-amplify/hosting？

在项目目录运行 npm install @aws-amplify/hosting，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：constructs（^10\.6\.0）、aws-cdk-lib（^2\.257\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @aws-amplify/hosting 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @aws-amplify/hosting 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @aws-amplify/hosting 可以商用吗？

@aws-amplify/hosting 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @aws-amplify/hosting 的下载量有多少？

根据 npm 官方下载统计，@aws-amplify/hosting 在 2026/10/07 – 2026/11/05 这 30 天内被下载 168,997 次，日均约 5,633 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @aws-amplify/hosting 还在维护吗？

最新版本 1\.0\.1 发布于 2026/09/18（1 个月前）；至今共发布 20 个版本，其中过去 12 个月发布了 20 个；首次发布于 2026/04/02。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

