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

這是 AWS CDK v2 開發人員指南。較舊的 CDK v1 已於 2022 年 6 月 1 日進入維護,並於 2023 年 6 月 1 日結束支援。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

在 JavaScript AWS CDK 中使用

JavaScript 是 完全支援的用戶端語言, AWS CDK 且被視為穩定。在 JavaScript AWS Cloud Development Kit (AWS CDK) 中使用 會使用熟悉的工具,包括 Node.js 和 Node Package Manager (npm)。如果您願意,也可以使用 Yarn,但本指南中的範例使用 NPM。包含 AWS Construct Library 的模組會透過 NPM 儲存庫 npmjs.org 進行分發。

您可以使用任何編輯器或 IDE。許多 AWS CDK 開發人員使用 Visual 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 Toolkit 使用本機 CDK Toolkit
初始化專案 cdk init -- 語言 javascript npx aws-cdk init --language javascript
執行 CDK Toolkit 命令 cdk ... npm 執行 cdk ... or npx aws-cdk ...

npx aws-cdk 會執行目前專案中於本機安裝的 CDK Toolkit 版本,如果有的話,請返回全域安裝。如果沒有全域安裝, 會npx下載 CDK Toolkit 的臨時複本並執行該複本。您可以使用語法:npx aws-cdk@1.120 --version列印 @ 來指定 CDK Toolkit 的任意版本1.120.0

提示

設定別名,以便您可以搭配本機 CDK Toolkit 安裝使用 cdk命令。

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

管理 AWS 建構程式庫模組

使用 Node Package Manager (npm) 來安裝和更新 AWS Construct Library 模組,以供您的應用程式以及您需要的其他套件使用。(npm您可以yarn改為使用 。) npm也會自動安裝這些模組的相依性。

大多數 AWS CDK 建構都位於名為 的主 CDK 套件中aws-cdk-lib,這是 所建立新專案的預設相依性cdk init。"Experimental" AWS Construct Library 模組,其中更高層級的建構仍在開發中,命名為 aws-cdk-lib/SERVICE-NAME-alpha。服務名稱具有 aws 字首。如果您不確定模組的名稱,請在 NPM 上搜尋

注意

CDK API 參考也會顯示套件名稱。

例如,以下命令會安裝實驗模組 for AWS CodeStar。

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

有些服務的建構程式庫支援位於多個命名空間中。例如,除了 之外aws-route53,還有三個額外的 Amazon Route 53 命名空間:aws-route53-targetsaws-route53-patternsaws-route53resolver

您專案的相依性會在 中維護package.json。您可以編輯此檔案,將部分或全部相依性鎖定至特定版本,或允許在特定條件下將其更新至較新的版本。若要根據您在 中指定的規則,將專案的 NPM 相依性更新至最新允許的版本package.json

npm update

在 JavaScript 中,您可以使用使用 NPM 安裝模組的相同名稱,將模組匯入您的程式碼。我們建議您在應用程式中匯入 AWS CDK 類別和 AWS 建構程式庫模組時採用下列實務。遵循這些準則有助於讓您的程式碼與其他 AWS CDK 應用程式保持一致,以及更易於理解。

  • 使用 require(),而非 ES6-styleimport指令。較舊版本的 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。您可以使用 caret (^) 版本編號指定詞,指出只要版本位於相同的主要版本,您接受的版本會比指定的版本更高。

對於實驗建構,請指定 alpha 建構程式庫模組的確切版本,這些模組具有可能會變更APIs。請不要使用 ^ 或 ~,因為這些模組的較新版本可能會帶來 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,使用 caret (^) 指定aws-cdk-lib程式庫使用的最低版本。這可最大限度地提高程式庫與各種 CDK 版本的相容性。指定 alpha 建構程式庫模組的確切版本,這些模組具有可能會變更APIs。使用 peerDependencies可確保樹狀目錄中只有一個 CDK node_modules 程式庫的副本。

在 中devDependencies,指定測試所需的工具和程式庫,選擇性地使用 ^ 來表示可接受較新的相容版本。準確指定 (不含 ^ 或 ~) 您公告程式庫的 aws-cdk-lib和其他 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 上託管套件,您可以設定 Dependabot 版本更新以自動更新 package.json。或者,使用 npm-check-updates

重要

根據設計,當您安裝或更新相依性時,NPM 和 Yarn 會選擇符合 中指定需求的每個套件的最新版本package.json。這些版本一律有損壞的風險 (意外或刻意)。更新專案的相依性後,請徹底測試。

AWS CDK JavaScript 中的慣用語

道具

所有 AWS 建構程式庫類別都是使用三個引數來執行個體化:定義建構體的範圍 (其在建構樹狀結構中的父系)、idprops,這是建構體用來設定其建立之 AWS 資源的金鑰/值對套件。其他類別和方法也會使用「屬性組合」模式做為引數。

使用具有良好 JavaScript 自動完成功能的 IDE 或編輯器,有助於避免屬性名稱拼寫錯誤。如果建構正在預期 encryptionKeys 屬性,而您拼寫它encryptionkeys,則當您執行個體化建構時,您尚未傳遞預期的值。如果需要 屬性,這可能會在合成時間造成錯誤,或者如果是選用,則會導致該屬性被無提示忽略。在後一種情況下,您可能會收到要覆寫的預設行為。請特別注意此處。

將 AWS Construct Library 類別 (或覆寫採用類似 props 引數的方法) 子分類時,您可能想要接受其他屬性以供自己使用。這些值會被父類別或覆寫方法忽略,因為它們永遠不會存取該程式碼,因此您通常可以傳遞您收到的所有道具。

未來的 版本 AWS CDK 可能會同時新增具有您用於自有屬性名稱的新屬性。然後,傳遞您收到的繼承鏈值可能會導致意外行為。將屬性移除或設定為 時收到的道具淺版傳遞給 會更安全undefined。例如:

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

或者,為您的屬性命名,以便清楚它們屬於您的建構。如此一來,它們不太可能在未來 AWS CDK 版本中與屬性碰撞。如果其中有許多,請使用單一適當命名的物件來保留它們。

缺少值

物件 (例如 props) 中的遺失值,其值位於 JavaScript undefined中。通常的技術適用於處理這些技巧。例如,存取可能未定義之值屬性的常見慣用語如下所示:

// 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 及更新版本支援可簡化未定義值處理的新運算子。如需詳細資訊,請參閱選用的鏈結Nullish Coalescing 提案。

搭配 JavaScript 使用 TypeScript 範例

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 支援類別private成員的存取修飾詞 protectedpublic和 。JavaScript 中的所有類別成員都是公開的。只需在您看到這些修飾詞的地方將其移除。

了解如何識別和移除這些 TypeScript 功能,對於將簡短 TypeScript 程式碼片段適應 JavaScript 有很大的幫助。但是,以這種方式轉換較長的 TypeScript 範例可能不切實際,因為它們更有可能使用其他 TypeScript 功能。對於這些情況,我們建議使用 Sucrase。例如,如果程式碼使用未定義的變數,則 Sucrase 不會tsc抱怨。如果其在語法上有效,則 Sucrase 可以將其轉譯為 JavaScript。這對於轉換可能無法自行執行的程式碼片段特別重要。

遷移至 TypeScript

許多 JavaScript 開發人員會隨著專案變得更大且更複雜,而遷移至 TypeScript。TypeScript 是 JavaScript 的超級集,所有 JavaScript 程式碼都是有效的 TypeScript 程式碼,因此不需要變更程式碼,而且也是支援 AWS CDK 的語言。類型註釋和其他 TypeScript 功能是選用的,您可以在應用程式中找到值時將其新增至 AWS CDK 應用程式中。TypeScript 也可讓您在最終確定之前提早存取新的 JavaScript 功能,例如選用的鏈結和 Nullish Coalescing,而且不需要升級 Node.js。

TypeScript 的「形狀型」界面,可定義 物件內必要和選用屬性 (及其類型) 的套件,允許在您撰寫程式碼時攔截常見錯誤,並讓您的 IDE 更輕鬆地提供強大的自動完成和其他即時編碼建議。

TypeScript 中的編碼確實涉及一個額外步驟:使用 TypeScript 編譯器 編譯您的應用程式tsc。對於典型 AWS CDK 應用程式,編譯最多需要幾秒鐘。

將現有 JavaScript AWS CDK 應用程式遷移至 TypeScript 的最簡單方法是使用 建立新的 TypeScript 專案cdk init app --language typescript,然後將您的來源檔案 (以及任何其他必要的檔案,例如 AWS Lambda 函數原始碼等資產) 複製到新專案。重新命名您的 JavaScript 檔案以結束,.ts並在 TypeScript 中開始開發。