diff --git a/src/esm/hook/resolve.ts b/src/esm/hook/resolve.ts index 6c663854c..1e8f6111c 100644 --- a/src/esm/hook/resolve.ts +++ b/src/esm/hook/resolve.ts @@ -127,53 +127,50 @@ export const resolve: resolve = async ( || isRelativePathPattern.test(specifier) ); - // bare specifier - if (!isPath) { - // TS path alias - if ( - tsconfigPathsMatcher - && !context.parentURL?.includes('/node_modules/') - ) { - const possiblePaths = tsconfigPathsMatcher(specifier); - for (const possiblePath of possiblePaths) { - try { - return await resolve( - pathToFileURL(possiblePath).toString(), - context, - nextResolve, - ); - } catch {} + if (isPath) { + // Inherit namespace from parent + let requestNamespace = getNamespace(specifier); + if (context.parentURL) { + const parentNamespace = getNamespace(context.parentURL); + if (parentNamespace && !requestNamespace) { + requestNamespace = parentNamespace; + specifier += `${specifier.includes('?') ? '&' : '?'}${namespaceQuery}${parentNamespace}`; } } - // npm package -- use default resolution - return nextResolve(specifier, context); - } - - // Inherit namespace from parent - let requestNamespace = getNamespace(specifier); - if (context.parentURL) { - const parentNamespace = getNamespace(context.parentURL); - if (parentNamespace && !requestNamespace) { - requestNamespace = parentNamespace; - specifier += `${specifier.includes('?') ? '&' : '?'}${namespaceQuery}${parentNamespace}`; + if (data.namespace && data.namespace !== requestNamespace) { + return nextResolve(specifier, context); } - } - - if (data.namespace && data.namespace !== requestNamespace) { - return nextResolve(specifier, context); - } - // If directory, can be index.js, index.ts, etc. - if (isDirectoryPattern.test(specifier)) { - return await tryDirectory(specifier, context, nextResolve); + // If directory, can be index.js, index.ts, etc. + if (isDirectoryPattern.test(specifier)) { + return await tryDirectory(specifier, context, nextResolve); + } + } else if ( // Bare specifier + // TS path alias + tsconfigPathsMatcher + && !context.parentURL?.includes('/node_modules/') + ) { + const possiblePaths = tsconfigPathsMatcher(specifier); + for (const possiblePath of possiblePaths) { + try { + return await resolve( + pathToFileURL(possiblePath).toString(), + context, + nextResolve, + ); + } catch {} + } } // Typescript gives .ts, .cts, or .mts priority over actual .js, .cjs, or .mjs extensions // // If `allowJs` is set in `tsconfig.json`, then we'll apply the same resolution logic // to files without a TypeScript extension. - if (tsExtensionsPattern.test(context.parentURL!) || allowJs) { + if ( + tsExtensionsPattern.test(context.parentURL!) + || allowJs + ) { const tsPaths = resolveTsPath(specifier); if (tsPaths) { for (const tsPath of tsPaths) { diff --git a/tests/specs/smoke.ts b/tests/specs/smoke.ts index 83766b90b..5e4d8f736 100644 --- a/tests/specs/smoke.ts +++ b/tests/specs/smoke.ts @@ -238,10 +238,10 @@ const files = { 'pkg-module': { 'package.json': JSON.stringify({ type: 'module', - exports: './index.js', + main: './index.js', }), - 'index.js': `${syntaxLowering}\nexport * from "./empty-export.js"`, - 'empty-export.js': 'export {}', + 'index.js': `${syntaxLowering}\nexport * from "./empty-export"`, + 'empty-export/index.js': 'export {}', }, }, @@ -357,6 +357,7 @@ export default testSuite(async ({ describe }, { tsx }: NodeApis) => { import * as pkgCommonjs from 'pkg-commonjs'; import * as pkgModule from 'pkg-module'; + import 'pkg-module/empty-export'; // implicit directory & extension // .js import * as js from './js/index.js';