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

mtb9vblg  于 12个月前  发布在  Node.js
关注(0)|答案(4)|浏览(144)

我在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;
};

字符串
如果我使用以下内容,它会给我错误-

//ES6+ example 
import { KinesisClient, AddTagsToStreamCommand } from "@aws-sdk/client-kinesis";
     
exports.handler = async (event) => {
    // TODO implement
    const response = {
       statusCode: 200,
       body: JSON.stringify('Hello from Lambda!'),
    };
    return response; 
};
     
"Runtime.UserCodeSyntaxError: SyntaxError: Cannot use import statement outside a module",


问题是...
1.如何从AWS lambda控制台实现这一点?
1.使用ES 5和ES6有什么危害吗?只是语法问题还是也有性能问题?
谢谢你,谢谢

uubf1zoe

uubf1zoe1#

1.为了在lambda中实现这一点,你必须:

  • 为您的Lambda运行时使用NodeJS版本14或更高版本(UPDATE)
  • "type": "module"添加到您的package.json文件中,以便告诉Node使用ES6模块而不是传统的ES 5/CommonJS语法。

1.如果有性能问题,那我们就不用担心了!PS:我建议在更改运行时时测试lambda使用的ES 5/CJS/CommonJS模块的兼容性。

drkbr07n

drkbr07n2#

要升级到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,以防止出现以下错误之一:

  • 语法错误:无法在模块外部使用导入语句
  • 语法错误:意外的标记“export”
    2.将您的处理程序从CommonJS模块处理程序更改为ES模块处理程序

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

  • Undefined或未导出index.handlerNotFound
  • 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;
};

字符串

3.更改模块导入方式

您不能再使用“require”关键字。当您这样做时,您将得到以下错误:

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

重要的是要知道,自NodeJS 18以来,您无法再导入完整的AWS SDK,但您必须指定您需要的模块,否则您将获得以下错误:

  • 错误:无法找到模块“website.org”

参考: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";

trnvg8h3

trnvg8h33#

Tl;医生:要部署第二个示例,您需要进行一些配置更改,这将要求您上传ZIP文件以供将来部署。版本之间的文件更改将在IDE中完成,然后发送到Lambda。
的漫长道路(通过控制台和IDE完成):第二个例子,如果失败,因为NodeJS默认为ES 5需要语法,而ES6切换到导入语法;既然你提到了VSCode,here's something promising I saw。如果这不起作用,那么使用第二个例子中的导入语法,你需要告诉Node这个期望。这是通过应用程序的rootdir中的package.json文件配置的,并启用各种配置选项,as seen here。要做到这一点,你可以运行npm inityarn init,这取决于你选择的包管理器。如果你对这两个都不太了解,我会说yarn比YMMV更适合新手。
现在,所有上述YakShaving的全部目的只是为了让你有一个地方(即package.json内)粘贴:
{ "type": "module" }
添加“type”时:package.json文件中的'module',您通过启用ES 6模块来使用导入语法。当您没有此功能时,您应该只使用require语法。

pgccezyw

pgccezyw4#

我在使用Node18时遇到了同样的问题。
我修复了这个问题,无需package.json中定义"type": "module"
使用以下代码修改tslog.json,修复了它:

{
  "extends": "@tsconfig/node18/tsconfig.json",
  "compilerOptions": {
    "experimentalDecorators": true,
    "outDir": "dist"
  },
  "inlineSource": true,
  "sourceMap": true,
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules"]
}

字符串

相关问题