使用Terraform创建Node.js18+ Lambda时遇模块找不到错误求助
这个错误的核心是Lambda运行时无法定位到指定的处理程序文件,结合你的代码和目录结构,问题出在TypeScript未编译、打包路径不匹配、流程缺失编译步骤这几个点上,以下是具体分析和解决方案:
问题根源
Lambda不直接支持TypeScript
Lambda的Node.js运行环境只能执行.js/.mjs文件,你当前的代码是.ts格式,没有经过编译就打包上传,导致运行时找不到可执行的模块。Handler路径与打包结构不匹配
你配置的Handler是slack-notification.handler,意味着Lambda需要在zip包的根目录找到slack-notification.js文件,且该文件导出了handler函数。但你的slack-notification.ts在src/functions/目录下,当前打包流程没有将编译后的文件放到正确的位置。依赖与代码打包流程缺失
你的Terraform配置仅执行了npm install,但没有添加TypeScript编译步骤,也没有确保编译后的代码和必要依赖被正确打包进zip文件。
解决方案
步骤1:配置TypeScript编译输出
修改src/tsconfig.json,指定编译后的文件输出目录(比如src/dist),确保编译产物路径符合Lambda的要求:
{ "compilerOptions": { "target": "ES2020", "module": "commonjs", "outDir": "./dist", "rootDir": "./functions", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["functions/**/*"], "exclude": ["node_modules", "dist"] }
步骤2:添加npm编译脚本
在src/package.json中添加编译命令,方便一键完成编译:
{ "scripts": { "build": "tsc" }, "devDependencies": { "@types/aws-lambda": "^8.10.131", "typescript": "^5.3.3" } }
步骤3:修正Terraform配置
调整流程,先安装依赖、编译TypeScript,再打包编译后的产物:
resource "null_resource" "lambda_build" { triggers = { # 监听代码和配置变化,触发重新构建 code_hash = filemd5("${path.module}/../../src/functions/slack-notification.ts") config_hash = filemd5("${path.module}/../../src/tsconfig.json") package_hash = filemd5("${path.module}/../../src/package.json") } provisioner "local-exec" { command = "npm install && npm run build" working_dir = "${path.module}/../../src" } } data "archive_file" "lambda-zip" { type = "zip" # 指向编译后的产物目录 source_dir = "${path.module}/../../src/dist" output_path = "${path.module}/lambda_function.zip" depends_on = [null_resource.lambda_build] } resource "aws_lambda_function" "lambda_module" { filename = data.archive_file.lambda-zip.output_path function_name = "gitlab-slack-integration-${var.environment}" role = aws_iam_role.iam_for_lambda.arn # 编译后的文件名为slack-notification.js,handler路径保持不变 handler = "slack-notification.handler" source_code_hash = data.archive_file.lambda-zip.output_base64sha256 runtime = "nodejs18.x" environment { variables = { env = var.environment } } }
步骤4:验证打包结果
执行terraform apply后,解压生成的lambda_function.zip,确认根目录下存在slack-notification.js文件,且文件中包含exports.handler(或ES模块的export const handler)代码。
注意:@types/aws-lambda是开发依赖,不需要打包进zip,Lambda运行环境会提供核心的aws-lambda模块。
内容的提问来源于stack exchange,提问作者user12494839

