Skip to content

CommonJS dist is imported instead of ESModule when using Node.js with ESModules, causing import errors. #2754

@dsommerich

Description

@dsommerich

Describe the bug

When importing the SDK from a plain ESModule file in Node.js (i.e. without using a bundler), Node.js attempts to import the CommonJS dist (@aws-sdk/*/dist/cjs) instead of the ESModule dist. This causes an error due to missing named exports, as Node.js can't translate the CommonJS exports to named exports and only exposes a default export.

Your environment

SDK version number

@aws-sdk/[email protected]

Is the issue in the browser/Node.js/ReactNative?

Node.js

Details of the browser/Node.js/ReactNative version

Tested on Node.js v16.8.0, v14.17.6 , v12.22.1.

Steps to reproduce

package.json:

{
  "type": "module",
  "dependencies": {
    "@aws-sdk/client-dynamodb": "^3.29.0"
  }
}

main.js:

import { DynamoDB } from "@aws-sdk/client-dynamodb";

Then run node main.js.

Observed behavior

This error occurs:

import { DynamoDB } from "@aws-sdk/client-dynamodb";
         ^^^^^^^^
SyntaxError: Named export 'DynamoDB' not found. The requested module '@aws-sdk/client-dynamodb' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@aws-sdk/client-dynamodb';
const { DynamoDB } = pkg;

    at ModuleJob._instantiate (internal/modules/esm/module_job.js:121:21)
    at async ModuleJob.run (internal/modules/esm/module_job.js:166:5)
    at async Loader.import (internal/modules/esm/loader.js:178:24)
    at async Object.loadESM (internal/process/esm_loader.js:68:5)

Expected behavior

The package should be imported and work using named imports, without having to use a default import.

Additional context

The error message does give a workaround, but this workaround is unergonomic and requires even more changes when migrating to ESModules. With many packages moving to being pure ESM (whether we like it or not), this problem is just adding unnecessary work when users a forced to move to ESM.

The SDK should define the exports field in the package.json instead of just main and module (which Node.js ignores). See Dual CommonJS/ES module packages. Additionally, the ESModule dist needs to add file extensions to its imports, i.e. import ... "./foo.js"; or import ... "./foo/index.js"; instead of import ... "./foo"; (doing this would probably also help with #1289).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions