Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default import from an ESM package into a CommonJS project with esModuleInterop is faulty #58341

Closed
JonasDoe opened this issue Apr 27, 2024 · 3 comments
Labels
External Relates to another program, environment, or user action which we cannot control.

Comments

@JonasDoe
Copy link

JonasDoe commented Apr 27, 2024

🔎 Search Terms

"cjs esm esModuleInterop default", "common esm esModuleInterop default"

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about default imports from ESM to CommonJS
  • I'm using TypeScript 5.4.5

⏯ Playground Link

https://github.com/JonasDoe/typescript-esm-issue

💻 Code

With esModuleInterop=true:

import { default as Provider } from 'oidc-provider'; // this is an ESM project with export default class Provider
console.log('Created new Provider:', new Provider('http://example.tld'))

The transpiled code will be:

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const oidc_provider_1 = __importDefault(require("oidc-provider"));
console.log('Created new Provider:', new oidc_provider_1.default('http://example.tld'));

🙁 Actual behavior

  • Create a CommonJS project with Node22, so --experimental-require-module is supported.
  • Import the default export of an ESM dependency
  • Enable esModuleInterop
  • Transpilation will create an object like {"default": {"default": the-imported-object}}, so the-imported-object isn't found

🙂 Expected behavior

  • Transpilation should create an object like {"default": the-imported-object}, so without the double nesting.

Additional information about the issue

The original suggestion that this is a bug in TypeScript came from here: panva/node-oidc-provider#1249 (reply in thread), and by a person with greater knowledge about Node and TypeScript. So I'm sorry if I left something unclear.

@RyanCavanaugh
Copy link
Member

esModuleInterop depends on the __esModule property in order to work, but Node's --experimental-require-module doesn't generate that. See nodejs/node#52697

@RyanCavanaugh
Copy link
Member

Also nodejs/node#52166

Once that experimental feature lands (unexperimentally) in Node, you'll need to a) update to a version of TypeScript, which will eventually exist, that supports it and b) set module: nodenext in tsconfig

@RyanCavanaugh RyanCavanaugh added the External Relates to another program, environment, or user action which we cannot control. label Apr 29, 2024
@JonasDoe
Copy link
Author

I see! Thank you for the reponse!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
External Relates to another program, environment, or user action which we cannot control.
Projects
None yet
Development

No branches or pull requests

2 participants