Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve -Cannot use import statement outside a module in AWS lambda console

I am trying this in the AWS lambda console. I have installed npm install @aws-sdk/client-kinesis on my terminal and used zipped the file and created a lambda layer which has client-kinesis.

If use the following it works!

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

If I am using the following it is giving me errors-

//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",

Question -

  1. How to make this work from the AWS lambda console ?
  2. Is there any harm in using as the ES5 vs ES6 ? is it only syntax or there are performance issues also?

Thanks !

like image 754
Judi Avatar asked Dec 10 '25 23:12

Judi


2 Answers

To upgrade to Node.js 18, you have to change the code to make the function work again. I don't use zip files, config files or layers.

Steps to upgrade your AWS Lambda function:

1. Change the filename of index.js to index.mjs

File names ending in .mjs are always treated as ES modules. File names ending in .js inherit their type from the package.

Reference: https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/

You should rename your index.js file to index.mjs to prevent one of the following errors:

  • SyntaxError: Cannot use import statement outside a module

  • SyntaxError: Unexpected token 'export'

2. Change your handler from CommonJS module handler to ES module handler

You must update the way you define your handler to prevent one of the following errors:

  • Runtime.HandlerNotFound: index.handler is undefined or not exported

  • ReferenceError: exports is not defined in ES module scope

Reference: 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. Change the way you import your modules

You cannot use the "require" keyword anymore. You will get the following error when you do:

  • ReferenceError: require is not defined in ES module scope, you can use import instead

It is important to know that since NodeJS 18 you cannot import the complete AWS SDK anymore, but you have to specify which modules you need, or you will get the following error:

  • Runtime.ImportModuleError: Error: Cannot find module 'aws-sdk'

Reference: 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";
like image 121
user1646217 Avatar answered Dec 13 '25 12:12

user1646217


In order to fix the error, you could opt to use at least NodeJS version 18 or the latest runtime version (NodeJS 22)

  1. You can upgrade your old functions by adding "type": "module" to your package.json file. This will inform the Node runtime to use ES6 modules instead of the traditional ES5/CommonJS syntax.

  2. Change the extension of your files to .mjs to force the NodeJS runtime to treat your file as an ES6 module.

  3. If you are using esbuild, you will have to make sure that your build output is compatible with the ES6 modules (import/export).

  4. If you were using TypeScript, configure your transpiler to produce a build output that is compatible with ES modules.

  5. If there is a performance issue, it would be minimal that we don't have to worry about it! PS: I recommend to test the compatibility of the ES5/CJS/CommonJS modules that the lambda uses when you change the runtime.

like image 39
Allan Chua Avatar answered Dec 13 '25 11:12

Allan Chua



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!