使用 AWS CDK in JavaScript - AWS Cloud Development Kit (AWS CDK) v2

这是 AWS CDK v2 开发者指南。较旧的 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 AWS CDK in JavaScript

JavaScript是完全支持的客户端语言,被认为是 AWS CDK 稳定的。在 in AWS Cloud Development Kit (AWS CDK) 中 JavaScript 使用熟悉的工具,包括 Node.js 和 Node Package Manager (npm)。如果你愿意,也可以使用 Yarn,尽管本指南中的示例使用 NPM。构成 AWS 构造库的模块通过 NPM 存储库 npmjs.org 分发。

您可以使用任何编辑器或 IDE。许多 AWS CDK 开发人员使用 V isual Studio Code(或其开源等效物 vsCodium),它有很好的支持。 JavaScript

开始使用 JavaScript

要使用 AWS CDK,您必须拥有 AWS 账户和凭据并已安装 Node.js 和 AWS CDK Toolkit。请参阅 开始使用 AWS CDK

JavaScript AWS CDK 除这些条件外,应用程序不需要其他先决条件。

注意

第三方语言弃用:语言版本仅在供应商或社区共享的 EOL(生命周期结束)之前才受支持,如有更改,恕不另行通知。

创建项目

您可以通过在空目录cdk init中调用来创建新 AWS CDK 项目。使用该--language选项并指定javascript

mkdir my-project cd my-project cdk init app --language javascript

创建项目还会安装aws-cdk-lib模块及其依赖关系。

cdk init使用项目文件夹的名称来命名项目的各种元素,包括类、子文件夹和文件。文件夹名称中的连字符将转换为下划线。但是,除此之外,名称应遵循 JavaScript 标识符的形式;例如,名称不应以数字开头或包含空格。

使用本地 cdk

在大多数情况下,本指南假设您全局安装 CDK Toolkit (npm install -g aws-cdk),并且提供的命令示例(例如cdk synth)遵循此假设。这种方法可以轻松保持 CDK Toolkit 的最新状态,而且由于 CDK 对向后兼容采取了严格的方法,因此始终使用最新版本通常风险不大。

有些团队更喜欢在每个项目中指定所有依赖关系,包括诸如 CDK Toolkit 之类的工具。这种做法允许您将此类组件固定到特定版本,并确保团队中的所有开发人员(以及您的 CI/CD 环境)都完全使用这些版本。这消除了可能的变更来源,有助于使构建和部署更加一致和可重复。

CDK 在 JavaScript 项目模板中包含对 CDK Toolkit 的依赖关系package.json,因此,如果您想使用这种方法,则无需对项目进行任何更改。你所需要做的就是使用稍微不同的命令来构建应用程序和发出cdk命令。

操作 使用全球 CDK 工具包 使用本地 CDK 工具包
初始化项目 cdk init--语言 javascript npx aws-cdk init — 语言 javascript
运行 CDK 工具包命令 cdk... npm 运行 cdk... or npx aws-cdk...

npx aws-cdk运行当前项目中本地安装的 CDK Toolkit 版本(如果有),则回退到全局安装(如果有)。如果不存在全局安装,则npx下载 CDK Toolkit 的临时副本并运行该副本。您可以使用@语法指定 CDK 工具包的任意版本:pr npx aws-cdk@1.120 --version in 1.120.0 ts。

提示

设置别名,这样你就可以在安装本地 CDK Toolkit 时使用该cdk命令。

macOS/Linux
alias cdk="npx aws-cdk"
Windows
doskey cdk=npx aws-cdk $*

管理 AWS 构造库模块

使用 Node Package Manager (npm) 安装和更新 C AWS onstruct Library 模块以供您的应用程序使用,以及您需要的其他软件包。(npm如果你愿意,你可以yarn改用。) npm还会自动安装这些模块的依赖关系。

