serverless icon indicating copy to clipboard operation
serverless copied to clipboard

Node ES6 support issue

Open nickhaakman opened this issue 2 years ago • 1 comments

Are you certain it's a bug?

  • [X] Yes, it looks like a bug

Is the issue caused by a plugin?

  • [X] It is not a plugin issue

Are you using the latest v3 release?

  • [X] Yes, I'm using the latest v3 release

Is there an existing issue for this?

  • [X] I have searched existing issues, it hasn't been reported yet

Issue description

Using nodejs18.x runtime 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)"
    ]
}

I would expect the file created by Serverless to also be in the ES6 notation, but it is not.

Here is my full code:

package.json:

{
  "dependencies": {
    "@aws-sdk/client-s3": "^3.391.0",
    "aws-sdk": "^2.1437.0"
  },
  "type": "module"
}

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);
};

Service configuration (serverless.yml) content

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

Command name and used flags

N/A

Command output

N/A

Environment information

Framework Core: 3.29.0
Plugin: 6.2.3
SDK: 4.3.2

nickhaakman avatar Aug 17 '23 10:08 nickhaakman

Getting the exact same error.

I'm in the process of migrating our project to serverless v3 and ESM modules. I've followed the steps of adding "type": "module" to my package.json and replacing require(...) with import. However, I've encountered the "require is not defined" error when invoking the serverless function.

Error Message:

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 '/Users/saju/Documents/my-app/package.json' contains "type": "module". 
To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
at file:///Users/saju/Documents/my-app/s_myHandlerFunction.js:2:21

Environment

Environment: darwin
node 16.16.0, 
framework 3.34.0, 
plugin 6.2.3, 
SDK 4.3.2

Temporary File Creation:

During the invocation of my serverless function, a temporary file named s_myHandlerFunction.js is being created. This file contains instances of require(...).

Expected Behavior:

I expected the migration to work smoothly with ES modules after following the steps mentioned. However, I'm encountering the "require is not defined" error.

Code Sample:

Here's how I'm calling my serverless function:

export async function myHandlerFunction(event) {
  
}

Request for Help:

I've tried different approaches, but I'm still facing the same problem. Could someone provide insights or suggestions to resolve this issue?

Thank you in advance!

sadekujjaman avatar Aug 30 '23 13:08 sadekujjaman