mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
ESM mode nonrelative imports should assume index.js entrypoints even if no package main is present (#47854)
This commit is contained in:
parent
e204acfa26
commit
1bdb0d90bf
@ -1394,7 +1394,13 @@ namespace ts {
|
||||
onlyRecordFailures = true;
|
||||
}
|
||||
}
|
||||
return loadNodeModuleFromDirectory(extensions, candidate, onlyRecordFailures, state, considerPackageJson);
|
||||
// esm mode relative imports shouldn't do any directory lookups (either inside `package.json`
|
||||
// files or implicit `index.js`es). This is a notable depature from cjs norms, where `./foo/pkg`
|
||||
// could have been redirected by `./foo/pkg/package.json` to an arbitrary location!
|
||||
if (!(state.features & NodeResolutionFeatures.EsmMode)) {
|
||||
return loadNodeModuleFromDirectory(extensions, candidate, onlyRecordFailures, state, considerPackageJson);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
@ -2178,7 +2184,7 @@ namespace ts {
|
||||
if (packageInfo && packageInfo.packageJsonContent.exports && state.features & NodeResolutionFeatures.Exports) {
|
||||
return loadModuleFromExports(packageInfo, extensions, combinePaths(".", rest), state, cache, redirectedReference)?.value;
|
||||
}
|
||||
const pathAndExtension =
|
||||
let pathAndExtension =
|
||||
loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) ||
|
||||
loadNodeModuleFromDirectoryWorker(
|
||||
extensions,
|
||||
@ -2188,6 +2194,16 @@ namespace ts {
|
||||
packageInfo && packageInfo.packageJsonContent,
|
||||
packageInfo && packageInfo.versionPaths
|
||||
);
|
||||
if (
|
||||
!pathAndExtension && packageInfo
|
||||
&& packageInfo.packageJsonContent.exports === undefined
|
||||
&& packageInfo.packageJsonContent.main === undefined
|
||||
&& state.features & NodeResolutionFeatures.EsmMode
|
||||
) {
|
||||
// EsmMode disables index lookup in `loadNodeModuleFromDirectoryWorker` generally, however non-relative package resolutions still assume
|
||||
// a default `index.js` entrypoint if no `main` or `exports` are present
|
||||
pathAndExtension = loadModuleFromFile(extensions, combinePaths(candidate, "index.js"), onlyRecordFailures, state);
|
||||
}
|
||||
return withPackageId(packageInfo, pathAndExtension);
|
||||
};
|
||||
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
tests/cases/compiler/index.ts(2,31): error TS2834: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node12' or 'nodenext'. Consider adding an extension to the import path.
|
||||
tests/cases/compiler/index.ts(3,31): error TS2834: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node12' or 'nodenext'. Consider adding an extension to the import path.
|
||||
|
||||
|
||||
==== tests/cases/compiler/node_modules/pkg/package.json (0 errors) ====
|
||||
{
|
||||
"name": "pkg",
|
||||
"version": "0.0.1"
|
||||
}
|
||||
==== tests/cases/compiler/node_modules/pkg/index.d.ts (0 errors) ====
|
||||
export const item = 4;
|
||||
==== tests/cases/compiler/pkg/package.json (0 errors) ====
|
||||
{
|
||||
"private": true
|
||||
}
|
||||
==== tests/cases/compiler/pkg/index.d.ts (0 errors) ====
|
||||
export const item = 4;
|
||||
==== tests/cases/compiler/package.json (0 errors) ====
|
||||
{
|
||||
"type": "module",
|
||||
"private": true
|
||||
}
|
||||
==== tests/cases/compiler/index.ts (2 errors) ====
|
||||
import { item } from "pkg"; // should work (`index.js` is assumed to be the entrypoint for packages found via nonrelative import)
|
||||
import { item as item2 } from "./pkg"; // shouldn't work (`index.js` is _not_ assumed to be the entrypoint for packages found via relative import)
|
||||
~~~~~~~
|
||||
!!! error TS2834: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node12' or 'nodenext'. Consider adding an extension to the import path.
|
||||
import { item as item3 } from "./node_modules/pkg" // _even if they're in a node_modules folder_
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2834: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node12' or 'nodenext'. Consider adding an extension to the import path.
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
//// [tests/cases/compiler/nodeNextImportModeImplicitIndexResolution.ts] ////
|
||||
|
||||
//// [package.json]
|
||||
{
|
||||
"name": "pkg",
|
||||
"version": "0.0.1"
|
||||
}
|
||||
//// [index.d.ts]
|
||||
export const item = 4;
|
||||
//// [package.json]
|
||||
{
|
||||
"private": true
|
||||
}
|
||||
//// [index.d.ts]
|
||||
export const item = 4;
|
||||
//// [package.json]
|
||||
{
|
||||
"type": "module",
|
||||
"private": true
|
||||
}
|
||||
//// [index.ts]
|
||||
import { item } from "pkg"; // should work (`index.js` is assumed to be the entrypoint for packages found via nonrelative import)
|
||||
import { item as item2 } from "./pkg"; // shouldn't work (`index.js` is _not_ assumed to be the entrypoint for packages found via relative import)
|
||||
import { item as item3 } from "./node_modules/pkg" // _even if they're in a node_modules folder_
|
||||
|
||||
|
||||
//// [index.js]
|
||||
export {};
|
||||
@ -0,0 +1,18 @@
|
||||
=== tests/cases/compiler/node_modules/pkg/index.d.ts ===
|
||||
export const item = 4;
|
||||
>item : Symbol(item, Decl(index.d.ts, 0, 12))
|
||||
|
||||
=== tests/cases/compiler/pkg/index.d.ts ===
|
||||
export const item = 4;
|
||||
>item : Symbol(item, Decl(index.d.ts, 0, 12))
|
||||
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import { item } from "pkg"; // should work (`index.js` is assumed to be the entrypoint for packages found via nonrelative import)
|
||||
>item : Symbol(item, Decl(index.ts, 0, 8))
|
||||
|
||||
import { item as item2 } from "./pkg"; // shouldn't work (`index.js` is _not_ assumed to be the entrypoint for packages found via relative import)
|
||||
>item2 : Symbol(item2, Decl(index.ts, 1, 8))
|
||||
|
||||
import { item as item3 } from "./node_modules/pkg" // _even if they're in a node_modules folder_
|
||||
>item3 : Symbol(item3, Decl(index.ts, 2, 8))
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
=== tests/cases/compiler/node_modules/pkg/index.d.ts ===
|
||||
export const item = 4;
|
||||
>item : 4
|
||||
>4 : 4
|
||||
|
||||
=== tests/cases/compiler/pkg/index.d.ts ===
|
||||
export const item = 4;
|
||||
>item : 4
|
||||
>4 : 4
|
||||
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import { item } from "pkg"; // should work (`index.js` is assumed to be the entrypoint for packages found via nonrelative import)
|
||||
>item : 4
|
||||
|
||||
import { item as item2 } from "./pkg"; // shouldn't work (`index.js` is _not_ assumed to be the entrypoint for packages found via relative import)
|
||||
>item : any
|
||||
>item2 : any
|
||||
|
||||
import { item as item3 } from "./node_modules/pkg" // _even if they're in a node_modules folder_
|
||||
>item : any
|
||||
>item3 : any
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
// @module: nodenext
|
||||
// @filename: node_modules/pkg/package.json
|
||||
{
|
||||
"name": "pkg",
|
||||
"version": "0.0.1"
|
||||
}
|
||||
// @filename: node_modules/pkg/index.d.ts
|
||||
export const item = 4;
|
||||
// @filename: pkg/package.json
|
||||
{
|
||||
"private": true
|
||||
}
|
||||
// @filename: pkg/index.d.ts
|
||||
export const item = 4;
|
||||
// @filename: package.json
|
||||
{
|
||||
"type": "module",
|
||||
"private": true
|
||||
}
|
||||
// @filename: index.ts
|
||||
import { item } from "pkg"; // should work (`index.js` is assumed to be the entrypoint for packages found via nonrelative import)
|
||||
import { item as item2 } from "./pkg"; // shouldn't work (`index.js` is _not_ assumed to be the entrypoint for packages found via relative import)
|
||||
import { item as item3 } from "./node_modules/pkg" // _even if they're in a node_modules folder_
|
||||
Loading…
x
Reference in New Issue
Block a user