Skip to content

fix(compiler-sfc): resolve top-level exports from files registered as global types#14805

Open
danielroe wants to merge 1 commit into
vuejs:mainfrom
danielroe:fix/global-scope-cache-poisoning
Open

fix(compiler-sfc): resolve top-level exports from files registered as global types#14805
danielroe wants to merge 1 commit into
vuejs:mainfrom
danielroe:fix/global-scope-cache-poisoning

Conversation

@danielroe
Copy link
Copy Markdown
Member

@danielroe danielroe commented May 11, 2026

resolves nuxt/nuxt#33694

the issue is that files registered as globalTypeFiles that contain plain top-level export declarations (no declare global { ... }) were cached with an empty TypeScope and that cached scope was then reused for regular import { Foo } from '...' resolution, so imports of those types failed to resolve.

Summary by CodeRabbit

  • Tests

    • Added test cases for global type file resolution, verifying proper handling of global type files with top-level exports through module-style imports and validating cache behavior.
  • Refactor

    • Enhanced type scope caching mechanism with separate cache management for global and normal file scope resolution, improving type resolution efficiency.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

📝 Walkthrough

Walkthrough

This PR fixes global-scope type caching by introducing a separate cache for global-scope resolutions. Global type files added via globalTypeFiles can now have their exported types resolved via module-style imports, addressing the issue where addTypeTemplate prevented exported type resolution.

Changes

Global-Scope Type Cache Separation

Layer / File(s) Summary
Separate Cache Initialization
packages/compiler-sfc/src/script/resolveType.ts
Introduces fileToGlobalScopeCache to independently cache type scopes created with asGlobal = true.
Dual-Cache Invalidation
packages/compiler-sfc/src/script/resolveType.ts
Extends invalidateTypeCache() to normalize the filename and clear both fileToScopeCache and fileToGlobalScopeCache before tsconfig invalidation.
Cache Read and Write Logic
packages/compiler-sfc/src/script/resolveType.ts
Updates fileToScope() to select the appropriate cache based on asGlobal when reading existing scopes and storing computed results.
Test Coverage
packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts
Adds test case verifying global type files with top-level exports resolve correctly via module imports with props and deps tracked, and test case validating cache reuse when global-scope loading is followed by successful module import.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • vuejs/core#14260: Also modifies global-scope type handling in resolveType.ts to improve type resolution within declare global blocks.
  • vuejs/core#13789: Addresses global-type handling in resolveType.ts, specifically recording of named exports inside declare global.
  • vuejs/core#13301: Modifies fileToScope() in resolveType.ts for different parsing concerns.

Suggested labels

ready to merge, scope: sfc, :hammer: p3-minor-bug

Suggested reviewers

  • edison1105
  • LittleSound

Poem

🐰 Global types now dance in caches bright,
Separate paths for day and night,
Exported props leap through module doors,
addTypeTemplate works like never before! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: resolving top-level exports from files registered as global types, which directly addresses the root cause of the issue.
Linked Issues check ✅ Passed The PR implementation correctly addresses the linked issue by introducing separate caching for global scope resolution, ensuring top-level exports from global type files are resolved properly during imports.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the global type file caching issue: test cases verify the fix, and implementation changes update the caching strategy.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 11, 2026

Open in StackBlitz

@vue/compiler-core

pnpm add https://pkg.pr.new/@vue/compiler-core@14805
npm i https://pkg.pr.new/@vue/compiler-core@14805
yarn add https://pkg.pr.new/@vue/compiler-core@14805.tgz

@vue/compiler-dom

pnpm add https://pkg.pr.new/@vue/compiler-dom@14805
npm i https://pkg.pr.new/@vue/compiler-dom@14805
yarn add https://pkg.pr.new/@vue/compiler-dom@14805.tgz

@vue/compiler-sfc

pnpm add https://pkg.pr.new/@vue/compiler-sfc@14805
npm i https://pkg.pr.new/@vue/compiler-sfc@14805
yarn add https://pkg.pr.new/@vue/compiler-sfc@14805.tgz

@vue/compiler-ssr

pnpm add https://pkg.pr.new/@vue/compiler-ssr@14805
npm i https://pkg.pr.new/@vue/compiler-ssr@14805
yarn add https://pkg.pr.new/@vue/compiler-ssr@14805.tgz

@vue/reactivity

pnpm add https://pkg.pr.new/@vue/reactivity@14805
npm i https://pkg.pr.new/@vue/reactivity@14805
yarn add https://pkg.pr.new/@vue/reactivity@14805.tgz

@vue/runtime-core

