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

1

Trying to follow a DynamoDB + Lambda + API Gateway tutorial: http-api-dynamo-db.

const AWS = require("aws-sdk");
const dynamo = new AWS.DynamoDB.DocumentClient();

These above lines in the lambda function result in a "ReferenceError":

{
  "errorType": "ReferenceError",
  "errorMessage": "require is not defined in ES module scope, you can use import instead",
  "trace": [
    "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:921:16)",
    "    at async _tryRequire (file:///var/runtime/index.mjs:970:86)",
    "    at async _loadUserApp (file:///var/runtime/index.mjs:994:16)",
    "    at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1035:21)",
    "    at async start (file:///var/runtime/index.mjs:1200:23)",
    "    at async file:///var/runtime/index.mjs:1206:1"
  ]
}

How to resolve it? and what is causing this issue? Thanks.

  • Yup, same thing here. I can confirm that the tutorial seems to be incorrect.

3 Answers
1
Accepted Answer

This is seen if you are using NodeJS 14 or above which no longer has require by default. See https://nodejs.org/api/esm.html#no-require-exports-or-moduleexports

You can fix this by adding these two lines at the top of your file.

import { createRequire } from 'module';
const require = createRequire(import.meta.url);
AWS
dsp
answered a year ago
profile picture
EXPERT
reviewed 5 months ago
  • I followed the same tutorial and ran into the same error.

    The solution doesn't solve it for me unfortunately. If I paste it literally at the top of the file, the new error is:

    "errorType": "Runtime.ImportModuleError", "errorMessage": "Error: Cannot find module 'aws-sdk'\nRequire stack:\n- /var/task/index.mjs",

    But if respect that it first should say const AWS = require("aws-sdk"); and I paste it anywhere under that line, then the error changes into:

    "errorType": "ReferenceError", "errorMessage": "Cannot access 'require' before initialization",

    Any ideas on how to move on?

    Thanks!

  • @BSPNas Are you using Node 18.x runtime? If so, the aws-sdk module isn't shipped with that runtime today (See https://github.com/aws/aws-lambda-base-images/issues/47#issuecomment-1292011841). To fix this, you can either change runtime to Node 16.x or add a layer that contains the required SDK. Also, the fix in my original answer is required if your index file extension is ".mjs". If you rename the file to ".js" and change runtime to Node 16.x then the code given in the blog link should work as is.

  • I found this solution and it worked for me:

    import { createRequire } from 'module'; const require = createRequire(import.meta.url); const { DynamoDB } = require("@aws-sdk/client-dynamodb"); const dynamodb = new DynamoDB({apiVersion: '2012-08-10', region: 'us-east-1'})

    Hope it will help anybody.

  • but then it occurs "SyntaxError: Cannot use import statement outside a module" errors? anyone got this issues also?

    I got this both in node 14, 16, 18 environment

1

SDK V2

const AWS = require("aws-sdk");

const dynamo = new AWS.DynamoDB.DocumentClient();

SDK V3

const {DynamoDB} = require("@aws-sdk/client-dynamodb");

const dynamo = new DynamoDB({});

Backward V2 Compatibility Style

import * as AWS from "@aws-sdk/client-dynamodb";

const dynamo = new AWS.DynamoDB({});

See https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/welcome.html

answered 6 months ago
0

I only got it to work with Node 18 after

  1. installing the DynamoDB client in Cloudshell with
npm install @aws-sdk/client-dynamodb

from https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/installing-jssdk.html

  1. changing the code to
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { PutCommand, DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);

/**
 * Returns an HTML page containing an interactive Web-based tutorial.
 * Visit the function URL to see it and learn how to build with lambda.
 */
export const handler = async (event) => {
    if(event.queryStringParameters){
        const command = new PutCommand({
            TableName: "formStore",
            Item: {
              PK: "form",
              SK: event.requestContext.requestId,
              form: event.queryStringParameters
            }
        });
        const response = await docClient.send(command);
        console.log(response);
    }

from https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/javascript_dynamodb_code_examples.html#actions

  1. creating the formStore table in AWS Dynamo DB with PK as partition key and SK as sort key and adding the dynamoDB:PutItem permission to the IAM Role of my Lambda function
To add the dynamoDb:PutItem permission to the IAM role of your Lambda function:
1. Open the IAM console and navigate to the role used by your Lambda function (link) .
2. Click on the "Permissions" tab.
3. Click "Create inline policy".
4. Choose "DynamoDB" as the service.
5. In the "Actions" search box, type "PutItem" and select it.
6. For the "Resources" field, specify the ARN of your DynamoDB table (e.g. arn:aws:dynamodb:region:account-id:table/table-name).
7. Click "Review Policy" then "Create Policy".
answered 2 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions