이전에 lambda에서 runtime을 node.js 16 버전으로 해서 작성했었는데, 업데이트 된지 모르고 node.js 18 버전으로 lambda를 만들었다가 이전 코드가 적용되지 않는다는 걸 알았다.
AWS Docs에 들어가니 SDK가 Node.js 18 버전부터는 3 버전으로 적용되어 있었다.
이 포스팅은 16 버전 코드를 18 버전으로 변경하는 방법 혹은 발생하는 에러를 수정하는 방법에 대해서 서술하려고 한다.
아래의 에러는 한 번에 발생한 것이 아니라 조금씩 고칠 때마다 발생한 에러이다. 세 번에 걸쳐서 변경했다.
require is not defined in ES module scope, you can use import instead
exports is not defined in ES module scope
Referenceerror exports is not defined in es module scope
기존에 사용하던 코드이다. require
를 사용해서 aws-sdk를 가져왔다. DynamoDB Client를 가져오는 방식도 간단하게 되어 있고, 아래에서 update 사용 시에 dynamodbClient.update()
로 간단히 구현했다. 또, export.handler
형태로 함수를 함수를 작성했다.
const { AWS } = require("aws-sdk");
const dynamodbClient = new AWS.DynamoDB.DocumentClient({region: "us-east-1"});
exports.handler = async (event, context) => {
let ddbParams = {
...
}
};
try {
var updateResult = await dynamodbClient.update(ddbParams).promise();
} catch (err) {
console.error("err", err);
}
};
aws-sdk를 require 대신에 import
해서 사용하고, update를 위해 UpdateCommand
를 sdk에서 가져와서 사용했다. 또 export const handler
를 사용해서 함수를 작성했다.
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { UpdateCommand } from "@aws-sdk/lib-dynamodb";
const ddbDocClient = new DynamoDBClient({ region: "us-east-1" });
export const handler = async (event, context) => {
let params = {
...
};
try {
var updateResult = await ddbDocClient.send(new UpdateCommand(params));
} catch (err) {
console.error("err", err);
}
};
이 에러는 버전 문제때문에 발생한 것 같지는 않은데, 버전 변경하면서 처음으로 발생한 에러라서 같이 적어둔다.
validationexception invalid updateexpression attribute name is a reserved keyword
이렇게 사용하니 position이라는 attribute name이 이미 예약된 키워드라고 에러가 계속 발생했다.
let params = {
TableName: "test-widget-tbl",
Key: {
"dashboardId": event.dashboardId,
"widgetId": event.widgetId
},
UpdateExpression: "set position = :p",
ExpressionAttributeValues: {
":p": event.position,
},
};
ExpressionAttributeNames
를 사용해서 이름 설정을 해주었더니 에러가 발생하지 않았다.
let params = {
TableName: "test-widget-tbl",
Key: {
"dashboardId": event.dashboardId,
"widgetId": event.widgetId
},
UpdateExpression: "set #po = :p",
ExpressionAttributeValues: {
":p": event.position,
},
ExpressionAttributeNames: {
"#po": "position"
},
};
참조
https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html
https://stackoverflow.com/questions/72359031/exports-is-not-defined-in-es-module-scope-aws-lambda
https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-dynamodb/index.html#usage