Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork5.5k
fix(nuxt): invalidate module cache on composable export type changes#33671
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
Changes fromall commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -89,6 +89,69 @@ export default defineNuxtModule<Partial<ImportsOptions>>({ | ||
| } | ||
| let ctx: Unimport | ||
| const viteServers = new Set<any>() | ||
| // Track all Vite servers (client + SSR) | ||
| nuxt.hook('vite:serverCreated', (server) => { | ||
| viteServers.add(server) | ||
| }) | ||
| // Vite plugin to detect and handle export type changes BEFORE HMR | ||
| nuxt.hook('vite:configResolved', (viteConfig) => { | ||
| if (!viteConfig.plugins) { return } | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Shouldnt we initialise the list here and push the plugin in anyway? CollaboratorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more.
| ||
| viteConfig.plugins.push({ | ||
| name: 'nuxt:composables-hmr', | ||
| handleHotUpdate: async (hmrContext) => { | ||
| // Only handle composable files | ||
| if (!composablesDirs.some(dir => hmrContext.file.startsWith(dir + '/'))) { | ||
| return | ||
| } | ||
| // Get current imports to compare | ||
| const currentImports = await ctx.getImports() | ||
| const oldImports = currentImports.filter(i => i.from === hmrContext.file) | ||
| // Scan the updated file | ||
| const newImports = await scanDirExports([hmrContext.file], { | ||
| fileFilter: file => !isIgnored(file), | ||
| }) | ||
| // Check if export type changed (default ↔ named) | ||
| let exportTypeChanged = false | ||
| for (const newImport of newImports) { | ||
| const oldImport = oldImports.find(i => (i.as || i.name) === (newImport.as || newImport.name)) | ||
| if (oldImport && oldImport.name !== newImport.name) { | ||
| exportTypeChanged = true | ||
| break | ||
| } | ||
| } | ||
Comment on lines +119 to +128 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Detection misses default↔named switches when the alias changes Line 120: if the export flips between | ||
| if (exportTypeChanged) { | ||
| // Invalidate module cache recursively in all Vite servers (client + SSR) | ||
| for (const server of viteServers) { | ||
| const visited = new Set() | ||
| const invalidateRecursively = (mod: any) => { | ||
| if (!mod || visited.has(mod)) { return } | ||
| visited.add(mod) | ||
| mod.importers.forEach((importer: any) => invalidateRecursively(importer)) | ||
| server.moduleGraph.invalidateModule(mod) | ||
| } | ||
| const modules = server.moduleGraph.getModulesByFile(hmrContext.file) | ||
| if (modules) { | ||
| modules.forEach((mod: any) => invalidateRecursively(mod)) | ||
| } | ||
| } | ||
| // Trigger full reload - the changed export type cannot be handled with HMR | ||
| hmrContext.server.ws.send({ type: 'full-reload', path: '*' }) | ||
| return [] | ||
| } | ||
| return | ||
| }, | ||
| }) | ||
| }) | ||
| // initialise unimport only after all modules | ||
| // have had a chance to register their hooks | ||
Uh oh!
There was an error while loading.Please reload this page.