Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion src/compiler/moduleNameResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2804,7 +2804,23 @@ function getLoadModuleFromTargetExportOrImport(extensions: Extensions, state: Mo
const finalPath = toAbsolutePath(pattern ? resolvedTarget.replace(/\*/g, subpath) : resolvedTarget + subpath);
const inputLink = tryLoadInputFileForPath(finalPath, subpath, combinePaths(scope.packageDirectory, "package.json"), isImports);
if (inputLink) return inputLink;
return toSearchResult(withPackageId(scope, loadFileNameFromPackageJsonField(extensions, finalPath, target, /*onlyRecordFailures*/ false, state), state));
// First try the standard package.json field resolution
const fromPkgJsonField = loadFileNameFromPackageJsonField(extensions, finalPath, target, /*onlyRecordFailures*/ false, state);
if (fromPkgJsonField) {
return toSearchResult(withPackageId(scope, fromPkgJsonField, state));
}
// For extensionless paths in bundler mode (non-ESM), try adding extensions (e.g., ./foo -> ./foo.ts)
// This handles wildcard exports like "./*": "./src/*" where the resolved path has no extension.
if (!(state.features & NodeResolutionFeatures.EsmMode)) {
const filename = getBaseFileName(finalPath);
if (!filename.includes(".")) {
const fromFile = loadModuleFromFile(extensions, finalPath, /*onlyRecordFailures*/ false, state);
if (fromFile) {
return toSearchResult(withPackageId(scope, fromFile, state));
}
}
}
return toSearchResult(/*value*/ undefined);
}
else if (typeof target === "object" && target !== null) { // eslint-disable-line no-restricted-syntax
if (!Array.isArray(target)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//// [tests/cases/compiler/bundlerWildcardExportsExtensionResolution.ts] ////

=== /node_modules/@repo/library/src/utils.ts ===
export function greet(): string {
>greet : Symbol(greet, Decl(utils.ts, 0, 0))

return "hello";
}

=== /node_modules/@repo/library/src/component.tsx ===
export const Component = () => null;
>Component : Symbol(Component, Decl(component.tsx, 0, 12))

=== /node_modules/@repo/library/src/deep/nested/module.ts ===
export const deep = true;
>deep : Symbol(deep, Decl(module.ts, 0, 12))

=== /app.ts ===
// These imports should all resolve successfully in bundler mode
import { greet } from "@repo/library/utils";
>greet : Symbol(greet, Decl(app.ts, 1, 8))

import { Component } from "@repo/library/component";
>Component : Symbol(Component, Decl(app.ts, 2, 8))

import { deep } from "@repo/library/deep/nested/module";
>deep : Symbol(deep, Decl(app.ts, 3, 8))

greet();
>greet : Symbol(greet, Decl(app.ts, 1, 8))

Component;
>Component : Symbol(Component, Decl(app.ts, 2, 8))

deep;
>deep : Symbol(deep, Decl(app.ts, 3, 8))

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[
"File '/node_modules/@repo/library/src/package.json' does not exist.",
"Found 'package.json' at '/node_modules/@repo/library/package.json'.",
"File '/node_modules/@repo/library/src/package.json' does not exist according to earlier cached lookups.",
"File '/node_modules/@repo/library/package.json' exists according to earlier cached lookups.",
"File '/node_modules/@repo/library/src/deep/nested/package.json' does not exist.",
"File '/node_modules/@repo/library/src/deep/package.json' does not exist.",
"File '/node_modules/@repo/library/src/package.json' does not exist according to earlier cached lookups.",
"File '/node_modules/@repo/library/package.json' exists according to earlier cached lookups.",
"======== Resolving module '@repo/library/utils' from '/app.ts'. ========",
"Explicitly specified module resolution kind: 'Bundler'.",
"Resolving in CJS mode with conditions 'import', 'types'.",
"File '/package.json' does not exist.",
"Loading module '@repo/library/utils' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.",
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
"File '/node_modules/@repo/library/package.json' exists according to earlier cached lookups.",
"Using 'exports' subpath './*' with target './src/utils'.",
"File '/node_modules/@repo/library/src/utils.ts' exists - use it as a name resolution result.",
"Resolving real path for '/node_modules/@repo/library/src/utils.ts', result '/node_modules/@repo/library/src/utils.ts'.",
"======== Module name '@repo/library/utils' was successfully resolved to '/node_modules/@repo/library/src/utils.ts'. ========",
"======== Resolving module '@repo/library/component' from '/app.ts'. ========",
"Explicitly specified module resolution kind: 'Bundler'.",
"Resolving in CJS mode with conditions 'import', 'types'.",
"File '/package.json' does not exist according to earlier cached lookups.",
"Loading module '@repo/library/component' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.",
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
"File '/node_modules/@repo/library/package.json' exists according to earlier cached lookups.",
"Using 'exports' subpath './*' with target './src/component'.",
"File '/node_modules/@repo/library/src/component.ts' does not exist.",
"File '/node_modules/@repo/library/src/component.tsx' exists - use it as a name resolution result.",
"Resolving real path for '/node_modules/@repo/library/src/component.tsx', result '/node_modules/@repo/library/src/component.tsx'.",
"======== Module name '@repo/library/component' was successfully resolved to '/node_modules/@repo/library/src/component.tsx'. ========",
"======== Resolving module '@repo/library/deep/nested/module' from '/app.ts'. ========",
"Explicitly specified module resolution kind: 'Bundler'.",
"Resolving in CJS mode with conditions 'import', 'types'.",
"File '/package.json' does not exist according to earlier cached lookups.",
"Loading module '@repo/library/deep/nested/module' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.",
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
"File '/node_modules/@repo/library/package.json' exists according to earlier cached lookups.",
"Using 'exports' subpath './*' with target './src/deep/nested/module'.",
"File '/node_modules/@repo/library/src/deep/nested/module.ts' exists - use it as a name resolution result.",
"Resolving real path for '/node_modules/@repo/library/src/deep/nested/module.ts', result '/node_modules/@repo/library/src/deep/nested/module.ts'.",
"======== Module name '@repo/library/deep/nested/module' was successfully resolved to '/node_modules/@repo/library/src/deep/nested/module.ts'. ========"
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//// [tests/cases/compiler/bundlerWildcardExportsExtensionResolution.ts] ////

=== /node_modules/@repo/library/src/utils.ts ===
export function greet(): string {
>greet : () => string
> : ^^^^^^

return "hello";
>"hello" : "hello"
> : ^^^^^^^
}

=== /node_modules/@repo/library/src/component.tsx ===
export const Component = () => null;
>Component : () => any
> : ^^^^^^^^^
>() => null : () => any
> : ^^^^^^^^^

=== /node_modules/@repo/library/src/deep/nested/module.ts ===
export const deep = true;
>deep : true
> : ^^^^
>true : true
> : ^^^^

=== /app.ts ===
// These imports should all resolve successfully in bundler mode
import { greet } from "@repo/library/utils";
>greet : () => string
> : ^^^^^^

import { Component } from "@repo/library/component";
>Component : () => any
> : ^^^^^^^^^

import { deep } from "@repo/library/deep/nested/module";
>deep : true
> : ^^^^

greet();
>greet() : string
> : ^^^^^^
>greet : () => string
> : ^^^^^^

Component;
>Component : () => any
> : ^^^^^^^^^

deep;
>deep : true
> : ^^^^

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/app.ts(2,23): error TS2307: Cannot find module '@repo/library/utils' or its corresponding type declarations.


==== /node_modules/@repo/library/package.json (0 errors) ====
{
"name": "@repo/library",
"type": "module",
"exports": {
"./*": "./src/*"
}
}

==== /node_modules/@repo/library/src/utils.ts (0 errors) ====
export function greet(): string {
return "hello";
}

==== /package.json (0 errors) ====
{
"type": "module"
}

==== /app.ts (1 errors) ====
// This import should FAIL in node16 mode - extensionless imports not supported
import { greet } from "@repo/library/utils";
~~~~~~~~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module '@repo/library/utils' or its corresponding type declarations.

greet();

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//// [tests/cases/compiler/node16WildcardExportsRequiresExtension.ts] ////

=== /node_modules/@repo/library/src/utils.ts ===
export function greet(): string {
>greet : Symbol(greet, Decl(utils.ts, 0, 0))

return "hello";
}

=== /app.ts ===
// This import should FAIL in node16 mode - extensionless imports not supported
import { greet } from "@repo/library/utils";
>greet : Symbol(greet, Decl(app.ts, 1, 8))

greet();
>greet : Symbol(greet, Decl(app.ts, 1, 8))

Loading