通过CDK部署的Lambda函数无法找到处理程序求助
CDK部署Lambda函数出现处理程序找不到的问题
问题背景
使用AWS CDK结合Projen开发,尝试部署一个关联API Gateway的Lambda函数,部署后访问API返回内部服务器错误,Lambda控制台测试时提示找不到处理程序模块。
目录结构
├── src │ ├── lambdas │ │ └── quotes.ts │ └── main.ts └── 其他Projen/CDK配置文件
代码片段
quotes.ts(Lambda处理函数)
import { APIGatewayProxyHandler } from 'aws-lambda'; const quotesHandler: APIGatewayProxyHandler = async (event, context) => { const quotes = [ { text: "You'll see it when you believe it.", author: 'Wayne Dyer, type.fit', }, { text: 'Today is the tomorrow we worried about yesterday.', author: 'type.fit', }, ]; const item = quotes[Math.floor(Math.random() * quotes.length)]; return { statusCode: 200, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(item), }; }; export default quotesHandler;
main.ts(CDK栈定义)
import { join } from 'path'; import { App, Stack, StackProps } from 'aws-cdk-lib'; import { LambdaIntegration, RestApi } from 'aws-cdk-lib/aws-apigateway'; import { Code, Runtime, Function } from 'aws-cdk-lib/aws-lambda'; import { Construct } from 'constructs'; export class MyStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const handlerFunction = new Function(this, 'HelloFunction', { runtime: Runtime.NODEJS_LATEST, memorySize: 512, handler: 'quotes.quotesHandler', code: Code.fromAsset( join(__dirname, './lambdas'), ), }); let api = new RestApi(this, 'quotes-api', { description: 'quotes API', }); let mainPath = api.root.addResource('quotes'); mainPath.addMethod('GET', new LambdaIntegration(handlerFunction)); } } const devEnv = { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION, }; const app = new App(); new MyStack(app, 'CDK-dev', { env: devEnv }); app.synth();
报错信息
Lambda控制台测试返回如下错误:
{ "errorType": "Runtime.ImportModuleError", "errorMessage": "Error: Cannot find module 'quotes'\nRequire stack:\n- /var/runtime/index.mjs", "trace": [ "Runtime.ImportModuleError: Error: Cannot find module 'quotes'", "Require stack:", "- /var/runtime/index.mjs", " at _loadUserApp (file:///var/runtime/index.mjs:1087:17)", " at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1119:21)", " at async start (file:///var/runtime/index.mjs:1282:23)", " at async file:///var/runtime/index.mjs:1288:1" ] }
补充说明
手动修改tsconfig的rootDir和outDir为.,将TypeScript转译为JavaScript后再部署,Lambda可正常运行。希望了解是否能避免手动转译操作。
解决方案
Lambda的Node.js运行时不支持直接执行TypeScript代码,转译为JavaScript是必要步骤,但可以通过工具自动化这个过程,无需手动操作:
1. 使用CDK的NodejsFunction构造(推荐)
CDK提供了@aws-cdk/aws-lambda-nodejs模块,内置esbuild自动编译TS代码,无需手动配置转译:
- 首先安装依赖:
npm install @aws-cdk/aws-lambda-nodejs - 修改main.ts中的Lambda定义:
部署时CDK会自动编译TS为JS并打包上传,无需手动处理tsconfig。import { NodejsFunction } from '@aws-cdk/aws-lambda-nodejs'; // 保留其他导入 // 替换原Function构造 const handlerFunction = new NodejsFunction(this, 'HelloFunction', { runtime: Runtime.NODEJS_LATEST, memorySize: 512, entry: join(__dirname, './lambdas/quotes.ts'), // 直接指定TS文件路径 handler: 'default', // 匹配quotes.ts中的export default });
2. 配置Projen自动编译
若坚持使用原生Function构造,可在Projen配置中添加自动编译任务:
- 在
.projenrc.ts中配置构建命令:import { AwsCdkTypeScriptApp } from 'projen'; const project = new AwsCdkTypeScriptApp({ // 其他配置... buildCommand: 'tsc --project src/tsconfig.json', // 确保tsconfig.json中outDir指向编译后的目录,比如"outDir": "./src/lambdas/dist" }); project.synth(); - 修改CDK中Lambda的代码和handler配置:
执行const handlerFunction = new Function(this, 'HelloFunction', { runtime: Runtime.NODEJS_LATEST, memorySize: 512, handler: 'quotes.default', // 编译后的JS文件导出default code: Code.fromAsset(join(__dirname, './lambdas/dist')), // 指向编译后的目录 });npx projen build时会自动编译TS,之后再执行CDK部署即可。
3. 使用Projen的Lambda专用模板
初始化项目时选择Projen的Lambda相关模板,它会自动配置好TS编译、Lambda打包的流程:
npx projen new aws-lambda-nodejs
后续只需编写TS代码,Projen会处理所有编译和打包工作。
内容的提问来源于stack exchange,提问作者NK Rao
相关产品推荐
相关产品推荐