大多数 AWS CDK 构造都位于名为 CDK 的主包中aws-cdk-lib,这是由创建的新项目中的默认依赖项。cdk init“实验性” AWS 构造库模块(其中更高级别的构造仍在开发中)被命名为。aws-cdk-lib/SERVICE-NAME-alpha服务名称带有 a ws- 前缀。如果您不确定某个模块的名称,请在 NPM 上进行搜索

注意

CDK API 参考还显示了软件包名称。

例如,以下命令安装的实验模块 AWS CodeStar。

npm install @aws-cdk/aws-codestar-alpha

某些服务的构造库支持位于多个命名空间中。例如,此外aws-route53,还有另外三个 Amazon Route 53 命名空间,aws-route53-targetsaws-route53-patterns、和。aws-route53resolver

您的项目的依赖关系在中维护package.json。您可以编辑此文件以将部分或全部依赖项锁定到特定版本,或者允许在特定条件下将其更新到较新的版本。要根据您在以下中指定的规则,将项目的 NPM 依赖项更新到允许的最新版本:package.json

npm update

在中 JavaScript,您可以将模块导入到代码中,其名称与使用 NPM 安装模块时使用的名称相同。在应用程序中导入 AWS CDK 类和 AWS 构造库模块时,我们建议采用以下做法。遵循这些准则将有助于使您的代码与其他 AWS CDK 应用程序保持一致并更易于理解。

  • 使用require(),而不是 ES6 风格的指令import。Node.js 的旧版本不支持 ES6 导入,因此使用较旧的语法更具兼容性。(如果你真的想使用 ES6 导入,请使用 esm 来确保你的项目与所有支持的 Node.js 版本兼容。)

  • 通常,从中导入单个类aws-cdk-lib

    const { App, Stack } = require('aws-cdk-lib');
  • 如果您需要来自的许多类aws-cdk-lib,则可以使用命名空间别名来cdk代替导入各个类。避免两者兼而有之。

    const cdk = require('aws-cdk-lib');
  • 通常,使用短命名空间别名导入 AWS 构造库。

    const { s3 } = require('aws-cdk-lib/aws-s3');

在中管理依赖关系 JavaScript

在 JavaScript CDK 项目中,依赖关系是在项目主目录package.json的文件中指定的。核心 AWS CDK 模块位于名为的单个NPM包中aws-cdk-lib

当你使用安装软件包时npm install,NPM 会package.json为你记录该软件包。

如果你愿意,你可以用 Yarn 代替 NPM。但是,CDK 不支持 Yarn plug-and-play 模式,这是 Yarn 2 中的默认模式。将以下内容添加到您的项目.yarnrc.yml文件中以关闭此功能。

nodeLinker: node-modules

CDK 应用程序

以下是该cdk init --language typescript命令生成的示例package.json文件。为生成的文件 JavaScript 类似,只是没有 TypeScript相关的条目。

{ "name": "my-package", "version": "0.1.0", "bin": { "my-package": "bin/my-package.js" }, "scripts": { "build": "tsc", "watch": "tsc -w", "test": "jest", "cdk": "cdk" }, "devDependencies": { "@types/jest": "^26.0.10", "@types/node": "10.17.27", "jest": "^26.4.2", "ts-jest": "^26.2.0", "aws-cdk": "2.16.0", "ts-node": "^9.0.0", "typescript": "~3.9.7" }, "dependencies": { "aws-cdk-lib": "2.16.0", "constructs": "^10.0.0", "source-map-support": "^0.5.16" } }

对于可部署的 CDK 应用程序,aws-cdk-lib必须在的dependencies部分中指定。package.json你可以使用尖号 (^) 版本号说明符来表示你将接受比指定版本更高的版本,前提是它们位于同一个主版本内。

对于实验构造,请为 alpha 构造库模块指定确切版本,这些模块的 API 可能会发生变化。请勿使用 ^ 或 ~,因为这些模块的更高版本可能会带来的 API 更改,从而导致您的应用程序中断。

