mcpField
A
aws-lambda-typescript-integration

aws-lambda-typescript-integration

github.com/giuseppe-trisciuoglio云与 DevOps3653.6k 次安装7 周前更新
代码仓库

关于 aws-lambda-typescript-integration

为 TypeScript AWS Lambda 开发提供实践指南,帮助开发者在 NestJS 与原生 TypeScript 方案间选择。内容涵盖冷启动优化、API Gateway 或 ALB 接入及部署流程。

主要功能

  1. 01NestJS 与原生 TypeScript 模式
  2. 02冷启动优化指南
  3. 03API Gateway 和 ALB 接入
  4. 04无服务器部署与 CI/CD
  5. 05测试和部署验证

适用场景

  1. 01为新的 Lambda 选择实现方案
  2. 02缩短函数冷启动时间
  3. 03配置 API Gateway 或 ALB 端点
  4. 04搭建 Lambda 部署流水线

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill aws-lambda-typescript-integration

安装后在 Claude Code 中输入/aws-lambda-typescript-integration确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
express-adapter.md
fastify-adapter.md
nestjs-lambda.md
raw-typescript-lambda.md
serverless-config.md
serverless-deployment.md
testing.md

详细介绍

AWS Lambda TypeScript 集成

使用 TypeScript 创建高性能 AWS Lambda 函数并优化冷启动的模式。

概述

使用 TypeScript 编写 Lambda 有两种方式:

  1. NestJS 框架 - 依赖注入、模块化架构,打包体积较大(100KB+)
  2. 原生 TypeScript - 开销极低,打包体积较小(<50KB),控制力最大

两种方式都支持与 API Gateway 和 ALB 集成。

适用场景

  • 使用 TypeScript 创建新的 Lambda 函数
  • 优化冷启动性能
  • 在 NestJS 和精简 TypeScript 之间进行选择
  • 配置 API Gateway 或 ALB 集成
  • 为 TypeScript Lambda 设置 CI/CD

操作说明

1. 选择实现方式
实现方式冷启动打包体积适用场景复杂度
NestJS< 500ms较大(100KB+)复杂 API、企业应用、需要 DI 的场景中
原生 TypeScript< 100ms较小(< 50KB)简单处理程序、微服务、依赖极少的场景低
2. 项目结构
NestJS 结构
my-nestjs-lambda/
├── src/
│   ├── app.module.ts
│   ├── main.ts
│   ├── lambda.ts           # Lambda entry point
│   └── modules/
│       └── api/
├── package.json
├── tsconfig.json
└── serverless.yml
原生 TypeScript 结构
my-ts-lambda/
├── src/
│   ├── handlers/
│   │   └── api.handler.ts
│   ├── services/
│   └── utils/
├── dist/                   # Compiled output
├── package.json
├── tsconfig.json
└── template.yaml
3. 实现示例

详细的实现指南请参阅参考资料部分。以下是简单示例:

NestJS 处理程序:

// lambda.ts
import { NestFactory } from '@nestjs/core';
import { ExpressAdapter } from '@nestjs/platform-express';
import serverlessExpress from '@codegenie/serverless-express';
import { Context, Handler } from 'aws-lambda';
import express from 'express';
import { AppModule } from './src/app.module';

let cachedServer: Handler;

async function bootstrap(): Promise<Handler> {
  const expressApp = express();
  const adapter = new ExpressAdapter(expressApp);
  const nestApp = await NestFactory.create(AppModule, adapter);
  await nestApp.init();
  return serverlessExpress({ app: expressApp });
}

export const handler: Handler = async (event: any, context: Context) => {
  if (!cachedServer) {
    cachedServer = await bootstrap();
  }
  return cachedServer(event, context);
};

原生 TypeScript 处理程序:

// src/handlers/api.handler.ts
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';

export const handler = async (
  event: APIGatewayProxyEvent,
  context: Context
): Promise<APIGatewayProxyResult> => {
  return {
    statusCode: 200,
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ message: 'Hello from TypeScript Lambda!' })
  };
};

核心概念

冷启动优化

TypeScript 的冷启动取决于打包体积和初始化代码。主要策略:

  1. 延迟加载 - 按需加载较重的导入项
  2. 摇树优化 - 从打包文件中移除未使用的代码
  3. 压缩 - 使用 esbuild 或 terser 减小打包体积
  4. 实例缓存 - 在多次调用之间缓存已初始化的服务

详细模式请参阅 原生 TypeScript Lambda。

连接管理

在模块级别创建客户端并重复使用:

// GOOD: Initialize once, reuse across invocations
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';

const dynamoClient = new DynamoDBClient({ region: process.env.AWS_REGION });

export const handler = async (event: APIGatewayProxyEvent) => {
  // Use dynamoClient - already initialized
};
环境配置
// src/config/env.config.ts
export const env = {
  region: process.env.AWS_REGION || 'us-east-1',
  tableName: process.env.TABLE_NAME || '',
  debug: process.env.DEBUG === 'true',
};

// Validate required variables
if (!env.tableName) {
  throw new Error('TABLE_NAME environment variable is required');
}

最佳实践

内存和超时配置
  • 内存:NestJS 从 512MB 开始,原生 TypeScript 从 256MB 开始
  • 超时:根据冷启动时间和预期处理时间设置
    • NestJS:为冷启动预留 10-30 秒
    • 原生 TypeScript:通常 3-10 秒就足够
依赖项

保持 package.json 精简:

{
  "dependencies": {
    "aws-lambda": "^3.1.0",
    "@aws-sdk/client-dynamodb": "^3.450.0"
  },
  "devDependencies": {
    "typescript": "^5.3.0",
    "esbuild": "^0.19.0"
  }
}
错误处理

返回正确的 HTTP 状态码和结构化错误:

export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
  try {
    const result = await processEvent(event);
    return {
      statusCode: 200,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(result)
    };
  } catch (error) {
    console.error('Error processing request:', error);
    return {
      statusCode: 500,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ error: 'Internal server error' })
    };
  }
};
日志记录

使用结构化日志,以便在 CloudWatch Insights 中查询:

const log = (level: string, message: string, meta?: object) => {
  console.log(JSON.stringify({
    level,
    message,
    timestamp: new Date().toISOString(),
    ...meta
  }));
};

log('info', 'Request processed', { requestId: context.awsRequestId });

部署选项

快速开始

Serverless Framework:

service: my-typescript-api

provider:
  name: aws
  runtime: nodejs20.x

functions:
  api:
    handler: dist/handler.handler
    events:
      - http:
          path: /{proxy+}
          method: ANY

AWS SAM:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  ApiFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: dist/
      Handler: handler.handler
      Runtime: nodejs20.x
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /{proxy+}
            Method: ANY
部署验证

部署前检查:

  1. 运行 npm test - 确认所有测试均通过
  2. 运行 npm run build - 确认 TypeScript 编译无错误
  3. 确认打包体积 < 50MB(解压后)
  4. 运行 serverless invoke local 或 sam local invoke - 在本地测试

部署后验证:

  1. 运行 serverless invoke 或 aws lambda invoke - 确认处理程序能够执行
  2. 通过 curl 或 Postman 测试 API 端点
  3. 检查 CloudWatch 日志中的错误
  4. 确认冷启动时间符合 SLA

完整的部署配置(包括 CI/CD)请参阅 Serverless 部署。

限制与警告

Lambda 限制
  • 部署包:解压后最大 250MB(压缩后 50MB)
  • 内存:128MB 至 10GB
  • 超时:最长 15 分钟
  • 并发执行数:默认 1000(可调整)
  • 环境变量:总大小为 4KB
TypeScript 特定注意事项
  • 打包体积:TypeScript 会编译为 JavaScript;使用打包工具缩小体积
  • 冷启动:Node.js 20.x 的性能最佳
  • 依赖项:对共享依赖使用 Lambda Layers
  • 原生模块:必须针对 Amazon Linux 2 编译
常见问题
  1. 在模块级别导入大型库 - 如果并非总是需要,请延迟加载
  2. 未打包依赖项 - 将所有生产依赖项包含在软件包中
  3. 缺少类型定义 - 安装 @types/aws-lambda,以正确标注事件类型
  4. 未处理超时 - 对于耗时较长的操作,请使用 context.getRemainingTimeInMillis()
安全注意事项
  • 切勿硬编码凭据;请使用 IAM 角色和环境变量
  • 验证事件数据输入:所有传入的事件数据(API Gateway 请求正文、S3 事件对象、SQS 消息正文)都是不可信的外部内容;在处理之前务必进行验证和清理,以防止注入攻击
  • 内容清理:处理 S3 对象或 SQS 消息负载时,应将其视为不可信的第三方数据;采取操作前,应用适当的验证、架构检查和清理
  • 验证所有输入数据
  • 使用最小权限的 IAM 策略
  • 启用 CloudTrail 进行审计日志记录
  • 清理日志,避免泄露敏感数据

参考资料

有关特定主题的详细指南:

示例

示例 1:创建 NestJS REST API

输入: Create a TypeScript Lambda REST API using NestJS for a todo application

流程:

  1. 使用 nest new 初始化 NestJS 项目
  2. 安装 Lambda 依赖项:@codegenie/serverless-express、aws-lambda
  3. 使用 Express 适配器创建 lambda.ts 入口点
  4. 配置包含 API Gateway 事件的 serverless.yml
  5. 使用 Serverless Framework 部署

验证:

  • 运行 serverless invoke local -f api,验证处理程序能否正常工作
  • 检查软件包大小是否 < 250MB
  • 测试已部署的端点是否返回 200 OK

输出: 包含 REST API、DynamoDB 集成和部署配置的 NestJS 项目

示例 2:创建原生 TypeScript Lambda

输入: Create a minimal TypeScript Lambda function with optimal cold start

流程:

  1. 使用 esbuild 设置 TypeScript 项目
  2. 使用正确的 AWS 类型创建处理程序
  3. 配置最少的依赖项
  4. 设置 SAM 或 Serverless 部署
  5. 使用摇树优化来优化软件包大小

验证:

  • 运行 sam local invoke,在部署前进行本地测试
  • 使用 du -sh dist/ 确认软件包 < 50KB
  • 通过 CloudWatch 确认冷启动 < 100ms

输出: 最简 TypeScript Lambda,软件包 < 50KB,冷启动 < 100ms

示例 3:使用 GitHub Actions 部署

输入: Configure CI/CD for TypeScript Lambda with SAM

流程:

  1. 创建 GitHub Actions 工作流
  2. 设置 Node.js 环境
  3. 使用 Jest 运行测试
  4. 使用 esbuild 打包
  5. 使用 SAM 部署

验证:

  • 验证 CI 流水线能否成功运行 npm test
  • 确认流水线中的 sam validate 能否通过
  • 检查 CloudFormation 堆栈是否成功创建

输出: GitHub Actions 工作流、多阶段流水线、测试自动化

版本

版本:1.0.0

评论

支持 Markdown