Skip to content

Commit

Permalink
Support require(esm) in --module nodenext (#60761)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewbranch authored Jan 23, 2025
1 parent efe07a0 commit 5e52b28
Show file tree
Hide file tree
Showing 209 changed files with 3,602 additions and 580 deletions.
6 changes: 5 additions & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4715,7 +4715,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (errorNode && resolvedModule.isExternalLibraryImport && !resolutionExtensionIsTSOrJson(resolvedModule.extension)) {
errorOnImplicitAnyModule(/*isError*/ false, errorNode, currentSourceFile, mode, resolvedModule, moduleReference);
}
if (errorNode && (moduleResolutionKind === ModuleResolutionKind.Node16 || moduleResolutionKind === ModuleResolutionKind.NodeNext)) {
if (errorNode && (moduleKind === ModuleKind.Node16 || moduleKind === ModuleKind.Node18)) {
const isSyncImport = (currentSourceFile.impliedNodeFormat === ModuleKind.CommonJS && !findAncestor(location, isImportCall)) || !!findAncestor(location, isImportEqualsDeclaration);
const overrideHost = findAncestor(location, l => isImportTypeNode(l) || isExportDeclaration(l) || isImportDeclaration(l) || isJSDocImportTag(l));
// An override clause will take effect for type-only imports and import types, and allows importing the types across formats, regardless of
Expand Down Expand Up @@ -48082,6 +48082,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
);
}

if (moduleKind === ModuleKind.NodeNext && !isImportAttributes) {
return grammarErrorOnFirstToken(node, Diagnostics.Import_assertions_have_been_replaced_by_import_attributes_Use_with_instead_of_asserts);
}

if (declaration.moduleSpecifier && getEmitSyntaxForModuleSpecifierExpression(declaration.moduleSpecifier) === ModuleKind.CommonJS) {
return grammarErrorOnNode(
node,
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3980,6 +3980,10 @@
"category": "Error",
"code": 2879
},
"Import assertions have been replaced by import attributes. Use 'with' instead of 'asserts'.": {
"category": "Error",
"code": 2880
},

"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error TS5095: Option 'bundler' can only be used when 'module' is set to 'preserve' or to 'es2015' or later.
error TS5109: Option 'moduleResolution' must be set to 'Node16' (or left unspecified) when option 'module' is set to 'Node18'.


!!! error TS5095: Option 'bundler' can only be used when 'module' is set to 'preserve' or to 'es2015' or later.
!!! error TS5109: Option 'moduleResolution' must be set to 'Node16' (or left unspecified) when option 'module' is set to 'Node18'.
==== /app/test.ts (0 errors) ====
import { test } from '../lib';

==== /lib/package.json (0 errors) ====
{
"main": "./cjs/index.js"
}

==== /lib/cjs/index.js (0 errors) ====
export function test() {}

==== /lib/cjs/index.d.ts (0 errors) ====
export function test(): void;

Large diffs are not rendered by default.

Large diffs are not rendered by default.

File renamed without changes.
12 changes: 12 additions & 0 deletions tests/baselines/reference/cjsErrors(module=nodenext).errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
index.ts(1,22): error TS2876: This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to "./foo.ts/index.ts".


==== index.ts (1 errors) ====
import foo = require("./foo.ts"); // Error
~~~~~~~~~~
!!! error TS2876: This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to "./foo.ts/index.ts".
import type _foo = require("./foo.ts"); // Ok

==== foo.ts/index.ts (0 errors) ====
export = {};

17 changes: 17 additions & 0 deletions tests/baselines/reference/cjsErrors(module=nodenext).js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts] ////

//// [index.ts]
export = {};

//// [index.ts]
import foo = require("./foo.ts"); // Error
import type _foo = require("./foo.ts"); // Ok


//// [index.js]
"use strict";
module.exports = {};
//// [index.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const foo = require("./foo.js"); // Error
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
main.ts(1,18): error TS2307: Cannot find module './file.js' or its corresponding type declarations.
main.ts(2,18): error TS2307: Cannot find module './file.jsx' or its corresponding type declarations.
main.ts(3,18): error TS2307: Cannot find module './file.ts' or its corresponding type declarations.
main.ts(4,18): error TS2307: Cannot find module './file.tsx' or its corresponding type declarations.
main.ts(5,18): error TS2307: Cannot find module './file.mjs' or its corresponding type declarations.
main.ts(6,18): error TS2307: Cannot find module './file.cjs' or its corresponding type declarations.
main.ts(7,18): error TS2307: Cannot find module './file.mts' or its corresponding type declarations.
main.ts(8,18): error TS2307: Cannot find module './file.cts' or its corresponding type declarations.
main.ts(9,18): error TS2307: Cannot find module './file.d.ts' or its corresponding type declarations.
main.ts(10,19): error TS2307: Cannot find module './file.d.cts' or its corresponding type declarations.
main.ts(11,19): error TS2307: Cannot find module './file.d.mts' or its corresponding type declarations.
main.ts(12,19): error TS2307: Cannot find module './file.d.json.ts' or its corresponding type declarations.


==== package.json (0 errors) ====
{"type": "module"}
==== main.ts (12 errors) ====
import def1 from "./file.js";
~~~~~~~~~~~
!!! error TS2307: Cannot find module './file.js' or its corresponding type declarations.
import def2 from "./file.jsx";
~~~~~~~~~~~~
!!! error TS2307: Cannot find module './file.jsx' or its corresponding type declarations.
import def3 from "./file.ts";
~~~~~~~~~~~
!!! error TS2307: Cannot find module './file.ts' or its corresponding type declarations.
import def4 from "./file.tsx";
~~~~~~~~~~~~
!!! error TS2307: Cannot find module './file.tsx' or its corresponding type declarations.
import def5 from "./file.mjs";
~~~~~~~~~~~~
!!! error TS2307: Cannot find module './file.mjs' or its corresponding type declarations.
import def6 from "./file.cjs";
~~~~~~~~~~~~
!!! error TS2307: Cannot find module './file.cjs' or its corresponding type declarations.
import def7 from "./file.mts";
~~~~~~~~~~~~
!!! error TS2307: Cannot find module './file.mts' or its corresponding type declarations.
import def8 from "./file.cts";
~~~~~~~~~~~~
!!! error TS2307: Cannot find module './file.cts' or its corresponding type declarations.
import def9 from "./file.d.ts";
~~~~~~~~~~~~~
!!! error TS2307: Cannot find module './file.d.ts' or its corresponding type declarations.
import def10 from "./file.d.cts";
~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module './file.d.cts' or its corresponding type declarations.
import def11 from "./file.d.mts";
~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module './file.d.mts' or its corresponding type declarations.
import def12 from "./file.d.json.ts";
~~~~~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module './file.d.json.ts' or its corresponding type declarations.
==== file.d.js.ts (0 errors) ====
declare var bad: "bad1";
export default bad;
==== file.d.jsx.ts (0 errors) ====
declare var bad: "bad2";
export default bad;
==== file.d.ts.ts (0 errors) ====
declare var bad: "bad3";
export default bad;
==== file.d.tsx.ts (0 errors) ====
declare var bad: "bad4";
export default bad;
==== file.d.mjs.ts (0 errors) ====
declare var bad: "bad5";
export default bad;
==== file.d.cjs.ts (0 errors) ====
declare var bad: "bad6";
export default bad;
==== file.d.mts.ts (0 errors) ====
declare var bad: "bad7";
export default bad;
==== file.d.cts.ts (0 errors) ====
declare var bad: "bad8";
export default bad;
==== file.d.d.ts.ts (0 errors) ====
declare var bad: "bad9";
export default bad;
==== file.d.d.mts.ts (0 errors) ====
declare var bad: "bad10";
export default bad;
==== file.d.d.cts.ts (0 errors) ====
declare var bad: "bad11";
export default bad;
==== file.d.d.json.ts (0 errors) ====
declare var bad: "bad12";
export default bad;
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//// [tests/cases/conformance/nonjsExtensions/declarationFileForTsJsImport.ts] ////

//// [package.json]
{"type": "module"}
//// [main.ts]
import def1 from "./file.js";
import def2 from "./file.jsx";
import def3 from "./file.ts";
import def4 from "./file.tsx";
import def5 from "./file.mjs";
import def6 from "./file.cjs";
import def7 from "./file.mts";
import def8 from "./file.cts";
import def9 from "./file.d.ts";
import def10 from "./file.d.cts";
import def11 from "./file.d.mts";
import def12 from "./file.d.json.ts";
//// [file.d.js.ts]
declare var bad: "bad1";
export default bad;
//// [file.d.jsx.ts]
declare var bad: "bad2";
export default bad;
//// [file.d.ts.ts]
declare var bad: "bad3";
export default bad;
//// [file.d.tsx.ts]
declare var bad: "bad4";
export default bad;
//// [file.d.mjs.ts]
declare var bad: "bad5";
export default bad;
//// [file.d.cjs.ts]
declare var bad: "bad6";
export default bad;
//// [file.d.mts.ts]
declare var bad: "bad7";
export default bad;
//// [file.d.cts.ts]
declare var bad: "bad8";
export default bad;
//// [file.d.d.ts.ts]
declare var bad: "bad9";
export default bad;
//// [file.d.d.mts.ts]
declare var bad: "bad10";
export default bad;
//// [file.d.d.cts.ts]
declare var bad: "bad11";
export default bad;
//// [file.d.d.json.ts]
declare var bad: "bad12";
export default bad;

//// [main.js]
export {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
//// [tests/cases/conformance/nonjsExtensions/declarationFileForTsJsImport.ts] ////

=== main.ts ===
import def1 from "./file.js";
>def1 : Symbol(def1, Decl(main.ts, 0, 6))

import def2 from "./file.jsx";
>def2 : Symbol(def2, Decl(main.ts, 1, 6))

import def3 from "./file.ts";
>def3 : Symbol(def3, Decl(main.ts, 2, 6))

import def4 from "./file.tsx";
>def4 : Symbol(def4, Decl(main.ts, 3, 6))

import def5 from "./file.mjs";
>def5 : Symbol(def5, Decl(main.ts, 4, 6))

import def6 from "./file.cjs";
>def6 : Symbol(def6, Decl(main.ts, 5, 6))

import def7 from "./file.mts";
>def7 : Symbol(def7, Decl(main.ts, 6, 6))

import def8 from "./file.cts";
>def8 : Symbol(def8, Decl(main.ts, 7, 6))

import def9 from "./file.d.ts";
>def9 : Symbol(def9, Decl(main.ts, 8, 6))

import def10 from "./file.d.cts";
>def10 : Symbol(def10, Decl(main.ts, 9, 6))

import def11 from "./file.d.mts";
>def11 : Symbol(def11, Decl(main.ts, 10, 6))

import def12 from "./file.d.json.ts";
>def12 : Symbol(def12, Decl(main.ts, 11, 6))

=== file.d.js.ts ===
declare var bad: "bad1";
>bad : Symbol(bad, Decl(file.d.js.ts, 0, 11))

export default bad;
>bad : Symbol(bad, Decl(file.d.js.ts, 0, 11))

=== file.d.jsx.ts ===
declare var bad: "bad2";
>bad : Symbol(bad, Decl(file.d.jsx.ts, 0, 11))

export default bad;
>bad : Symbol(bad, Decl(file.d.jsx.ts, 0, 11))

=== file.d.ts.ts ===
declare var bad: "bad3";
>bad : Symbol(bad, Decl(file.d.ts.ts, 0, 11))

export default bad;
>bad : Symbol(bad, Decl(file.d.ts.ts, 0, 11))

=== file.d.tsx.ts ===
declare var bad: "bad4";
>bad : Symbol(bad, Decl(file.d.tsx.ts, 0, 11))

export default bad;
>bad : Symbol(bad, Decl(file.d.tsx.ts, 0, 11))

=== file.d.mjs.ts ===
declare var bad: "bad5";
>bad : Symbol(bad, Decl(file.d.mjs.ts, 0, 11))

export default bad;
>bad : Symbol(bad, Decl(file.d.mjs.ts, 0, 11))

=== file.d.cjs.ts ===
declare var bad: "bad6";
>bad : Symbol(bad, Decl(file.d.cjs.ts, 0, 11))

export default bad;
>bad : Symbol(bad, Decl(file.d.cjs.ts, 0, 11))

=== file.d.mts.ts ===
declare var bad: "bad7";
>bad : Symbol(bad, Decl(file.d.mts.ts, 0, 11))

export default bad;
>bad : Symbol(bad, Decl(file.d.mts.ts, 0, 11))

=== file.d.cts.ts ===
declare var bad: "bad8";
>bad : Symbol(bad, Decl(file.d.cts.ts, 0, 11))

export default bad;
>bad : Symbol(bad, Decl(file.d.cts.ts, 0, 11))

=== file.d.d.ts.ts ===
declare var bad: "bad9";
>bad : Symbol(bad, Decl(file.d.d.ts.ts, 0, 11))

export default bad;
>bad : Symbol(bad, Decl(file.d.d.ts.ts, 0, 11))

=== file.d.d.mts.ts ===
declare var bad: "bad10";
>bad : Symbol(bad, Decl(file.d.d.mts.ts, 0, 11))

export default bad;
>bad : Symbol(bad, Decl(file.d.d.mts.ts, 0, 11))

=== file.d.d.cts.ts ===
declare var bad: "bad11";
>bad : Symbol(bad, Decl(file.d.d.cts.ts, 0, 11))

export default bad;
>bad : Symbol(bad, Decl(file.d.d.cts.ts, 0, 11))

=== file.d.d.json.ts ===
declare var bad: "bad12";
>bad : Symbol(bad, Decl(file.d.d.json.ts, 0, 11))

export default bad;
>bad : Symbol(bad, Decl(file.d.d.json.ts, 0, 11))

Loading

0 comments on commit 5e52b28

Please sign in to comment.