在的devDependencies部分中指定测试您的应用程序所需的库和工具版本(例如jest测试框架)package.json。(可选)使用 ^ 来指定可以接受更高版本的兼容版本。

第三方构造库

如果您正在开发构造库,请使用peerDependenciesdevDependencies部分的组合来指定其依赖关系,如以下示例package.json文件所示。

{ "name": "my-package", "version": "0.0.1", "peerDependencies": { "aws-cdk-lib": "^2.14.0", "@aws-cdk/aws-appsync-alpha": "2.10.0-alpha", "constructs": "^10.0.0" }, "devDependencies": { "aws-cdk-lib": "2.14.0", "@aws-cdk/aws-appsync-alpha": "2.10.0-alpha", "constructs": "10.0.0", "jsii": "^1.50.0", "aws-cdk": "^2.14.0" } }

在中peerDependencies,使用尖号 (^) 指定您的库aws-cdk-lib所使用的最低版本。这样可以最大限度地提高您的库与一系列 CDK 版本的兼容性。为 alpha 构造库模块指定确切版本,这些模块的 API 可能会发生变化。使用peerDependencies可以确保node_modules树中只有一个所有 CDK 库的副本。

在中devDependencies,指定测试所需的工具和库,也可以使用 ^ 表示可以接受更高版本的兼容版本。准确指定(不带 ^ 或 ~)你宣传的库aws-cdk-lib与之兼容的其他 CDK 软件包的最低版本和其他 CDK 软件包。这种做法可确保您的测试针对这些版本运行。这样,如果您无意中使用了仅在新版本中找到的功能,则您的测试可以捕捉到它。

警告

peerDependencies仅由 NPM 7 及更高版本自动安装。如果您使用的是 NPM 6 或更早版本,或者使用的是 Yarn,则必须在中devDependencies包含依赖项的依赖关系。否则,它们将无法安装,并且您将收到有关未解决的对等依赖关系的警告。

安装和更新依赖关系

运行以下命令来安装项目的依赖项。

NPM
# Install the latest version of everything that matches the ranges in 'package.json' npm install # Install the same exact dependency versions as recorded in 'package-lock.json' npm ci
Yarn
# Install the latest version of everything that matches the ranges in 'package.json' yarn upgrade # Install the same exact dependency versions as recorded in 'yarn.lock' yarn install --frozen-lockfile

要更新已安装的模块,可以使用前面的npm installyarn upgrade命令。任一命令都会将软件包更新node_modules到满足中规则的最新版本package.json。但是,它们不会package.json自行更新,您可能需要这样做来设置新的最低版本。如果您托管软件包 GitHub,则可以将 De pendabot 版本更新配置为自动更新package.json或者,请使用 npm-check-updates

重要

根据设计,当您安装或更新依赖项时,NPM 和 Yarn 会选择满足中指定要求的每个软件包的最新版本。package.json这些版本总是存在损坏的风险(无论是意外还是故意)。更新项目的依赖关系后,请进行全面测试。

AWS CDK 中的成语 JavaScript

道具

所有 C AWS onstruct Library 类都使用三个参数进行实例化:定义构造的作用域(构造树中的父级)、idprops(构造函数用来配置其创建的资源的键/值对)。 AWS 其他类和方法也使用 “属性包” 模式作为参数。

使用具有良好 JavaScript 自动完成功能的 IDE 或编辑器将有助于避免拼写错误的属性名称。如果一个构造需要一个encryptionKeys属性,而你拼写了它encryptionkeys,那么在实例化构造时,你还没有传递你想要的值。如果该属性是必需的,则这可能会在合成时导致错误,或者如果该属性是可选的,则会导致该属性被静默忽略。在后一种情况下,你可能会得到一个你打算覆盖的默认行为。这里要特别小心。

对 AWS 构造库类进行子类化(或重写采用类似 props 的参数的方法)时,您可能需要接受其他属性供自己使用。这些值将被父类或重写方法忽略,因为在该代码中永远不会访问它们,因此您通常可以传递收到的所有道具。

future 版本 AWS CDK 可能会巧合地添加一个新属性,其名称是你用于自己的财产。然后,将您收到的值传递到继承链上可能会导致意外行为。如果你的属性被移除或设置为,那么传递一份你收到的道具的浅层副本会更安全。undefined例如:

super(scope, name, {...props, encryptionKeys: undefined});

或者,请命名您的属性,使其清楚地表明它们属于您的构造。这样,它们就不太可能在 future AWS CDK 版本中与属性发生冲突。如果其中有很多,请使用一个命名恰当的对象来存放它们。

缺失值

对象(例如props)中缺失的值具有undefined中的值 JavaScript。通常的技术适用于处理这些问题。例如,访问可能未定义的值的属性的常用惯用法如下:

// a may be undefined, but if it is not, it may have an attribute b // c is undefined if a is undefined, OR if a doesn't have an attribute b let c = a && a.b;

但是,a如果除此之外还有其他的 “假” 值undefined,则最好使测试更加明确。在这里,我们将利用这样一个事实,即nullundefined等于同时测试两者:

let c = a == null ? a : a.b;
提示

Node.js 14.0 及更高版本支持新的运算符,这些运算符可以简化未定义值的处理。有关更多信息,请参阅可选的链接无效合并提案

合成和部署

可以使用以下命令合成 AWS CDK 应用程序中定义的堆栈并单独或一起部署。通常,当你发布它们时,你应该在项目的主目录中。

  • cdk synth:从应用程序中的一个或多个堆栈中 AWS CDK 合成一个 AWS CloudFormation 模板。

  • cdk deploy:将您的 AWS CDK 应用程序中的一个或多个堆栈定义的资源部署到。 AWS

您可以在单个命令中指定要合成或部署的多个堆栈的名称。如果您的应用程序只定义了一个堆栈,则无需指定该堆栈。

cdk synth # app defines single stack cdk deploy Happy Grumpy # app defines two or more stacks; two are deployed

您也可以使用通配符 *(任意数量的字符)和? (任何单个字符),用于按模式识别堆栈。使用通配符时,请用引号将模式括起来。否则,在将文件传递到 T AWS CDK oolkit 之前,shell 可能会尝试将其扩展为当前目录中的文件名。

cdk synth "Stack?" # Stack1, StackA, etc. cdk deploy "*Stack" # PipeStack, LambdaStack, etc.
提示

在部署堆栈之前,您无需显式合成堆栈;请cdk deploy执行此步骤以确保部署最新的代码。

有关该cdk命令的完整文档,请参阅AWS CDK 工具包(cdk命令)

使用 TypeScript 示例 JavaScript

TypeScript是我们用来开发的语言 AWS CDK,也是开发应用程序时支持的第一种语言,因此编写了许多可用的 AWS CDK 代码示例 TypeScript。对于 JavaScript 开发人员来说,这些代码示例可能是一个很好的资源;你只需要删除代码中 TypeScript特定部分即可。

TypeScript 片段通常使用较新的ECMAScript importexport关键字从其他模块导入对象,并声明要在当前模块之外提供的对象。Node.js 刚刚开始在其最新版本中支持这些关键词。根据您正在使用(或希望支持)的 Node.js 版本,您可以重写导入和导出以使用较旧的语法。

可以将导入替换为对require()函数的调用。

TypeScript
import * as cdk from 'aws-cdk-lib'; import { Bucket, BucketPolicy } from 'aws-cdk-lib/aws-s3';
JavaScript
const cdk = require('aws-cdk-lib'); const { Bucket, BucketPolicy } = require('aws-cdk-lib/aws-s3');

可以将导出分配给module.exports对象。

TypeScript
export class Stack1 extends cdk.Stack { // ... } export class Stack2 extends cdk.Stack { // ... }
JavaScript
class Stack1 extends cdk.Stack { // ... } class Stack2 extends cdk.Stack { // ... } module.exports = { Stack1, Stack2 }
注意

使用旧式导入和导出的另一种方法是使用该esm模块。

对导入和导出进行排序后,就可以深入研究实际的代码了。您可能会遇到以下常用功能 TypeScript :

  • 类型注释

  • 接口定义

  • 类型转换/转换

  • 访问修饰符

可以为变量、类成员、函数参数和函数返回类型提供类型注释。对于变量、参数和成员,类型是在标识符后面加上冒号和类型来指定的。函数返回值遵循函数签名,由冒号和类型组成。

要将带类型注释的代码转换为 JavaScript,请删除冒号和类型。类成员中必须有一些值 JavaScript;undefined如果类成员中只有类型注释,则将其设置为 TypeScript。

TypeScript
var encrypted: boolean = true; class myStack extends cdk.Stack { bucket: s3.Bucket; // ... } function makeEnv(account: string, region: string) : object { // ... }
JavaScript
var encrypted = true; class myStack extends cdk.Stack { bucket = undefined; // ... } function makeEnv(account, region) { // ... }

在中 TypeScript,接口用于为必需属性和可选属性的捆绑包及其类型命名。然后,您可以使用接口名称作为类型注释。 TypeScript 将确保你用作函数参数的对象具有正确类型的必需属性。

interface myFuncProps { code: lambda.Code, handler?: string }

JavaScript 没有接口功能,因此删除类型注释后,请完全删除接口声明。

当函数或方法返回通用类型(例如object),但您想将该值视为更具体的子类型以访问不属于更一般类型接口的属性或方法时, TypeScript 允许您使用as后跟类型或接口名称来转换值。 JavaScript 不支持(或不需要)这个,所以只需删除as和以下标识符即可。一种不太常见的强制转换语法是在方括号中使用类型名称<LikeThis>;这些强制转换也必须删除。

最后, TypeScript 支持类成员的访问修饰符publicprotected、和private。中的所有班级成员 JavaScript 都是公开的。只要在任何地方看到这些修饰符即可。

知道如何识别和删除这些 TypeScript 功能对于使简短的 TypeScript片段适应大有帮助. JavaScript 但是,以这种方式转换较长的 TypeScript 示例可能不切实际,因为它们更有可能使用其他 TypeScript 功能。对于这些情况,我们建议使用 Sucras e。例如,如果代码使用未定义的变量,Sucrase 就不会抱怨。tsc如果它在语法上是有效的,那么除了少数例外,Sucrase 可以将其翻译为。 JavaScript这使得它对于转换可能无法单独运行的片段特别有价值。

迁移到 TypeScript

TypeScript随着项目规模越来越大、越来越复杂,许多 JavaScript 开发人员开始使用。 TypeScript 是 JavaScript(所有 JavaScript 代码均为有效代码,因此无需对 TypeScript 代码进行任何更改)的超集,而且它也是一种支持的语言。 AWS CDK 类型注释和其他 TypeScript 功能是可选的,当你发现其中的价值时,可以将其添加到你的 AWS CDK 应用程序中。 TypeScript 还可以让您在新 JavaScript 功能最终确定之前抢先体验这些新功能,例如可选的链接和空值合并,而且无需升级 Node.js。

TypeScript的 “基于形状” 的接口,它定义了对象中的必需和可选属性(及其类型)的捆绑包,允许您在编写代码时发现常见错误,并使您的 IDE 更容易提供强大的自动完成功能和其他实时编码建议。

编程 TypeScript 确实涉及一个额外的步骤:使用编 TypeScript 译器编译应用程序tsc。对于典型的 AWS CDK 应用程序,编译最多需要几秒钟。

将现有 JavaScript AWS CDK 应用程序迁移到的最简单方法 TypeScript 是使用创建新 TypeScript 项目cdk init app --language typescript,然后将源文件(以及任何其他必需的文件,例如 AWS Lambda 函数源代码等资产)复制到新项目。将 JavaScript 文件重命名为结尾.ts并开始开发 TypeScript。