构建基本 Web 应用程序教程中的 AWS Lambda“找不到模块 aws-sdk”

Rob*_*rtB 21 javascript amazon-web-services node.js amazon-dynamodb aws-lambda

我尝试从头开始运行构建基本 Web 应用程序教程来开始使用 AWS。我想我可以一步一步地遵循它,并有一个简单的 Hello World 网页前端到一个小数据库。但我遇到了一个奇怪的错误:包括最基本的错误,默认aws-sdk模块失败了!

简洁版本:

这段代码:

// Include the AWS SDK module
const AWS = require('aws-sdk');
Run Code Online (Sandbox Code Playgroud)

生成此错误:Error: Cannot find module 'aws-sdk'

很长的故事:

我正在逐步遵循该流程,使用 AWS 在线工具创建所有部分。当我创建 Lambda 函数时,第一个麻烦发生了。我不太担心 Create Function 工具显示 Node.js 版本 18.x 而不是教程的 Node.js 16.x,但我确实注意到它生成的 Lambda shell 被命名index.mjs为index.js. 没问题,我将使用该文件。我用亚马逊的HelloWorld代码替换了内容。

// Define handler function, the entry point to our code for the Lambda service
// We receive the object that triggers the function as a parameter
exports.handler = async (event) => {
    // Extract values from event and format as strings
    let name = JSON.stringify(`Hello from Lambda, ${event.firstName} ${event.lastName}`);
    // Create a JSON object with our response and store it in a constant
    const response = {
        statusCode: 200,
        body: name
    };
    // Return the response constant
    return response;
};
Run Code Online (Sandbox Code Playgroud)

我使用他们的数据设置测试事件功能:

{
  "firstName": "Ada",
  "lastName": "Lovelace"
}
Run Code Online (Sandbox Code Playgroud)

但运行代码产生了我的第一个错误:exports is not defined in ES module scope

对这个错误进行一些搜索让我陷入了远远超出基本教程范围的兔子洞,因此我将文件从 index.mjs 重命名为 index.js。重建后,效果很好:

{
  "statusCode": 200,
  "body": "\"Hello from Lambda, Ada Lovelace\""
}
Run Code Online (Sandbox Code Playgroud)

我不会完成创建数据库的步骤,因为那不相关。一切都很好,直到我用访问数据库的代码替换了代码 - 它出现了上面的错误消息。为了简化问题,我删除了 Lambda 并使用上面的工作代码重新构建了它,语句如下require:

// Include the AWS SDK module
const AWS = require('aws-sdk');
// Define handler function, the entry point to our code for the Lambda service
// We receive the object that triggers the function as a parameter
exports.handler = async (event) => {
    // Extract values from event and format as strings
    let name = JSON.stringify(`Hello from Lambda, ${event.firstName} ${event.lastName}`);
    // Create a JSON object with our response and store it in a constant
    const response = {
        statusCode: 200,
        body: name
    };
    // Return the response constant
    return response;
};
Run Code Online (Sandbox Code Playgroud)

运行会生成以下输出:

{
  "errorType": "Runtime.ImportModuleError",
  "errorMessage": "Error: Cannot find module 'aws-sdk'\nRequire stack:\n- /var/task/index.js\n- /var/runtime/index.mjs",
  "trace": [
    "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:1000:17)",
    "    at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1035:21)",
    "    at async start (file:///var/runtime/index.mjs:1200:23)",
    "    at async file:///var/runtime/index.mjs:1206:1"
  ]
}
Run Code Online (Sandbox Code Playgroud)

我在转储中看到的最奇怪的事情:index.mjs即使我删除了该文件(或重命名它 - 我尝试了两种方法),它仍然引用。在在线 IDE 中,我只能访问仅显示 index.js 的文件树。我认为这/var/task就是我不知道在哪里/var/runtime仍然包含对index.mjs.

我很期待这个令人头疼的问题的解决方案。感觉它很简单,应该可以工作!

Erv*_*gyi 47

该教程提供的代码不适用于使用 NodeJS 18 的 Lambda Runtime。造成这种情况的原因有几个:

  1. Node.js 18.x 使用AWS SDK v3。在您的代码中,您尝试导入 AWS SDK v2。问题在于,NodeJS 18.x 运行时并未附带自动打包并可供使用的 AWS SDK 版本 2。这就是您收到无法找到 的错误的原因aws-sdk。较新的 v3 SDK 与较旧的 v2 版本有显着不同。

  2. exports is not defined in ES module scope- 此错误的原因是 Node.js 18.x 运行时使用ECMAScript 模块而不是 CommonJS 模块。这就是您看到带有扩展名的 JavaScript 文件的原因.mjs。可以说,ECMAScript 模块以不同的方式导出依赖项(使用export关键字),同样,它们使用 import而不是require导入依赖项。

由于您正在制作教程,因此我建议暂时使用 NodeJS 16(或更低的可用版本)。迁移到 NodeJS 18.x 并不像您想象的那样是一项微不足道的任务,但只要您拥有必要的经验,也不是世界末日。希望本教程将来能够更新为最新的可用运行时。

要使用 NodeJS 16.x 创建函数,您可以从列表中选择运行时: 在此输入图像描述

在此输入图像描述

  • 是的,这就是问题所在!我希望是这样的一些小细节。谢谢! (2认同)