Skip to content

import=require emits incorrectly with NodeNext, target<=es2018, when emitting as ESM #48876

@cspotcode

Description

@cspotcode

Bug Report

🔎 Search Terms

nodenext createrequire
nodenext import
node12

Discussed here:
#46452 (comment)

🕗 Version & Regression Information

typescript@4.7.0-dev.20220428

This is the behavior in every version I tried, and I reviewed the FAQ for entries about NodeNext
I was unable to test this on prior versions because this feature is new in 4.7

⏯ Playground Link

The playground does not allow specifying package.json "type", so instead, I've published a minimal reproduction here:

https://github.com/cspotcode/repros/tree/ts-nodenext-emit-bug

💻 Code

tsconfig.json

{
    "compilerOptions": {
        // This bug occurs when using the new Node module type and resolver
        // And when target is <= es2018
        "module": "NodeNext",
        "moduleResolution": "NodeNext",
        "target": "es2018"
    }
}

package.json

{
  "type": "module"
}
// This should emit a call to createRequire(import.meta.url)
import foo = require('foo');
foo;

🙁 Actual behavior

When target is <= es2018, the import is entirely omitted from the emit.

It looks like this: https://github.com/cspotcode/repros/blob/ts-nodenext-emit-bug/dist/example.js

foo;
export {};

🙂 Expected behavior

The import is emitted, including a call to createRequire()

It should look like this: https://github.com/cspotcode/repros/blob/ts-nodenext-emit-bug/dist-with-bug-workaround/example.js

import { createRequire as _createRequire } from "module";
const __require = _createRequire(import.meta.url);
// This should emit a call to createRequire(import.meta.url)
const foo = __require("foo");
foo;

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions