英文:
Require is not defined in lambda function
问题
抱歉,我只会提供代码的翻译,不会回答翻译问题。以下是您提供的代码的翻译:
首先,如果这很琐碎的话,我要道歉,但是我尝试的每个解决方案都报错。
简而言之,我是AWS环境的新手,选择了DynamoDB作为数据库设置。我使用了一个Lambda函数,以便能够从任何地方批量写入数据到云端。
花了一些时间,但我最终使它全部工作了,但是出于错误选择(或者说使用了默认的)数据库位置为us-east-1。现在长话短说,出于法律原因,数据应该位于欧洲。所以我只是复制了一切,并将所有内容迁移到eu-central-1。
这就是问题开始出现的时候... 在us-east-1中的代码在node.js 16上运行,使用"const AWS = require("aws-sdk");"
但是在eu-central-1中相同的语句一直报错。如果我在node.js 16中运行它,会显示以下信息:
> "errorType": "ReferenceError",
> "errorMessage": "在ES模块范围内未定义require,您可以使用import代替",
> "stack": [
> "ReferenceError: 在ES模块范围内未定义require,您可以使用import代替",
> "在 file:///var/task/index.mjs:1:13 处",
> "在 ModuleJob.run (node:internal/modules/esm/module_job:193:25) 处"
> ]
如果我在node.js 18中运行它(因为我发现require语句是在这个版本中添加的)
> "errorType": "ReferenceError",
> "errorMessage": "在ES模块范围内未定义require,您可以使用import代替",
> "stack": [
> "ReferenceError: 在ES模块范围内未定义require,您可以使用import代替",
> "在 file:///var/task/index.mjs:1:13 处"
> ]
我尝试了许多不同的语法,但没有一个解决了我的问题或者解释了问题。当我使用建议的import语句时,会出现找不到aws-sdk文件的错误。但是我尝试将它们安装在相同的位置,但没有成功。可能这是一个我应该追求的解决方案,但我似乎找不到如何成功附加文件的清晰信息(我尝试导出Lambda函数并将aws-sdk附加到文件夹中,但仍然出现相同的错误)。更重要的是,我想知道为什么会发生这种情况,因为我绝对没有在us-east-1地区安装aws-sdk,但在那里它正常工作,而且require语句在那里定义了。
所以任何阅读、建议、建议都欢迎。我会保留这个更新,并添加您需要提供帮助的代码(或设置或建议更改的结果)。
这是工作中的Lambda代码(来自us-east-1),代码与eu-central-1中的相同,除了表名和位置。
```javascript
const AWS = require("aws-sdk");
const dynamo = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event, context) => {
let body;
let statusCode = 200;
const headers = {
"Content-Type": "application/json"
};
try {
switch (event.routeKey) {
case "DELETE /items/{id}":
await dynamo
.delete({
TableName: "TestID",
Key: {
id: event.pathParameters.id
}
})
.promise();
body = `Deleted item ${event.pathParameters.id}`;
break;
case "GET /items/{id}":
body = await dynamo
.get({
TableName: "TestID",
Key: {
id: event.pathParameters.id
}
})
.promise();
break;
case "GET /items":
body = await dynamo.scan({ TableName: "TestID" }).promise();
break;
case "PUT /items":
let requestJSON = JSON.parse(event.body);
if (!requestJSON[0].ModuleID || !requestJSON[0].DataID) {
throw new Error("Missing required fields: ModuleID or DataID, greetings ");
}
await dynamo
.put({
TableName: "TestID",
Item: {
ModuleID: requestJSON[0].ModuleID,
DataID: requestJSON[0].DataID,
TimeStamp: requestJSON[0].TimeStamp,
ValTemp: requestJSON[0].ValTemp
}
})
.promise();
body = `Put item ${requestJSON[0].DataID}`;
break;
case "PUT /items/batch":
let requestJSONBatch = JSON.parse(event.body);
let items = requestJSONBatch.map(item => {
return {
PutRequest: {
Item: {
ModuleID: item.ModuleID,
DataID: item.DataID,
TimeStamp: item.TimeStamp,
T2: item.T2,
ValTemp: item.ValTemp
}
}
};
});
await dynamo
.batchWrite({
RequestItems: {
"TestID": items
}
})
.promise();
body = `PUT items`;
break;
default:
throw new Error(`Unsupported route: "${event.routeKey}"`);
}
} catch (err) {
statusCode = 400;
body = err.message;
} finally {
body = JSON.stringify(body);
}
return {
statusCode,
body,
headers
};
};
我按照建议更改了第一行:
const AWS = require("@aws-sdk/client-s3")
并在node.js 18中运行了代码;我收到了类似的错误:
"errorType": "ReferenceError", "errorMessage": "在ES模块范围内未定义require,您可以使用import代替", "stack": [
"ReferenceError: 在ES模块范围内未定义require,您可以使用import代替", " 在 file:///var/task/index.mjs:
英文:
First of all, my apologies if this is very trivial but every solution I tried just gave errors.
In short I am new to the aws enviroment and choose a dynamodb to set up as database. I used a lamdba function to be able to batch write data from anywhere to the cloud.
It took some time but I got it all working, however by mistake I chose (or rather used the default) db location us-east-1. Now long story short for legal reasons the data should be in Europe. So I just copied everything, and migrated everything to eu-central-1.
And that's when things when sideways... The code in us-east-1 is running on node.js 16 and uses "const AWS = require("aws-sdk");"
But the same statement in eu-central-1 keeps giving errors. If I run it in node.js 16 it states this:
> errorType": "ReferenceError",
> "errorMessage": "require is not defined in ES module scope, you can use import instead",
> "stack": [
> "ReferenceError: require is not defined in ES module scope, you can use import instead",
> at file:///var/task/index.mjs:1:13",
> at ModuleJob.run (node:internal/modules/esm/module_job:193:25)",
> at async Promise.all (index 0)",
> at async ESMLoader.import (node:internal/modules/esm/loader:530:24)",
> at async _tryAwaitImport (file:///var/runtime/index.mjs:918:16)",
> at async _tryRequire (file:///var/runtime/index.mjs:967:86)",
> at async _loadUserApp (file:///var/runtime/index.mjs:991:16)",
> at async Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1032:21)",
> at async start (file:///var/runtime/index.mjs:1195:23)",
> at async file:///var/runtime/index.mjs:1201:1"
And if I run it in node.js 18 (because I found out that the require statement is something added in this version)
> "errorType": "ReferenceError",
> "errorMessage": "require is not defined in ES module scope, you can use import instead",
> "stack": [
> "ReferenceError: require is not defined in ES module scope, you can use import instead",
> at file:///var/task/index.mjs:1:13",
> at ModuleJob.run (node:internal/modules/esm/module_job:194:25)"`
> ]
I tried many different syntaxes but none have solved my problem or my knowledge of the problem. When I use the suggested import statement I get errors that the aws-sdk files are not found. But I tried to install them in the same location but that did not work. Probably is this a solution that I should persue but I can't seem to find any clear information on how to succesfully attach the files (I tried to export the Lambda function and attach the aws-sdk in the folder but that gave the same errors) And more Importantly I want to know why this is occurring, because I definetly didn't install aws-sdk in the us-east-1 region and there it works, plus the require statement is defined there.
So any reading, tips, suggestion is welcome. I 'll keep this update and add the code that you need to provide help (or settings or results of proposed changes).
Here is the working Lambda code (from the us-east-1), the code is the same as in eu-central-1 except for the table name and location.
const AWS = require("aws-sdk");
const dynamo = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event, context) => {
let body;
let statusCode = 200;
const headers = {
"Content-Type": "application/json"
};
try {
switch (event.routeKey) {
case "DELETE /items/{id}":
await dynamo
.delete({
TableName: "TestID",
Key: {
id: event.pathParameters.id
}
})
.promise();
body = `Deleted item ${event.pathParameters.id}`;
break;
case "GET /items/{id}":
body = await dynamo
.get({
TableName: "TestID",
Key: {
id: event.pathParameters.id
}
})
.promise();
break;
case "GET /items":
body = await dynamo.scan({ TableName: "TestID" }).promise();
break;
case "PUT /items":
let requestJSON = JSON.parse(event.body);
if (!requestJSON[0].ModuleID || !requestJSON[0].DataID) {
throw new Error("Missing required fields: ModuleID or DataID, greetings ");
}
await dynamo
.put({
TableName: "TestID",
Item: {
ModuleID: requestJSON[0].ModuleID,
DataID: requestJSON[0].DataID,
TimeStamp: requestJSON[0].TimeStamp,
ValTemp: requestJSON[0].ValTemp
}
})
.promise();
body = `Put item ${requestJSON[0].DataID}`;
break;
case "PUT /items/batch":
let requestJSONBatch = JSON.parse(event.body);
let items = requestJSONBatch.map(item => {
return {
PutRequest: {
Item: {
ModuleID: item.ModuleID,
DataID: item.DataID,
TimeStamp: item.TimeStamp,
T2: item.T2,
ValTemp: item.ValTemp
}
}
};
});
await dynamo
.batchWrite({
RequestItems: {
"TestID": items
}
})
.promise();
body = `PUT items`;
break;
default:
throw new Error(`Unsupported route: "${event.routeKey}"`);
}
} catch (err) {
statusCode = 400;
body = err.message;
} finally {
body = JSON.stringify(body);
}
return {
statusCode,
body,
headers
};
};
I followed the suggestion and changed the first line to:
const AWS = require("@aws-sdk/client-s3")
And ran the code in node.js 18 ; I get a similar error:
> "errorType": "ReferenceError", "errorMessage": "require is not defined
> in ES module scope, you can use import instead", "stack": [
> "ReferenceError: require is not defined in ES module scope, you can
> use import instead", " at file:///var/task/index.mjs:1:13", " at
> ModuleJob.run (node:internal/modules/esm/module_job:194:25)" ]
答案1
得分: 0
以下是已翻译好的内容:
解决方案,
最终问题很简单,如果你使用 Web 界面创建 Lambda 函数,你无需添加任何(常规)依赖项,比如 AWS-SDK 模块,因为亚马逊会处理它。但是,即使你只上传一个代码文件,只要上传一个 .zip 文件,这一部分就会停止。
所以我从位置 x 下载了我的工作代码,然后将我的代码上传到不同的位置,相应地更改了 API 和安全性,但不成功,因为我没有依赖项。
因此,没有 "package.json",我不理解任何建议,我能够验证的答案也没有帮助。最后,使用 aws cli(需要一些阅读和理解来设置)。然后添加 aws-sdk 并使用 aws cli 上传它。
详情:
AWS-SDK: https://github.com/aws/aws-sdk-js
在特定目录安装:
npm install aws-sdk
将 .mjs 代码文件添加到目录中
使用 7Zip 压缩目录中的所有内容:
\Program Files\7-Zip\7z" a -r awslambdav2.zip
将此 .zip 文件更新为现有函数的源代码
aws lambda update-function-code --function-name *插入函数名称* --zip-file fileb://awslambdav2.zip
完成!最后,不应使用 Web 界面部署 Lambda 函数。
英文:
The Solution,
In the end the problem was simple, if you create a lambda function using the webinterface you don't need to add any (regular) dependencies such as the AWS-SDK module, because Amazon takes care of it. However this part stops as soon as you upload a .zip file even if you don't add anything but a code file.
So I downloaded my working code from location x an uploade my code to a different location changed the API and Security accordingly but was unsuccesfull because I had no depencies.
Therefore there was no "package.json" and I didn't understand any of the suggestions and the answer I was able to verify didn't help. In the end, use the aws cli (it takes some reading and understanding to set up). And add the aws-sdk and upload this using the aws cli.
Details:
AWS-SDK: https://github.com/aws/aws-sdk-js
Instal in a specific directory:
npm install aws-sdk
Add .mjs code file to the directory
use 7Zip to zip everything in the directory:
\Program Files\7-Zip\7z" a -r awslambdav2.zip
Update this .zip file as the source for your existing function
aws lambda update-function-code --function-name *insertFunctionName* --zip-file fileb://awslambdav2.zip
And you're done! All fixed. In the end the webinterface should not be used to deploy Lambda functions.
答案2
得分: -2
Node 18现在使用AWS SDK V3,您应相应地处理您的代码。
此答案应有助于您的导入,并使您能够在SDK V3中建立DynamoDB客户端。
使用:
import * as AWS from "@aws-sdk/client-dynamodb";
还请阅读这里。
英文:
Node 18 now uses AWS SDK V3 and you should handle your code accordingly.
This answer should help with your imports and enable you to establish a DynamoDB Client in SDK V3.
Use:
import * as AWS from "@aws-sdk/client-dynamodb";
Also read here
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论