Skip to content

moduleResolution: 'bundler' with subpath import seem to not support directory module and extensionless import #60003

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
JunyeongChoi0 opened this issue Sep 19, 2024 · 5 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@JunyeongChoi0
Copy link

Demo Repo

https://github.com/JunyeongChoi0/typescript-error-reproduce

Which of the following problems are you reporting?

The module specifier resolves at runtime, but not at build time

Demonstrate the defect described above with a code sample.

The TypeScript documentation states that moduleResolution: 'bundler', unlike 'nodenext', supports extensionless imports and directory module imports. This works correctly when importing via relative paths, but when using subpath imports, an error occurs.

package.json

...
imports: {
  "#*": "./src/*
}
import { FOO } from '#libs/foo'  // error - why?
import { FOO } from '#libs/foo.ts' // works
import { BAR } from '#libs' // error - why?
import { BAR } from '#libs/index.ts' // works
import { FOO } from './libs/foo' //works
import { FOO } from './libs/foo.ts' //works
import { BAR } from './libs' //works

Run tsc --showConfig and paste its output here

{
"compilerOptions": {
"lib": [
"es2023"
],
"module": "preserve",
"target": "es2022",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"moduleResolution": "bundler",
"noEmit": true,
"isolatedModules": true,
"allowImportingTsExtensions": true,
"types": [
"node"
],
"allowSyntheticDefaultImports": true,
"resolvePackageJsonExports": true,
"resolvePackageJsonImports": true,
"resolveJsonModule": true,
"preserveConstEnums": true,
"useDefineForClassFields": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"strictBuiltinIteratorReturn": true,
"alwaysStrict": true,
"useUnknownInCatchVariables": true
},
"files": [
"./src/another.ts",
"./src/index.ts",
"./src/libs/bar.ts",
"./src/libs/foo.ts",
"./src/libs/index.ts"
],
"include": [
"src/**/*"
]
}

Run tsc --traceResolution and paste its output here

It is too long - github saids 'There was an error creating your Issue: body is too long, body is too long (maximum is 65536 characters).' So I omit it here

Paste the package.json of the importing module, if it exists

x

Paste the package.json of the target module, if it exists

x

Any other comments can go here

x

@RyanCavanaugh
Copy link
Member

Bundlers are still assumed to follow Node semantics when resolving subpath imports (e.g. file extensions are required).

The module specifier resolves at runtime, but not at build time

How are you running/bundling this code such that it works?

@RyanCavanaugh RyanCavanaugh added the Needs More Info The issue still hasn't been fully clarified label Sep 19, 2024
@JunyeongChoi0
Copy link
Author

@RyanCavanaugh
I am using Vite, and I have confirmed that the build works well without configuring resolve alias at the bundler level, by using subpath imports.

That being said, are paths with subpath imports treated as absolute paths? According to the documentation, it states that file extensions are not required for relative paths as follows:

'bundler’ for use with bundlers. Like node16 and nodenext, this mode supports package.json “imports” and “exports”, but unlike the Node.js resolution modes, bundler never requires file extensions on relative paths in imports.

@RyanCavanaugh RyanCavanaugh added Needs Investigation This issue needs a team member to investigate its status. and removed Needs More Info The issue still hasn't been fully clarified labels Sep 20, 2024
@andrewbranch
Copy link
Member

I can't find where this was discussed before; it may have been a tangent on a related issue. But, this is working as intended, and it's surprising/concerning that Vite's resolver is deviating from the spec like this. Your reading of our docs is correct; module specifiers that start with # are not relative. Some bundlers may be a little lax here, but we intend to stick to Node's spec for simplicity and portability. (Note that this isn't just a "Node.js ESM requires extensions" thing; this limitation of the resolution algorith applies even to require calls in Node.js, where directory modules and dropping extensions is otherwise usually supported.)

@andrewbranch andrewbranch added Working as Intended The behavior described is the intended behavior; this is not a bug and removed Needs Investigation This issue needs a team member to investigate its status. labels Sep 20, 2024
@andrewbranch andrewbranch removed their assignment Sep 20, 2024
@typescript-bot
Copy link
Collaborator

This issue has been marked as "Working as Intended" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Sep 23, 2024
@croraf
Copy link

croraf commented Oct 4, 2024

@RyanCavanaugh @andrewbranch I'm facing a similar issue. I reported a new issue #60139

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

5 participants