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

fix(check/lsp): fix bugs with tsc type resolution, allow npm packages to augment ImportMeta #27690

Merged
merged 9 commits into from
Jan 16, 2025

Conversation

nathanwhit
Copy link
Member

@nathanwhit nathanwhit commented Jan 16, 2025

Fixes #26224.
Fixes #27042.

There were three bugs here:

  • we were only resolving /// <reference types directives starting with npm:, which meant we failed to resolve bare specifiers (this broke the /// <reference types="vite/client"> directive in most of the vite templates)
  • the $node_modules workaround caused us to fail to read files for tsc. For instance tsc would construct new paths based on specifiers containing $node_modules, and since we hadn't created those we weren't mapping them back to the original (this broke some type resolution within vite/client)
  • our separation of ImportMeta across node and deno globals in tsc meant that npm packages couldn't augment ImportMeta (this broke vite/client's augmentation to add import.meta.env and others)

After this, the only remaining issue in the vanilla vite template is our error on /vite.svg (which is an ambient module), and I'll look into that next.

@marvinhagemeister
Copy link
Contributor

Great work, this is very exciting!!

@nathanwhit
Copy link
Member Author

Two tests are failing because TSC is emitting a new error:

[ERROR]: File 'internal:///missing_dependency.d.ts' not found.

The tests are essentially

/// <reference types="./nonexistent.d.ts" />
export const a = 1;

What happens is that we resolve the type reference directive to MISSING_DEPENDENCY_SPECIFIER (which to tsc looks like a successful resolution), but then when tsc requests the contents we return nothing - and tsc errors in this case (when a type reference resolves but doesn't exist).

I think we can safely ignore this diagnostic because we emit our own not found errors, but not 100% sure.

Copy link
Collaborator

@nayeemrmn nayeemrmn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment on lines -4344 to +4346
let specifier_str = original.replace(".d.ts.d.ts", ".d.ts");
let specifier_str = original
.replace(".d.ts.d.ts", ".d.ts")
.replace("$node_modules", "node_modules");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, I kept trying this as a hail mary for some other bugs but could never manifest a case where tsc was constructing paths bypassing op_resolve() (which typically stores mappings for every specifier when denormalizing its results). I guess it's happening at host.resolveTypeReferenceDirectiveReferences().

Nice find!

typeof diagnostic.messageText === "string" &&
(importMetaFilenameDirnameTypesRe.test(diagnostic.messageText)) &&
(diagnostic.file?.fileName.startsWith("asset:///") ||
diagnostic.file?.fileName?.includes("@types/node"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work for the global cache?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a test for this (across all of the node modules modes)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I misremembered how the global cache was structured.

@nathanwhit nathanwhit enabled auto-merge (squash) January 16, 2025 18:12
@nathanwhit nathanwhit disabled auto-merge January 16, 2025 18:24
@nathanwhit nathanwhit enabled auto-merge (squash) January 16, 2025 18:32
Copy link
Member

@dsherret dsherret left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@nathanwhit nathanwhit merged commit 464ee91 into denoland:main Jan 16, 2025
17 checks passed
bartlomieju pushed a commit that referenced this pull request Jan 16, 2025
… to augment `ImportMeta` (#27690)

Fixes #26224.
Fixes #27042.

There were three bugs here:
- we were only resolving `/// <reference types` directives starting with
`npm:`, which meant we failed to resolve bare specifiers (this broke the
`/// <reference types="vite/client">` directive in most of the vite
templates)
- the `$node_modules` workaround caused us to fail to read files for
tsc. For instance tsc would construct new paths based on specifiers
containing `$node_modules`, and since we hadn't created those we weren't
mapping them back to the original (this broke some type resolution
within `vite/client`)
- our separation of `ImportMeta` across node and deno globals in tsc
meant that npm packages couldn't augment `ImportMeta` (this broke
`vite/client`'s augmentation to add `import.meta.env` and others)


After this, the only remaining issue in the vanilla vite template is our
error on `/vite.svg` (which is an ambient module), and I'll look into
that next.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Mongoose types failing to load Cannot use vite/client types in Deno
4 participants