@aws-amplify/hosting

中文文档
1.0.1发布于 2026/09/18Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 16.9万

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

中文使用文档
文档目录49 节
  1. QQ 重要: 需要单独的文件
  2. 快速启动
  3. SPA (反应, Vue等)
  4. Next.js (瑞典语)
  5. 部署
  6. 常见错误
  7. 建筑
  8. 适配管道
  9. 内建适应器
  10. 基础设施
  11. 特征
  12. ISR(递增静态再生)
  13. 图像优化
  14. 中间软件
  15. 反应
  16. 部署期间发生了什么?
  17. 配置
  18. 自定义域
  19. 更改您的自定义域
  20. WAF (Web 应用程序防火墙)
  21. WAF 区域要求
  22. 第二阶段部署
  23. 旗帜
  24. 密钥环境变量( E)
  25. 计算机/光盘 definePipeline()
  26. 限制
  27. 沙盒
  28. 管理 ampx pipeline-deploy
  29. HEAD 请求 Content-Length 均等
  30. 多区跨区导航缓存
  31. Range 流出端点上的请求
  32. 自定义框架适配器
  33. SSR 自定义适配器示例
  34. 部署宣言司马
  35. 计算类型
  36. Lambda 配置
  37. 内容安全政策
  38. 独立的 CDK 用法( 无扩展 CLI)
  39. 子路径导入
  40. SPA 示例( Vanilla CDK)
  41. Next.js SSR 实例(万尼拉 CDK)
  42. 使用 BYO 证书自定义域
  43. 写入自定义适配器
  44. 解决问题
  45. 构建失败, 但错误消息不明
  46. CloudFront 返回 403
  47. 部署时间很长
  48. ISR 页面没有重新验证
  49. 图像优化返回 500

@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等)

// 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 使用 见下文.

Next.js (瑞典语)

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

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

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

部署

# 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

常见错误

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

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

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

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

// 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。 。 。 . @aws-amplify/hosting 重新出口这些物项(在《京都议定书》之下 AmplifyHostingConstruct 添加可放大特有胶水—— defineHosting(), (中文(简体) ), definePipeline(),以及后端-输出集成.

适配管道

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

内建适应器

适配器说明
下一个.js用途 @ opennextjs/ aws (帮助) 用于处理 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 (单位:千美元)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.
buildCommandstring- 说吧在部署前建立运行命令 .
buildOutputDirstring自动检测预建输出路径( SPA/ static) 。 已忽略 Next.js( OpenNext 构建) .
environmentRecord<string, string | ByoValue>- 说吧Env vars被注射到SSR计算. 使用 secret()编号 :config()编号 :byoSecret()编号 :byoConfig() 敏感值或可旋转值——见 密钥环境变量( E)。 。 。 .
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个月.
customAdapterFrameworkAdapterFn- 说吧不支持的框架自定义框架适配器 .
compute{ memorySize?, timeout?, logRetention?, reservedConcurrency? }1024MB, 30sSSR的Lambda配置.
cdn.priceClassPriceClassPRICE_CLASS_100云花价类. 使用 PRICE_CLASS_ALL 全球分布.
cdn.contentSecurityPolicystring限制性违约自定义 CSP 头值 .
cdn.geoRestriction{ type, countries }- 说吧云龙分布的地理限制.
storage.retainOnDeletebooleanfalse在堆栈删除时保留 S3 桶 .
storage.encryption'S3_MANAGED' | 'KMS''S3_MANAGED'主机桶的加密类型 .
logging.enabledbooleanfalse启用 CloudFront 访问日志到 S3 .
logging.retentionDaysnumber90保存访问日志的天数 .

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

自定义域

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

// 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默认).

// 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 ——非敏感字,被烤入"云形"模板(从不在此放出秘密):

    defineHosting({ environment: { APP_REGION: 'us-east-1' } });
    // read at runtime with process.env.APP_REGION
    
  • 秘诀 (单位:千美元)secret())——存储在AWS保密管理器中的敏感值. 只有商店定位器被注入;该值从未输入模板.

  • 配置 (单位:千美元)config()) ——储存在SSM参数存储器中的非敏感但可旋转值.

// 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:

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/建设代码:

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 参数名):

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) (中文(简体) ).

// 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()数字 :

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()。 。 。 .

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数字 :

// 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 自定义适配器示例

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 构造之间的合同。 自定义适配器必须返回此形状 :

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 设置 :

// 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 要覆盖的道具 :

// 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/ 需要目录 .

子路径导入

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

// 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)

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)

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 证书自定义域

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 适配器 :

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,
  };
};

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

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()页: 1revalidate: N 内 getStaticProps)也通过基于时间的再验证支持.

图像优化返回 500

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

版本与发布记录

@aws-amplify/hosting 共发布 20 个版本,首次发布于 2026/04/02;过去 12 个月发布了 20 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.0.1latest2026/09/181 个月前
1.0.02026/09/101 个月前
0.0.0-iac-hosting-20260609205023iac-hosting2026/06/104 个月前
0.0.0-iac-hosting-202606091454172026/06/094 个月前
0.0.0-iac-hosting-202606051244592026/06/055 个月前
0.0.0-iac-hosting-202606031902012026/06/045 个月前

其他发布通道:test → 0.0.0-test-20260601122829,iac-hosting → 0.0.0-iac-hosting-20260609205023。

关于 @aws-amplify/hosting 的常见问题

@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 和提交记录判断。