LocalStack部署Node.js Lambda触发报错:Cannot find module 'index'求助
问题详情
使用LocalStack部署Node.js Lambda函数,创建成功但触发时出现以下错误:
[ asgi_gw_0] l.s.l.i.executor_endpoint : Execution environment startup failed:
{"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'index'\nRequire stack:\n- /var/runtime/index.mjs","trace":["Runtime.ImportModuleError: Error: Cannot find module 'index'","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"]}
已尝试hot-reload和zip包两种部署方式,均未解决。
相关配置信息
Docker Compose配置
version: "3.0" networks: test: services: localstack: image: localstack/localstack:3.4.0 networks: - test environment: - SERVICES=sns,sqs,kms,events,lambda,s3,iam - LOCALSTACK_HOST=localstack - AWS_ACCESS_KEY_ID=test - AWS_SECRET_ACCESS_KEY=test - AWS_REGION=eu-west-2 - AWS_DEFAULT_REGION=eu-west-2 - DEFAULT_REGION=eu-west-2 - SKIP_SSL_CERT_DOWNLOAD=1 - LOCALSTACK_KMS_BACKEND=moto - LAMBDA_RUNTIME_ENVIRONMENT_TIMEOUT=2000 - LAMBDA_KEEPALIVE_MS=6000000 - LAMBDA_EXECUTOR=docker-reuse - DEBUG=0 - UPDATE_REQUEST_QUEUE_URL=http://localstack:4566/000000000000/test_update_request_queue.fifo - UPDATE_REQUEST_SNS_TOPIC_ARN=arn:aws:sns:eu-west-2:000000000000:test_update_request_queue.fifo - MESSAGE_GROUPS=2 volumes: - ./test/integration/localstackinit.d/init:/etc/localstack/init/boot.d/ - ./test/integration/localstackinit.d/ready/:/etc/localstack/init/ready.d/ - ./sd_refresh_docs.zip://home/aws/functions/sd_refresh_docs.zip - ./:/usr/lambda/ - "/var/run/docker.sock:/var/run/docker.sock" healthcheck: test: [ "CMD", "curl", "http://localhost.localstack.cloud:4566/_localstack/health" ] interval: 10s timeout: 5s retries: 10 expose: - 4566 - 4575 - 9915 ports: - 4566:4566 - 4575:4575 - 9915:9915 - 4571:4572 - 8090:8080
awslocal创建命令
awslocal lambda create-function \ --code S3Bucket='hot-reload',S3Key='/usr/lambda' \ --function-name sd-refresh-docs-function \ --handler app/index.handler \ --role "arn:aws:iam::000000000000:role/DummyRole" \ --runtime nodejs20.x \ --environment "Variables={LOG_LEVEL=debug,UPDATE_REQUEST_QUEUE_URL=${UPDATE_REQUEST_QUEUE_URL},MESSAGE_GROUPS=2}" log "Created Lambda function"
package.json依赖
"dependencies": { "@babel/eslint-parser": "7.24.5", "@dwp/ui-core": "2.0.0-release.897211608", "eslint-config-prettier": "9.1.0", "eslint-plugin-prettier": "5.1.3", "prettier": "3.2.5", "aws-sdk": "^2.1618.0", "winston": "3.13.0" },
目录结构
本地包含app/index.js文件
排查与解决方案
1. 验证Hot-Reload路径映射的实际结构
LocalStack的hot-reload模式下,S3Key='/usr/lambda'指向容器内的该目录,先确认容器内/usr/lambda下是否存在app/index.js:
docker exec -it <localstack-container-name> ls -la /usr/lambda/app
如果本地app目录未正确挂载,需调整Docker Compose的volume配置,确保本地根目录完整映射到容器的/usr/lambda。
2. 修正Handler路径配置
Node.js Lambda的handler格式为文件名.导出函数名,针对当前结构可尝试两种调整:
- 若
app/index.js是入口文件,且package.json的main字段设置为app/index.js,可将handler改为app.handler - 保持
app/index.handler的前提下,确认容器内/usr/lambda/app/index.js存在,且文件内明确导出了handler:exports.handler = ...
同时注意Linux容器区分大小写,检查index.js是否存在拼写错误。
3. 检查Zip包结构(Zip部署方式)
使用Zip包部署时,确保Zip根目录直接包含app文件夹,解压后结构应为:
sd_refresh_docs.zip/ └── app/ └── index.js
若Zip包内存在嵌套目录(如sd_refresh_docs.zip/项目根目录/app/index.js),Lambda runtime无法找到文件,需重新打包将app目录放在Zip根目录。
4. 验证文件权限
检查LocalStack容器内/usr/lambda目录及文件的可读权限:
docker exec -it <localstack-container-name> ls -la /usr/lambda/app/index.js
若权限不足,可调整本地文件权限,或在Docker Compose环境变量中添加LAMBDA_REMOTE_DOCKER=false,避免使用独立的Lambda执行容器以减少权限问题。
5. 适配Node.js Runtime模块逻辑
- 若
index.js使用ES模块(export语法),需在package.json中添加"type": "module",否则Node.js 20.x runtime会按CommonJS解析,导致找不到导出 - Hot-reload模式下,确保本地
node_modules正确挂载到容器内,或在ready.d初始化脚本中添加npm install命令安装依赖
内容的提问来源于stack exchange,提问作者user2366424

