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

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

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

使用 AWS CDK 中的 JavaScript

JavaScript是完全支援的用戶端語言, AWS CDK 且被認為是穩定的。 JavaScript 使用 AWS Cloud Development Kit (AWS CDK) 中的使用熟悉的工具,包括 Node.js 和節點 Package 管理員 (npm)。如果您願意,您也可以使用 Yarn,儘管本指南中的示例使用NPM。包括 AWS 構造庫的模塊通過NPM存儲庫 npm js.org 分佈。

您可以使用任何編輯器或IDE. 許多開 AWS CDK 發人員使用 Visual Studio 代碼(或其開源代碼等價物 VSCodium),該代碼對 JavaScript.

開始使用 JavaScript

若要使用 AWS CDK,您必須擁有 AWS 帳戶和認證,並已安裝 Node.js 和工 AWS CDK 具組。請參閱 開始使用 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 global (npm install -g aws-cdk) 安裝,並且提供的命令示例(例如cdk synth)遵循此假設。這種方法使 CDK Toolkit 保持在最新狀態變得容易,並且由於CDK採用了嚴格的向後兼容性方法,因此始終使用最新版本的風險通常很小。

有些團隊更喜歡指定每個項目中的所有依賴關係,包括工具包之類的工CDK具。這個做法可讓您將這些元件釘選到特定版本,並確保您團隊中的所有開發人員 (以及您的 CI/CD 環境) 都完全使用這些版本。這消除了可能的變更來源,有助於使組建和部署更加一致且可重複。

JavaScript 項目模板中CDK包含 CDK Toolkit 的依賴項package.json,因此,如果您想使用此方法,則不需要對項目進行任何更改。您需要做的就是使用稍微不同的命令來構建您的應用程序和發出cdk命令。

作業 使用全域CDK工具組 使用本機CDK工具組
初始化專案 cdk init --language javascript npx aws-cdk init --language javascript
執行CDK工具組命令 cdk ... npm run cdk ...npx aws-cdk ...

npx aws-cdk執行在目前專案中本機安裝的 CDK Toolkit 版本 (如果有的話),回溯至全域安裝 (如果有的話)。如果沒有全域安裝,請npx下載 CDK Toolkit 的暫存副本並執行該副本。您可以使用以下@語法指定CDK工具包的任意版本:npx aws-cdk@1.120 --versionprint 1.120.0

提示

設定別名,以便您可以在本機 CDK Toolkit 安裝中使用cdk指令。

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

管理 AWS 建構程式庫模組

使用節點 Package 件管理員 (npm) 安裝和更新「 AWS 建構程式庫」模組,以供您的應用程式使用,以及您需要的其他套件。(npm如果您願意,您可以使用yarn而不是。) npm還會自動為這些模塊安裝依賴關係。

大多數 AWS CDK 構造都在主CDK包中,名為aws-cdk-lib,它是由cdk init創建的新項目中的默認依賴項。「實驗」 AWS 構造庫模塊,其中更高級別的構造仍在開發中,命名為類似。aws-cdk-lib/SERVICE-NAME-alpha服務名稱具有 aws- 前綴。如果您不確定模塊的名稱,請在上搜索它NPM

注意

CDKAPI參考」也會顯示套件名稱。

例如,以下指令會安裝的實驗模組 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

在JavaScriptCDK專案中,相依性會在專package.json案的主目錄中的檔案中指定。核心 AWS CDK 模塊位於一個NPM名為aws-cdk-lib.

當您使用安裝套件時npm install,會package.json為您NPM記錄套件。

如果您願意,您可以使用紗線代替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必須在的一dependenciespackage.json節中指定。您可以使用脫字符號 (^) 版本編號說明符來表示您將接受比指定版本更新的版本,只要它們位於相同的主要版本中即可。

對於實驗結構,請為 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,使用脫字符號 (^) 來指定您的程式庫可使用aws-cdk-lib的最低版本。這樣可以最大限度地提高庫與一系列CDK版本的兼容性。指定 Alpha 建構程式庫模組的確切版本,這些模組APIs可能會變更。peerDependencies使用可確保node_modules樹中只有一個所有CDK資源庫的複本。

在中devDependencies,指定測試所需的工具和程式庫,選擇性地使用 ^ 表示可接受更新的相容版本。請確實指定 (不含 ^ 或 ~) 最低版本,以aws-cdk-lib及您公告程式庫相容的其他CDK套件。此做法可確保您的測試會針對這些版本執行。這樣,如果您無意中使用了僅在較新版本中找到的功能,則測試可以 catch 它。

警告

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 構造庫類都使用三個參數實例化:正在定義構造的範圍(它在構造樹中的父級),一個 idprop,構造用於配置它創建的 AWS 資源的鍵/值對的包。其他類和方法也使用「屬性包」模式作為參數。

使用具有良好 JavaScript 自動完成功能的IDE或編輯器將有助於避免屬性名稱拼寫錯誤。如果一個構造期待一個encryptionKeys屬性,並且你拼寫它encryptionkeys,在實例化構造時,你還沒有傳遞你想要的值。如果需要屬性,這可能會在合成時導致錯誤,或者如果屬性是可選的,則會導致無訊息地忽略該屬性。在後一種情況下,您可能會得到您打算覆蓋的默認行為。在這裡特別小心。

當對一個 AWS 構造庫類進行子類(或者覆蓋採用類似於 prop 的參數的方法)時,您可能需要接受其他屬性以供自己使用。這些值將被父類或重寫的方法忽略,因為它們永遠不會在該代碼中訪問,所以你通常可以傳遞你收到的所有 prop。

的 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,最好使測試更加明確。在這裡,我們將利用null並且等undefined於一次測試它們的事實:

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

Node.js 14.0 及更新版本支援可簡化處理未定義值的新運算子。有關更多信息,請參閱可選鏈接空合併提案。

使用 TypeScript 範例 JavaScript

TypeScript是我們用來開發的語言 AWS CDK,而且它是開發應用程式所支援的第一種語言,因此許多可用的程式 AWS CDK 碼範例都是用來編寫的 TypeScript。這些代碼示例對於 JavaScript 開發人員來說可能是一個很好的資源; 你只需要刪除代碼的 TypeScript特定部分。

TypeScript 程式碼片段通常使用較新的ECMAScriptimportexport關鍵字從其他模組匯入物件,並宣告要在目前模組外部使用的物件。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 功能。對於這些情況,我們建議使用 Sucrase。例如,如果代碼使用未定義的變量,Sucrase 就不會抱怨。tsc如果它在語法上是有效的,那麼除了少數例外,Sucrase 可以將其翻譯為。 JavaScript這使得它對於轉換可能無法自行執行的程式碼片段特別有用。

移轉至 TypeScript

許多 JavaScript 開發人員轉移到TypeScript他們的項目變得越來越大,更複雜。 TypeScript 是 JavaScript —all 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.