pnpm add https://pkg.pr.new/@vue/runtime-core@14805
npm i https://pkg.pr.new/@vue/runtime-core@14805
yarn add https://pkg.pr.new/@vue/runtime-core@14805.tgz

@vue/runtime-dom

pnpm add https://pkg.pr.new/@vue/runtime-dom@14805
npm i https://pkg.pr.new/@vue/runtime-dom@14805
yarn add https://pkg.pr.new/@vue/runtime-dom@14805.tgz

@vue/server-renderer

pnpm add https://pkg.pr.new/@vue/server-renderer@14805
npm i https://pkg.pr.new/@vue/server-renderer@14805
yarn add https://pkg.pr.new/@vue/server-renderer@14805.tgz

@vue/shared

pnpm add https://pkg.pr.new/@vue/shared@14805
npm i https://pkg.pr.new/@vue/shared@14805
yarn add https://pkg.pr.new/@vue/shared@14805.tgz

vue

pnpm add https://pkg.pr.new/vue@14805
npm i https://pkg.pr.new/vue@14805
yarn add https://pkg.pr.new/vue@14805.tgz

@vue/compat

pnpm add https://pkg.pr.new/@vue/compat@14805
npm i https://pkg.pr.new/@vue/compat@14805
yarn add https://pkg.pr.new/@vue/compat@14805.tgz

commit: 4147eab

@github-actions
Copy link
Copy Markdown

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 106 kB 40 kB 36 kB
vue.global.prod.js 164 kB 60 kB 53.4 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 48.7 kB 18.9 kB 17.3 kB
createApp 56.8 kB 22 kB 20.1 kB
createSSRApp 61.1 kB 23.7 kB 21.6 kB
defineCustomElement 63 kB 23.9 kB 21.8 kB
overall 71.6 kB 27.4 kB 25 kB

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts (1)

1769-1776: ⚡ Quick win

Assert the priming failure explicitly instead of swallowing it.

At Line 1769, the empty catch {} can hide regressions where the first compile no longer fails, weakening the test’s intended setup guarantee.

Suggested test adjustment
-        try {
-          resolve(
-            `defineProps<UnknownGlobal>()`,
-            files,
-            { globalTypeFiles: ['/globalTypes.d.ts'] },
-            '/PrimeGlobal.vue',
-          )
-        } catch {}
+        expect(() =>
+          resolve(
+            `defineProps<UnknownGlobal>()`,
+            files,
+            { globalTypeFiles: ['/globalTypes.d.ts'] },
+            '/PrimeGlobal.vue',
+          ),
+        ).toThrow('Unresolvable type reference')
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts` around
lines 1769 - 1776, The test currently swallows the expected priming failure by
using an empty catch block; instead assert the failure explicitly: call
resolve(...) with the same arguments (the `resolve` invocation for
"`defineProps<UnknownGlobal>()`" using `globalTypeFiles` and
`'/PrimeGlobal.vue'`) inside an assertion that it throws (e.g. use the test
framework's expect(...).toThrow or wrap in try/catch and call fail() when no
error is thrown) so the test fails if the initial compile unexpectedly succeeds.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts`:
- Around line 1769-1776: The test currently swallows the expected priming
failure by using an empty catch block; instead assert the failure explicitly:
call resolve(...) with the same arguments (the `resolve` invocation for
"`defineProps<UnknownGlobal>()`" using `globalTypeFiles` and
`'/PrimeGlobal.vue'`) inside an assertion that it throws (e.g. use the test
framework's expect(...).toThrow or wrap in try/catch and call fail() when no
error is thrown) so the test fails if the initial compile unexpectedly succeeds.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 30da15ee-fec1-4cab-b035-303d98725518

📥 Commits

Reviewing files that changed from the base of the PR and between 57545e9 and 4147eab.

📒 Files selected for processing (2)
  • packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts
  • packages/compiler-sfc/src/script/resolveType.ts

@edison1105 edison1105 added ready to merge The PR is ready to be merged. scope: sfc labels May 12, 2026
@edison1105
Copy link
Copy Markdown
Member

/ecosystem-ci run

@vue-bot
Copy link
Copy Markdown
Contributor

vue-bot commented May 12, 2026

📝 Ran ecosystem CI: Open

suite result latest scheduled
language-tools success success
pinia success success
quasar failure failure
primevue success success
nuxt failure success
test-utils success success
radix-vue success success
router success success
vue-i18n success success
vuetify success success
vue-simple-compiler success success
vitepress success success
vue-macros success success
vite-plugin-vue success success
vant success success
vueuse success success

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready to merge The PR is ready to be merged. scope: sfc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

addTypeTemplate prevents the exported types of added files from being resolved by compiler-sfc

3 participants