如何解决-无法在AWS lambda控制台中的模块外部使用导入语句

Jud*_*udi 15 amazon-web-services node.js aws-lambda

我正在 AWS lambda 控制台中尝试此操作。我已经在终端上安装了 npm install @aws-sdk/client-kinesis 并使用压缩文件并创建了一个具有 client-kinesis 的 lambda 层。

如果使用以下内容就可以了!

 // ES5 example
const { KinesisClient, AddTagsToStreamCommand } = require("@aws-sdk/client-kinesis");
exports.handler = async (event) => {
    // TODO implement
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};
Run Code Online (Sandbox Code Playgroud)

如果我使用以下内容,则会出现错误 -

 // ES5 example
const { KinesisClient, AddTagsToStreamCommand } = require("@aws-sdk/client-kinesis");
exports.handler = async (event) => {
    // TODO implement
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};
Run Code Online (Sandbox Code Playgroud)

问题 -

  1. 如何通过 AWS lambda 控制台实现此功能?
  2. 用作ES5 vs ES6 有什么坏处吗?仅仅是语法还是还存在性能问题?

谢谢 !

All*_*hua 17

  1. 为了在 lambda 中实现此功能,您必须:
  • 为您的 Lambda 运行时使用NodeJS 版本 16 或更高版本 (更新)
  • 添加"type": "module"到您的 package.json 文件中,以告诉 Node 使用 ES6 模块而不是传统的 ES5/CommonJS 语法。
  1. 如果存在性能问题,那是极小的,我们不必担心!PS:我建议在更改运行时时测试 lambda 使用的 ES5/CJS/CommonJS 模块的兼容性。

  • 我有一点困惑。请帮忙贴一下步骤。我从哪说起呢 ?vscode 还是 AWS Lambda 控制台?我尝试从控制台添加 package.json 文件,但它不起作用。 (3认同)

use*_*217 12

要升级到 Node.js 18,您必须更改代码才能使该功能再次运行。我不使用 zip 文件、配置文件或图层。

升级 AWS Lambda 函数的步骤:

1.将index.js文件名改为index.mjs

以 .mjs 结尾的文件名始终被视为 ES 模块。以 .js 结尾的文件名从包继承其类型。

参考: https: //aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/

您应该将index.js 文件重命名为index.mjs 以防止出现以下错误之一:

  • 语法错误:无法在模块外部使用 import 语句

  • 语法错误:意外的标记“导出”

2. 将处理程序从 CommonJS 模块处理程序更改为 ES 模块处理程序

您必须更新定义处理程序的方式,以防止出现以下错误之一:

  • Runtime.HandlerNotFound:index.handler未定义或未导出

  • ReferenceError:导出未在 ES 模块范围中定义

参考:https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html

// Before NodeJS 18
exports.handler = async function (event, context) {
  console.log("EVENT: \n" + JSON.stringify(event, null, 2));
  return context.logStreamName;
}; 

// NodeJS 18 and above
export const handler = async (event, context) => {
  console.log("EVENT: \n" + JSON.stringify(event, null, 2));
  return context.logStreamName;
};
Run Code Online (Sandbox Code Playgroud)

3. 改变导入模块的方式

您不能再使用“require”关键字。当您执行此操作时,您将收到以下错误:

  • ReferenceError: require 未在 ES 模块作用域中定义,您可以使用 import 代替

重要的是要知道,从 NodeJS 18 开始,您无法再导入完整的 AWS SDK,但您必须指定您需要哪些模块,否则您将收到以下错误:

  • Runtime.ImportModuleError:错误:找不到模块“aws-sdk”

参考: https: //aws.amazon.com/blogs/compute/node-js-18-x-runtime-now-available-in-aws-lambda/

// Before NodeJS 18
const AWS = require("aws-sdk");
const https = require("https");
const querystring = require("querystring"); 

// NodeJS 18 and above. In this example the module "client-sns" is imported from the AWS SDK.
import * as AWS from "@aws-sdk/client-sns";
import https from "https";
import querystring from "querystring";
Run Code Online (Sandbox Code Playgroud)