Serverless Node.js AWS Lambda报错:无法找到commonMiddleware模块
调用Serverless端点触发placeBid函数时,出现以下错误日志:
Streaming new logs for function: "placeBid" INIT_START Runtime - Version: nodejs:20.v42 Runtime Version ARN: arn:aws:lambda:sa-east-1::runtime:af2737389420ddcdbcdc4db3585842c334ad2482127c15295905f54a62feefc6 2024-10-20 17:41:33.920 - undefined - ERROR Uncaught Exception {"errorType":"Error","errorMessage":"Cannot find module '/var/task/lib/commonMiddleware' imported from /var/task/handlers/getAuction.js","code":"ERR_MODULE_NOT_FOUND","url":"file:///var/task/lib/commonMiddleware","stack":["Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/var/task/lib/commonMiddleware' imported from /var/task/handlers/getAuction.js"," at finalizeResolution (node:internal/modules/esm/resolve:269:11)"," at moduleResolve (node:internal/modules/esm/resolve:937:10)"," at moduleResolveWithNodePath (node:internal/modules/esm/resolve:1173:14)"," at defaultResolve (node:internal/modules/esm/resolve:1216:79)"," at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:540:12)"," at ModuleLoader.resolve (node:internal/modules/esm/loader:509:25)"," at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:239:38)"," at ModuleWrap.\<anonymous\> (node:internal/modules/esm/module_job:96:40)"," at link (node:internal/modules/esm/module_job:95:36)"]} INIT_REPORT Init Duration: 194.75 ms Phase: init Status: error Error Type: Runtime.Unknown 2024-10-20 17:41:34.689 - undefined - ERROR Uncaught Exception {"errorType":"Error","errorMessage":"Cannot find module '/var/task/lib/commonMiddleware' imported from /var/task/handlers/getAuction.js","code":"ERR_MODULE_NOT_FOUND","url":"file:///var/task/lib/commonMiddleware","stack":["Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/var/task/lib/commonMiddleware' imported from /var/task/handlers/getAuction.js"," at finalizeResolution (node:internal/modules/esm/resolve:269:11)"," at moduleResolve (node:internal/modules/esm/resolve:937:10)"," at moduleResolveWithNodePath (node:internal/modules/esm/resolve:1173:14)"," at defaultResolve (node:internal/modules/esm/resolve:1216:79)"," at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:540:12)"," at ModuleLoader.resolve (node:internal/modules/esm/loader:509:25)"," at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:239:38)"," at ModuleWrap.\<anonymous\> (node:internal/modules/esm/module_job:96:40)"," at link (node:internal/modules/esm/module_job:95:36)"]} INIT_REPORT Init Duration: 949.46 ms Phase: invoke Status: error Error Type: Runtime.Unknown START - b268505b-edc7-49c1-a4cb-27cc869d550f - Version: $LATEST END - b268505b-edc7-49c1-a4cb-27cc869d550f REPORT - b268505b-edc7-49c1-a4cb-27cc869d550f Duration: 960.51 ms Billed Duration: 961 ms Memory Size: 256 MB Max Memory Used: 73 MB Status: error Error Type: Runtime.Unknown
相关代码
placeBid函数代码
import AWS from 'aws-sdk'; import createError from 'http-errors'; import middy from '@middy/core'; import httpJsonBodyParser from '@middy/http-json-body-parser'; import httpEventNormalizer from '@middy/http-event-normalizer'; import httpErrorHandler from '@middy/http-error-handler'; import { getAuctionById } from './getAuction'; const dynamoDB = new AWS.DynamoDB.DocumentClient(); async function placeBid(event, context) { const { id } = event.pathParameters; const { amount } = event.body; const auction = await getAuctionById(id); console.log('AUCTIONS', auction); if (amount <= auction.highestBid.amount) { throw new createError.Forbidden( `Your bid must be higher than ${auction.highestBid.amount}!`, ); } const params = { TableName: process.env.AUCTIONS_TABLE_NAME, Key: { id }, UpdateExpression: 'set highestBid.amount = :amount', ExpressionAttributeValues: { ':amount': amount, }, ReturnValues: 'ALL_NEW', }; let updatedAuction; try { const result = await dynamoDB.update(params).promise(); updatedAuction = result.Attributes; } catch (error) { console.error(error); throw new createError.InternalServerError(error); } return { statusCode: 200, body: JSON.stringify(updatedAuction), }; } export const handler = middy(placeBid) .use(httpJsonBodyParser()) .use(httpEventNormalizer()) .use(httpErrorHandler());
getAuction函数代码
import AWS from 'aws-sdk'; import createError from 'http-errors'; import commonMiddleware from '../lib/commonMiddleware'; const dynamoDB = new AWS.DynamoDB.DocumentClient(); const getAuctionById = async id => { let auction; try { const result = await dynamoDB .get({ TableName: process.env.AUCTIONS_TABLE_NAME, Key: { id }, }) .promise(); auction = result.Item; } catch (error) { console.error(error); throw new createError.InternalServerError(error); } return auction; }; async function getAuction(event, context) { const { id } = event.pathParameters; const auction = await getAuctionById(id); if (!auction) { throw new createError.NotFound(`Auction with ID "${id}" not found!`); } return { statusCode: 200, body: JSON.stringify(auction), }; } export const handler = commonMiddleware(getAuction); export { getAuctionById };
解决方案
检查文件路径与存在性
确认commonMiddleware.js文件确实存在于项目根目录下的lib文件夹中,路径为lib/commonMiddleware.js。同时检查文件名大小写,Linux环境下文件名区分大小写,确保导入路径的大小写与实际文件完全一致。验证ES模块导入规范
由于使用的是Node.js 20(ES模块默认启用),确保所有导入语句包含文件扩展名。比如将import commonMiddleware from '../lib/commonMiddleware';修改为import commonMiddleware from '../lib/commonMiddleware.js';,Node.js ES模块要求显式指定.js扩展名。检查Serverless打包配置
确认serverless.yml中的打包配置包含了lib目录下的文件。如果使用了exclude规则,确保没有误排除lib文件夹;如果使用include规则,要明确包含lib/**。示例配置:package: include: - handlers/** - lib/**检查本地依赖与打包方式
如果commonMiddleware依赖了其他npm包,确保这些包已安装并被正确打包。如果使用Serverless的默认打包方式,会自动包含node_modules,但如果使用了自定义打包脚本,要确保所有依赖都被包含进部署包。清理并重新部署
删除本地的.serverless目录,清理Lambda函数的旧部署版本,然后重新运行serverless deploy,确保最新的文件被打包上传。
内容的提问来源于stack exchange,提问作者Henrique Matheus Roos

