[英]How to debug in VS Code a local AWS Lambda function with API Gateway written in TypeScript?
We are about to start working with Lambda functions.我们即将开始使用 Lambda 函数。
We have that technology constraint that we have to use TypeScript.我们有必须使用 TypeScript 的技术限制。
I want to be able to debug my ts file in VS Code when the related endpoint is called from Postman.当从 Postman 调用相关端点时,我希望能够在 VS Code 中调试我的 ts 文件。
So, we have the following development environment:所以,我们有如下的开发环境:
I've used sam init
with the Hello World template to generate the initial folder structure.我使用sam init
和 Hello World 模板来生成初始文件夹结构。
I've enhanced it (mostly based on this article ) to work with TypeScript.我已经对其进行了增强(主要基于这篇文章)以使用 TypeScript。
.
├── template.yaml
├── .aws-sam
├── .vscode
| └── launch.json
├── events
├── hello-world
| ├── dist
| ├── app.js
| └── app.js.map
| ├── src
| └── app.ts
| ├── package.json
| └── tsconfig.json
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
LambdaWithApiGateWayDebug
Sample SAM Template for LambdaWithApiGateWayDebug
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/dist
Handler: app.lambdaHandler
Runtime: nodejs12.x
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"sourceMap": true,
"outDir": "./dist",
"strict": true,
"noImplicitAny": true,
"esModuleInterop": true,
"sourceRoot": "./src",
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
package.json
{
"name": "hello_world",
"version": "1.0.0",
"description": "hello world sample for NodeJS",
"main": "app.js",
"repository": "https://github.com/awslabs/aws-sam-cli/tree/develop/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs",
"scripts": {
"compile": "tsc",
"start": "sam local start-api -t ../template.yaml -p 5000 -d 5678"
},
"dependencies": {
"@types/aws-lambda": "^8.10.64",
"@types/node": "^14.14.10",
"aws-sdk": "^2.805.0",
"source-map-support": "^0.5.19",
"typescript": "^4.1.2"
}
}
app.ts
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda";
export const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
const queries = JSON.stringify(event.queryStringParameters);
return {
statusCode: 200,
body: `Queries: ${queries}`
}
}
app.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.lambdaHandler = void 0;
const lambdaHandler = async (event) => {
const queries = JSON.stringify(event.queryStringParameters);
return {
statusCode: 200,
body: `Queries: ${queries}`
};
};
exports.lambdaHandler = lambdaHandler;
//# sourceMappingURL=app.js.map
app.js.map
{"version":3,"file":"app.js","sourceRoot":"./src/","sources":["app.ts"],"names":[],"mappings":";;;AAEO,MAAM,aAAa,GAAG,KAAK,EAAE,KAA2B,EAAkC,EAAE;IAC/F,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC5D,OAAO;QACL,UAAU,EAAE,GAAG;QACf,IAAI,EAAE,YAAY,OAAO,EAAE;KAC5B,CAAA;AACL,CAAC,CAAA;AANY,QAAA,aAAa,iBAMzB"}
launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "attach Program",
"port": 5678,
"address": "localhost",
"localRoot": "${workspaceFolder}/hello-world/dist",
"remoteRoot": "/var/task",
"protocol": "inspector",
"sourceMaps": true,
"smartStep": true,
"outFiles": ["${workspaceFolder}/hello-world/dist"]
}
]
}
As you can see:如你看到的:
hello-world/src/app.ts
我的 lambda function 定义在hello-world/src/app.ts
hello-world/dist/app.js
with sourcemap它符合 commonJs 和 ES2020 目标到hello-world/dist/app.js
和 sourcemaphello-world/dist
via the localhost:5000/hello
endpoint该模板通过localhost:5000/hello
端点公开位于hello-world/dist
下的处理程序 So, when I call npm run start
then it prints the following output:因此,当我调用npm run start
,它会打印以下 output:
> hello_world@1.0.0 start C:\temp\AWS\LambdaWithApiGateWayDebug\hello-world
> sam local start-api -t ../template.yaml -p 5000 -d 5678
Mounting HelloWorldFunction at http://127.0.0.1:5000/hello [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2020-12-08 11:40:48 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
When I make a request against the endpoint via Postman then the console is extended with the following text:当我通过 Postman 向端点发出请求时,控制台将扩展为以下文本:
Mounting C:\temp\AWS\LambdaWithApiGateWayDebug\hello-world\dist as /var/task:ro,delegated inside runtime container
START RequestId: 04d884cf-fa96-4d58-b41c-e4196e12de13 Version: $LATEST
Debugger listening on ws://0.0.0.0:5678/d6702717-f291-42cd-8056-22b9f029f4dd
For help, see: https://nodejs.org/en/docs/inspector
When I attach my VS Code to the node process then I can only debug the app.js
and not the app.ts
.当我将 VS Code 附加到节点进程时,我只能调试app.js
而不能调试app.ts
。
End of the console log:控制台日志结束:
Debugger attached.
END RequestId: 04d884cf-fa96-4d58-b41c-e4196e12de13
REPORT RequestId: 04d884cf-fa96-4d58-b41c-e4196e12de13 Init Duration: 0.12 ms Duration: 7064.19 ms Billed Duration: 7100 ms Memory Size: 128 MB Max Memory Used: 128 MB
No Content-Type given. Defaulting to 'application/json'.
2020-12-08 11:40:58 127.0.0.1 - - [08/Dec/2020 11:40:58] "GET /hello HTTP/1.1" 200 -
What should I change to be able to debug my app.ts
instead of app.js
?我应该改变什么才能调试我的app.ts
而不是app.js
?
I wrote a medium article explaining how to create, invoke and debug a TypeScript lambda function.我写了一篇中篇文章,解释如何创建、调用和调试 TypeScript lambda function。 Please for more details check the following link .请查看以下链接了解更多详情。
Requirements要求
1- Create a nodejs12x; 1-创建一个nodejs12x;
Create a nodejs12x lambda;创建一个nodejs12x lambda;
Install TypeScript: npm i -g typescript
安装 TypeScript: npm i -g typescript
Initialize typescript: tsc --init
(It will create the tsconfig.json file)初始化 typescript: tsc --init
(它将创建 tsconfig.json 文件)
Replace the created tsconfig.json file with the following code:将创建的 tsconfig.json 文件替换为以下代码:
{ "compilerOptions": { "module": "CommonJS", "target": "ES2017", "noImplicitAny": true, "preserveConstEnums": true, "outDir": "./built", "sourceMap": true }, "include": ["handler/**/*"], "exclude": ["node_modules", "**/*.spec.ts"] }
Delete app.js file;删除 app.js 文件;
Create your lambda in TypeScript code inside of handler folder (you need o create it):在处理程序文件夹内的 TypeScript 代码中创建 lambda (您需要创建它):
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda"; export const lambdaHandler = async ( event: APIGatewayProxyEvent ): Promise<APIGatewayProxyResult> => { const queries = JSON.stringify(event.queryStringParameters); return { statusCode: 200, body: `Queries: ${queries}` } }
Adapt the template.yaml.适配模板.yaml。 Change the CodeUri path of your lambda: CodeUri: hello-world/built
更改 lambda 的 CodeUri 路径: CodeUri: hello-world/built
Install the needed node packages: npm install typescript @types/aws-lambda @types/node -save-dev
安装所需的节点包: npm install typescript @types/aws-lambda @types/node -save-dev
Package json: Package json:
{ "name": "typescript_lambda", "version": "1.0.0", "description": "hello world sample for TypeScript", "main": "app.js", "repository": "https://github.com/jafreitas90/AWS", "author": "Jorge Freitas", "license": "JorgeFreitas Ltd:)", "dependencies": { }, "scripts": { "compile": "tsc" }, "devDependencies": { "@types/aws-lambda": "^8.10.71", "@types/node": "^14.14.22", "aws-sdk": "^2.815.0", "typescript": "^4.1.3" } }
npm install npm安装
npm run compile npm 运行编译
Set a breakpoint in your lambda function (TypeScript code).在 lambda function(TypeScript 代码)中设置断点。 On the left panel select Debug and then Start debugging (green button on top).在左侧面板上 select 调试然后开始调试(顶部的绿色按钮)。 And that's it:)就是这样:)
Project structure项目结构
As it turned out I have made two tiny mistakes:事实证明,我犯了两个小错误:
I've set sourceRoot
inside tsconfig.json
which is unnecessary in this case.我在tsconfig.json
中设置sourceRoot
,在这种情况下这是不必要的。 include
is enough: include
就足够了:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"sourceMap": true,
"outDir": "./dist",
"strict": true,
"noImplicitAny": true,
"esModuleInterop": true,
// "sourceRoot": "./src",
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
I've set two breakpoints: one inside app.js
and another inside app.ts
.我设置了两个断点:一个在app.js
中,另一个在app.ts
中。
As it turned out if app.js
does have a breakpoint then the other one will not be trigger.事实证明,如果app.js
确实有断点,则不会触发另一个断点。
So after I've removed the breakpoint from app.js
then the debugger stopped inside the app.ts
.因此,在我从app.js
中删除断点后,调试器在app.ts
内停止。
Your Lambda's runtime is JavaScript, yet you write your code in TypeScript.您的 Lambda 运行时是 JavaScript,但您在 TypeScript 中编写代码。 When you use TypeScript, behind the scenes the compiler is converting your code to JavaScript which is the debuggable code.当您使用 TypeScript 时,编译器会在后台将您的代码转换为可调试代码 JavaScript。
In another words, you code your lambda in TS, complier then converts it to JS which at the end is the code that gets executed and can be debugged.换句话说,您在 TS 中编写 lambda 代码,编译器然后将其转换为 JS,最后是可以执行并可以调试的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.