TypeStrong / ts-node

TypeScript execution and REPL for node.js
https://typestrong.org/ts-node
MIT License
12.92k stars 532 forks source link

Importing modules without named exports fails when using ts-node/esm #2130

Open Stono opened 3 months ago

Stono commented 3 months ago

Firstly, apologies if this thread comes across confused - because cjs -> esm really does have me confused. I'm trying to be a good citizen and move across, but it's painful. It's entirely possible i'm being an idiot. So let me explain with an example:

Take the kafkajs library as an example, it's a commonjs library with no named exports, when my app is commonjs, this code is fine:

import { ConfigResourceTypes } from 'kafkajs'
console.log(ConfigResourceTypes)
❯ ./node_modules/.bin/tsx lib/index.ts
{ UNKNOWN: 0, TOPIC: 2, BROKER: 4, BROKER_LOGGER: 8 }

However if i change my app to esm,(type: module in package.json), then it fails:

❯ ./node_modules/.bin/tsx lib/index.ts
import { ConfigResourceTypes } from 'kafkajs'
         ^
SyntaxError: The requested module 'kafkajs' does not provide an export named 'ConfigResourceTypes'
    at ModuleJob._instantiate (node:internal/modules/esm/module_job:171:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:254:5)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:485:26)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:109:5)

Node.js v22.5.1

The error makes sense, but it's unclear to me why it's fine if my app is commonjs, but not if it's esm. It's like in one of those scenarios it handles the fact it's a cjs module and almost pollyfills the named exports, but in the other it doesn't.

On top of that, the IDE has no problems at all, so this catches people out at runtime, which sucks. I think that's because @types/kafkajs gives it the impression it does have named exports.

Is this a bug with ts-node/esm? Or am I doing something straight up wrong? I've tried various permutations of allowSyntheticDefaultImports, esModuleInterop etc to try and get my IDE to fail in the same way ts-node does when running in esm, but I can't.