这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。
在 TypeScript 中使用 AWS CDK
TypeScript 是一种 AWS Cloud Development Kit (AWS CDK) 完全支持且视为稳定的客户端语言。在 TypeScript 中使用 AWS CDK 采用了熟悉的工具,包括 Microsoft 的 TypeScript 编译器 (tsc
)、Node.jsnpm
)。如果您愿意,也可以使用 Yarn
您可以使用任何编辑器或 IDE。许多 AWS CDK 开发人员都使用 Visual Studio Code
主题
开始使用 TypeScript
要使用 AWS CDK,您必须拥有 AWS 账户和凭证,并已安装 Node.js 和 AWS CDK Toolkit。请参阅 开始使用 AWS CDK。
您还需要 TypeScript 本身(版本 3.8 或更高版本)。如果您还没有 TypeScript,可使用 npm
进行安装。
npm install -g typescript
注意
如果遇到权限错误,且在系统上拥有管理员访问权限,请尝试 sudo npm install -g
typescript
。
通过定期的 npm update -g typescript
让 TypeScript 保持为最新版本。
注意
第三方语言弃用:语言版本仅在供应商或社区共享其 EOL(生命周期终止)之前才受支持,如有更改,会另行通知。
创建项目
您可以通过在空目录中调用 cdk init
来创建一个新的 AWS CDK 项目。使用 --language
选项并指定 typescript
:
mkdir my-project cd my-project cdk init app --language typescript
创建项目还会安装 aws-cdk-lib
模块及其依赖项。
cdk init
使用项目文件夹的名称来命名项目的各种元素,包括类、子文件夹和文件。文件夹名称中的连字符都将转换为下划线。但是,名称应遵循 TypeScript 标识符的形式;例如,名称不应以数字开头,也不应包含空格。
使用本地 tsc
和 cdk
在大多数情况下,本指南假设您已全局安装 TypeScript 和 CDK Toolkit (npm install -g
typescript aws-cdk
),并且提供的命令示例(例如 cdk synth
)也遵循此假设。这种方法可以很容易让两个组件保持为最新版本,并且由于两者都采取了严格的向后兼容性方法,所以始终使用最新版本通常风险很小。
有些团队更喜欢在每个项目中指定所有依赖项,包括 TypeScript 编译器和 CDK Toolkit 等工具。通过这种做法,您可以将这些组件固定到特定版本,并确保团队中的所有开发人员(以及您的 CI/CD 环境)都正好使用这些版本。这从根源上消除了可能发生的变更,有助于使构建和部署更加一致且可重复。
CDK 在 TypeScript 项目模板的 package.json
中包含了 TypeScript 和 CDK Toolkit 的依赖项,因此,如果您想使用这种方法,无需对项目进行任何更改。您所需要做的就是使用稍微不同的命令来构建应用程序以及发出 cdk
命令。
操作 | 使用全局工具 | 使用本地工具 |
---|---|---|
初始化项目 | cdk init --language typescript |
npx aws-cdk init --language typescript |
构建 | tsc |
npm run build |
运行 CDK Toolkit 命令 | cdk ... |
npm run cdk ... or npx aws-cdk ... |
npx aws-cdk
运行当前项目中本地安装的 CDK Toolkit 版本(如果存在),如有则回退到全局安装。如果不存在全局安装,则 npx
会下载 CDK Toolkit 的临时副本并运行该副本。您可以使用 @
语法(npx aws-cdk@2.0 --version
打印 2.0.0
)来指定 CDK Toolkit 的任意版本。
提示
设置别名,以便您可以在安装本地 CDK Toolkit 时使用 cdk
命令。
管理 AWS 构造库模块
使用节点软件包管理器 (npm
) 来安装和更新供您应用程序使用的 AWS 构造库模块以及您需要的其他软件包。(如果您愿意,可以用 yarn
代替 npm
。)npm
还会自动安装这些模块的依赖项。
大多数 AWS CDK 构造都位于名为 aws-cdk-lib
的 CDK 主包中,这是 cdk init 创建的新项目中的默认依赖项。“实验性”AWS 构造库模块(其中更高级别的构造仍在开发中)的命名类似于 @aws-cdk/
。服务名称带有 aws- 前缀。如果您不确定某个模块的名称,请在 NPM 上进行搜索SERVICE-NAME
-alpha
注意
CDK API Reference 也显示了包名称。
例如,以下命令用于安装 AWS CodeStar 的实验模块。
npm install @aws-cdk/aws-codestar-alpha
某些服务的构造库支持位于多个命名空间中。例如,除 aws-route53
之外,还有另外三个 Amazon Route 53 命名空间,分别是 aws-route53-targets
、aws-route53-patterns
和 aws-route53resolver
。
您项目的依赖项在 package.json
中进行维护。您可以编辑此文件,将部分或全部依赖项锁定到特定版本,或者允许在特定条件下将其更新到较新版本。根据您在以下 package.json
中指定的规则,将项目的 NPM 依赖项更新到允许的最新版本:
npm update
在 TypeScript 中,您可以将模块导入到代码中,其名称与使用 NPM 安装模块时使用的名称相同。在应用程序中导入 AWS CDK 类和 AWS 构造库模块时,我们建议采用以下做法。遵循这些准则将有助于让您的代码与其他 AWS CDK 应用程序保持一致并更易于理解。
-
请使用 ES6 风格的
import
指令,而非require()
。 -
通常,从
aws-cdk-lib
中导入单个类。import { App, Stack } from 'aws-cdk-lib';
-
如果您需要
aws-cdk-lib
中的许多类,则可以使用cdk
的命名空间别名,而不是导入单个类。避免同时执行这两项操作。import * as cdk from 'aws-cdk-lib';
-
通常,使用短命名空间别名来导入 AWS 服务构造。
import { aws_s3 as s3 } from 'aws-cdk-lib';
在 TypeScript 中管理依赖项
在 TypeScript CDK 项目中,在项目主目录的 package.json
文件中指定依赖项。核心 AWS CDK 模块位于名为 aws-cdk-lib
的单个 NPM 包中。
当您使用 npm install 来安装包时,NPM 会在 package.json
中记录该包。
如果您愿意,可以用 Yarn 代替 NPM。但是,CDK 不支持 Yarn 的即插即用模式,该模式是 Yarn 2 中的默认模式。将以下内容添加到项目的 .yarnrc.yml
文件以关闭此功能。
nodeLinker: node-modules
CDK 应用程序
以下是 cdk init --language
typescript
命令生成的示例 package.json
文件:
{ "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 应用程序,必须在 package.json
的 dependencies
部分中指定 aws-cdk-lib
。您可以使用脱字符(^)版本号说明符来表示您将接受比指定版本更高的版本,前提是它们位于同一个主版本内。
对于实验性构造,请为 alpha 构造库模块指定确切版本,这些模块的 API 可能会发生更改。请勿使用 ^ 或 ~,因为这些模块的更高版本可能会导致 API 发生更改,从而导致您的应用程序中断。
在 package.json
的 devDependencies
部分中指定测试应用程序所需的库和工具版本(例如,jest
测试框架)。或者使用 ^ 来指定可接受更高版本的兼容版本。
第三方构造库
如果您正在开发构造库,请结合 peerDependencies
和 devDependencies
部分来指定其依赖项,如以下示例 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 软件包的最低版本。这种做法可确保您的测试是针对这些版本运行的。这样,如果您无意中使用了仅较新版本中具备的功能,则您的测试可以将其捕捉到。
警告
只有 NPM 7 及更高版本才能自动安装 peerDependencies
。如果您使用的是 NPM 6 或更早版本,或者使用的是 Yarn,则必须在 devDependencies
中包含依赖项的依赖项。否则,将不会进行安装,并且您将收到有关对等依赖项未解决的警告。
安装和更新依赖项
使用以下命令来安装项目的依赖项。
要更新已安装的模块,可以使用前面的 npm install 和 yarn upgrade 命令。任一命令都会将 node_modules
中的软件包更新为可满足 package.json
中规则的最新版本。但是,它们不会更新 package.json
本身,您可能需要执行此操作来设置新的最低版本。如果您将包托管在 GitHub 上,则可以配置 Dependabot 版本更新package.json
。或者,可以使用 npm-check-updates
重要
根据设计,当您安装或更新依赖项时,NPM 和 Yarn 会选择可满足 package.json
中指定要求的每个包的最新版本。这些版本始终存在损坏风险(无论是无意还是有意)。更新项目的依赖项后,请彻底进行测试。
TypeScript 中的 AWS CDK 习语
Props
所有 AWS 构造库类都使用三个参数进行实例化:在其中定义构造的 scope(构造树中的父级)、id 和 props。props 参数是键/值对捆绑包,构造使用这些键/值对来配置其创建的 AWS 资源。其他类和方法也使用“属性捆绑包”模式作为参数。
在 TypeScript 中,props
的形状是使用一个接口定义的,该接口可显示必需参数和可选参数及其类型。为每种 props
参数定义一个此类接口,通常特定于单个构造或方法。例如,存储桶构造(在 aws-cdk-lib/aws-s3 module
中)指定符合 BucketProps 接口的 props
参数。
如果属性本身就是一个对象,例如 BucketProps
的 websiteRedirect 属性,则该对象将拥有自己的接口,其形状必须符合该接口,在本例中为 RedirectTarget。
如果正在子类化一个 AWS 构造库类(或重写采用类似 props 参数的方法),则可以从现有接口继承来创建一个新接口,该新接口可指定您的代码所需的任何新 props。在调用父类或基方法时,通常可以传递收到的整个 props 参数,因为对象中提供但未在接口中指定的所有属性都将被忽略。
AWS CDK 的未来版本可能会碰巧添加一个新属性,其名称与您用于自己属性的名称相同。将收到的值沿继承链向上传递可能会导致意外行为。更安全的做法是传递您收到的 props 的浅副本,同时删除属性或将其设置为 undefined
。例如:
super(scope, name, {...props, encryptionKeys: undefined});
或者,为您的属性命名,以便清楚地表明它们属于您的构造。这样,其就不太可能在未来的 AWS CDK 版本中与属性发生冲突。如果有很多属性,请使用一个适当命名的对象来存放它们。
缺失值
对象中的缺失值(例如 props)在 TypeScript 中的值为 undefined
。该语言的 3.7 版本引入了简化处理这些值的运算符,这样在达到未定义的值时就能更容易指定默认值和“短路”链接。有关这些功能的更多信息,请参阅 TypeScript 3.7 发行说明
构建和运行 CDK 应用程序
通常,构建和运行应用程序时,您应位于项目的根目录中。
Node.js 无法直接运行 TypeScript;相反,使用 TypeScript 编译器 tsc
将您的应用程序转换到 JavaScript。然后执行生成的 JavaScript 代码。
每当需要运行您的应用程序时,AWS CDK 都会自动执行此操作。但是,手动编译以检查错误并运行测试可能会很有用。要手动编译您的 TypeScript 应用程序,请发出 npm run
build
命令。您也可以发出 npm run watch
命令进入监视模式,在这种模式下,每当您保存对源文件的更改时,TypeScript 编译器都会自动重建您的应用程序。