使用AWS CDK Bundler时如何解析API Gateway的URL令牌传入环境变量
根本原因
该问题由CDK生命周期的阶段差异导致:
- S3 Asset的bundling步骤在
cdk synth合成阶段执行,此时CloudFormation栈尚未开始部署,API Gateway等资源还未创建,其URL属于部署阶段才会生成的动态值,只能用CloudFormation令牌占位符表示,无法在合成阶段获取到实际字符串 - 直接将令牌传入bundling的环境变量,最终得到的就是未解析的
${Token[xxx]}格式的占位符文本
可选解决方案
方案1:运行时动态获取配置(最易实现,无额外依赖)
不要在前端构建阶段硬编码PUBLIC_URL,改为部署时往S3桶写入一个包含实际API地址的配置文件,前端启动时先加载这个配置即可:
const api = new apigateway.RestApi(this, 'restApi'); const staticRoute = api.root.addResource('static'); const publicUrl = api.urlForPath(staticRoute.path); new s3deploy.BucketDeployment(this, 'DeployWebsite', { sources: [ // 原有静态资源构建逻辑,无需传入环境变量 s3deploy.Source.asset("./path/to/source/files", { bundling: { image: cdk.DockerImage.fromRegistry("node:latest"), command: [ 'bash', '-c', ` cd /asset-input \ && npm install \ && npm run build \ && mv build/* /asset-output ` ] } }), // 新增动态生成的配置文件,CloudFormation部署时会自动替换令牌为实际值 s3deploy.Source.jsonData('config.json', { PUBLIC_URL: publicUrl }) ], destinationBucket: this.websiteBucket, });
前端代码对应修改,加载配置后再初始化应用即可:
fetch('/config.json') .then(res => res.json()) .then(config => { window.PUBLIC_URL = config.PUBLIC_URL; // 此处放置原有应用初始化逻辑 })
方案2:拆分部署流程(适合必须构建时硬编码的场景)
如果构建流程要求编译阶段必须拿到PUBLIC_URL的实际值,可将部署拆为两个阶段:
- 第一阶段先部署API Gateway,将API URL作为CloudFormation栈的输出值导出
- 第二阶段读取上一步导出的实际URL作为环境变量传入bundling,再执行静态资源构建和S3部署
可以通过CDK Pipelines或其他CI/CD工具实现该流程,在两个部署阶段之间传递输出值即可。
方案3:CloudFormation占位符替换(无需修改前端代码)
如果不想改动前端逻辑,也可以在部署时让CloudFormation自动替换静态文件内的占位符:
- 构建时将代码中需要写
PUBLIC_URL的位置统一替换为自定义占位符,比如__PUBLIC_URL_PLACEHOLDER__ - 部署时使用
Fn.sub函数自动替换产物中的占位符为实际URL,该方案更适合单文件小体积的场景,复杂项目灵活性不如方案1。
内容的提问来源于stack exchange,提问作者Migwell
相关产品推荐
相关产品推荐

