Skip to content
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

import.meta.resolve is not shimmed when using --rewriteRelativeImportExtensions #61541

Open
nwidynski opened this issue Apr 6, 2025 · 4 comments
Labels
Not a Defect This behavior is one of several equally-correct options

Comments

@nwidynski
Copy link

πŸ”Ž Search Terms

"rewriteRelativeImportExtensions", "import.meta.resolve", "require.resolve", "shim", "experimental-strip-types", "experimental-transform-types"

πŸ•— Version & Regression Information

⏯ Playground Link

No response

πŸ’» Code

// tsc --rewriteRelativeImportExtensions
import("./foo.ts")
import.meta.resolve("./foo.ts")

// output:
import("./foo.js")
import.meta.resolve("./foo.ts")

πŸ™ Actual behavior

While imports are correctly rewritten/shimmed, calls to import.meta.resolve/require.resolve are not impacted.

πŸ™‚ Expected behavior

I would expect import.meta.resolve to resolve to the same path as an import call, as per MDN Documentation.

Additional information about the issue

No response

@RyanCavanaugh
Copy link
Member

We have to draw some line where import("x.ts") is rewritten and fs.readFile("x.ts") isn't. import.meta.resolve seems closer to the latter than the former, especially because it's legal to do something like

const foo: any = import.meta;
foo.resolve("x.ts")

which we don't have any chance of catching.

@RyanCavanaugh RyanCavanaugh added the Not a Defect This behavior is one of several equally-correct options label Apr 8, 2025
@nwidynski
Copy link
Author

nwidynski commented Apr 8, 2025

@RyanCavanaugh Hm, I haven't thought of import.meta being assigned to a new member, so thanks for the insight πŸ‘

That being said, I'm not sure I agree with import.meta.resolve being closer to fs.readFile("x.ts") than import("x.ts"), since its explicitly documented to be corresponding:

"[...] to the path that would be imported if the argument were passed to import()".

This behavior is broken when the --rewriteRelativeImportExtensions setting is enabled. A practical use-case where this becomes an issue is trying to spawn a Worker with a .ts filename. Afaik, Node.js does not offer module resolution like typescript, where it's okay to import a .ts file by its .js extension. I was hoping to get this resolved through this issue.

While not pretty, the import.meta.resolve could be shimmed itself instead of at the callsite:

const { resolve: r$182s9f } = import.meta;
import.meta.resolve = (path) => r$182s9f(path.replace('.ts', '.js'));

@Jamesernator
Copy link

A practical use-case where this becomes an issue is trying to spawn a Worker with a .ts filename.

Worth noting there is a stage 2.7 proposal that allows for statically refering to modules for basically this exact usage.

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Apr 10, 2025

I mean, the best we can do is make this differently inconsistent, and I'm not seeing a case for why the proposed inconsistency is better than the existing one. The rules today are at least 100% syntactic; you can be sure that if you write import(" it's rewritten, but otherwise isn't. If the rule is any more complicated than that, you can't really predict if

const { resolve } = import.meta;
resolve("path")

is rewritten or not.

Having the rule be simple is super critical for single-file transpilers wanting to replicate TypeScript's behavior, since they don't have the same symbol resolution mechanics that TS does which would allow it to even realize that import.meta.resolve is being referenced according to exactly some specific set of rules.

We also need to consider the case where a runtime adds something like import.meta.resolveCached or something; resolve is "just a function" from TypeScript's perspective and it doesn't know that it deserves special treatment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Not a Defect This behavior is one of several equally-correct options
Projects
None yet
Development

No branches or pull requests

3 participants