Using nodejs18.x
runtime in AWS Lambda using Serverless I have an issue with ES6 and Common JS.
When not setting type: module
in package.json
Lambda complains about using import
statements outside of the module.export
SyntaxError: Cannot use import statement outside a module
But when I do set the type
to module
in package.json
it complains that I am using required
. Which I am not doing, but the s_tag_file.js
file which is created by Serverless does contain required
{
"errorType": "ReferenceError",
"errorMessage": "require is not defined in ES module scope, you can use import instead\nThis file is being treated as an ES module because it has a '.js' file extension and '/var/task/package.json' contains \"type\": \"module\". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.",
"stack": [
"ReferenceError: require is not defined in ES module scope, you can use import instead",
"This file is being treated as an ES module because it has a '.js' file extension and '/var/task/package.json' contains \"type\": \"module\". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.",
" at file:///var/task/s_tag_file.js:2:21",
" at ModuleJob.run (node:internal/modules/esm/module_job:194:25)"
]
}
What am I doing wrong? Or what could I be doing differently?
Here is my full code:
package.json
:
{
"dependencies": {
"@aws-sdk/client-s3": "^3.391.0",
"aws-sdk": "^2.1437.0"
},
"type": "module"
}
serverless.yaml
:
org: OUR_ORG
app: OUR_APP
service: OUR_SERVICE
frameworkVersion: '3'
provider:
name: aws
runtime: nodejs18.x
lambdaHashingVersion: 20201221
region: us-east-1 # Required for using CloudFront, region does not matter though (it runs at the CF edge location anyways)
iamRoleStatements:
cloudFront:
cachePolicies:
cdnCachePolicy:
MinTTL: 0
MaxTTL: 5184001
DefaultTTL: 5184000
ParametersInCacheKeyAndForwardedToOrigin:
CookiesConfig:
CookieBehavior:
none
EnableAcceptEncodingBrotli: true
EnableAcceptEncodingGzip: true
HeadersConfig:
HeaderBehavior: none
QueryStringsConfig:
QueryStringBehavior: none
custom:
origin: 'ORIGIN_URL'
path: 'build'
functions:
tag-file:
handler: index.tagFile
events:
- cloudFront:
eventType: viewer-response
origin:
DomainName: ${self:custom.origin}
OriginPath: /${self:custom.path}
CustomOriginConfig:
OriginProtocolPolicy: match-viewer
cachePolicy:
name: cdnCachePolicy
index.js
:
import { S3Client, PutObjectTaggingCommand } from "@aws-sdk/client-s3";
export async function tagFile(event, context, callback) {
const response = event.Records[0].cf.response;
const client = new S3Client({ region: "eu-west-1"});
const input = {
Bucket: "BUCKET_NAME",
Key: event.Records[0].cf.request.uri,
Tagging: {
TagSet: [
{
Key: "requestTime",
Value: Date.now().toString(),
},
],
},
};
const command = new PutObjectTaggingCommand(input);
const S3response = await client.send(command);
console.log(S3response);
callback(null, response);
};
Since you are using org
key (line 1) in your serverless.yml
file, you are using Serverless Dashboard plugin.
This plugin do not have ES6 support (which is required for having import
statements). Refer to https://github.com/serverless/dashboard-plugin/issues/564 for more details.
On a site note, Serverless Dashboard is being depreciated in favour of Serverless Console, which comes with ES6 support.
So if you need to support ESM: