網站搜尋

node.js - AWS Lambda 層 - Typescript - Runtime.ImportModuleError


希望你一切安好。我在使用我設置的 Lambda 上使用 Lambda 層時遇到了一些問題。我已經嘗試了六百種方法來解決這個問題,但仍然沒能讓任何方法有效。

我可以看出這是一個相當典型的錯誤,因為我在這裡、Google 等地方遇到過許多關於它的文章。無論如何,有些事情我還是搞不清楚,因為儘管我應用了那些解決方案,它們仍然不起作用。

請注意,我正在使用 Windows。

我遇到的錯誤是,

{
    "errorType": "Runtime.ImportModuleError",
    "errorMessage": "Error: Cannot find module 'aws-sdk'\nRequire stack:\n- /var/task/index.js\n- /var/runtime/index.mjs",
    "stack": [
        "Runtime.ImportModuleError: Error: Cannot find module 'aws-sdk'",
        "Require stack:",
        "- /var/task/index.js",
        "- /var/runtime/index.mjs",
        "    at _loadUserApp (file:///var/runtime/index.mjs:1061:17)",
        "    at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1093:21)",
        "    at async start (file:///var/runtime/index.mjs:1256:23)",
        "    at async file:///var/runtime/index.mjs:1262:1"
    ]
}

下面是 lambda 代碼,雖然我認為它可能沒有幫助:

var AWS = require('aws-sdk');
AWS.config.update({region: 'US-East-1'})
var DynamoDBObject = new AWS.DynamoDB({apiVersion: '2012-08-10'})

exports.main = async function(event, context){
    console.log(event['Details']['ContactData']['CustomerEndpoint']['Address'])
    const numberNumber = parseInt(event['Details']['ContactData']['CustomerEndpoint']['Address'].replace("+1",""))

    console.log("I\'m working! Look at me: ", numberNumber)

    var params = {
        TableName: '{MyTableName}',
        Item: {
            'PhoneNumber': numberNumber
        }
    }
    DynamoDBObject.putItem(params, function(error, data){
        if(error){
            console.log("Error: ", error)
        } else {
            console.log("Success: ", data)
        }
    })
}

Lambda 的架構/部署以及關於 Layer 的資訊(我在控制台手動設置的)在這裡:

import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as s3 from "aws-cdk-lib/aws-s3";
import path from "path";

export class LambdaService extends Construct {
    constructor(scope: Construct, id: string){
        super(scope, id);

        //comment

        const codeContainer = new s3.Bucket(this, "LambdaContainer")

        const lambdaLayer = lambda.LayerVersion.fromLayerVersionArn(this, "mylambdalayer", "{LayerARN}")

        new lambda.Function(this, "PhoneNumberInsert2", {
            code: lambda.Code.fromAsset(path.join(__dirname,"../../Lambdas")),
            runtime: lambda.Runtime.NODEJS_18_X,
            handler: "index.main",
            logRetention: 1,
            description: "Lambda that enters a new phone number into DynamoDB",
            environment: {
              BUCKET: codeContainer.bucketName
            },
            layers:[lambdaLayer]
          });
    }
}

最後,當然,這裡是我在 AWS 配置的層的檔案結構。

**'TOP' Directory**: nodejs.zip
**Second Directory**: nodejs (why is it that when you zip, it adds this directory on top?)
**Third Directory Layer**:
 1. Directory: 'node_modules'
 2. File: package.json
 3. File: package-lock.json

任何幫助都將不勝感激。祝你有美好的一天!

答案#1

如果你正在運行 node18 或更高版本,lambda 執行環境預設不再包含 aws-sdk,而是改為包含 @aws-sdk 模組。如果是這種情況,你有幾個選擇:

  1. 降級到 nodejs16.x。警告:nodejs16.x 的棄用日期為 2024 年 6 月 12 日
  2. 將你的 lambda 重構以使用新版 @aws-sdk。這是建議的解決方案,如果你沒有大量舊代碼需要重構的話。
  3. 建立一個額外的層,其中包含 aws-sdk,然後當你同時包含這兩個層時,你就可以再次導入 aws-sdk。這裡的注意事項是,額外的層會增加每個 Lambda 的封裝大小。