fix(composables): stop shadowing Nuxt's built-in useLayout (#384) - #388
Open
AndreyYolkin wants to merge 8 commits into
Open
fix(composables): stop shadowing Nuxt's built-in useLayout (#384)#388AndreyYolkin wants to merge 8 commits into
AndreyYolkin wants to merge 8 commits into
Conversation
Code review found the preset walker diverged from unimport's own `resolvePreset`: nested presets wrongly inherited the parent `from`, and tuple entries used nullish instead of truthy fallback, so an empty alias was collected as a name. Also hardens the prefix decision, which returned the raw mode and so renamed every composable when given an unrecognised string.
Nuxt 4.5 ships its own `useLayout`, and the module's auto-import silently won the name, making the framework composable unreachable and crashing any call outside `<VApp>`. `prefixComposables` now defaults to `'auto'`, which prefixes only the composables whose name a Nuxt or Vue auto-import source already owns — the same set Nuxt reports as NUXT_B6002. Explicit `true`, `false` and array values are unchanged. Closes #384
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #384.
Problem
Nuxt 4.5.0 shipped a built-in
useLayout. This module also auto-imports Vuetify's unrelateduseLayout, and our registration silently won the name, so on every Nuxt >= 4.5 project with default options the framework's own composable became unreachable.The two are not interchangeable:
Readonly<ComputedRef<LayoutName>>{ getLayoutItem, mainRect, mainStyles }<VApp>[Vuetify] Could not find injected layoutNuxt's documented example calls
useLayout()inapp.vue, and<VApp>normally lives in a layout below it — so the documented Nuxt pattern crashed for our users.Reproduced on nuxt 4.5.2 before the fix (
nuxi prepareinapps/playground):Fix
moduleOptions.prefixComposablesgains a new value'auto', which becomes the default:'auto'(new default)true/false/string[]The invariant, which the implementation is written against:
Detection is dynamic, so there are no Nuxt or Vuetify version gates — on Nuxt < 4.5 the intersection is empty and nothing changes.
Why hooks instead of
addImportsaddImportsneeds the finished array at module-setup time, but the reserved names only exist onceimports:sourcesfires onmodules:done(measured:nuxt.options.imports.presetsholds a single preset at our setup, and nouseLayout). So we snapshot inimports:sourcesand push inimports:extend— which is literally whataddImportsdoes internally, one step later.Scope
Only framework-owned sources count (
fromstarting with#, orvue/vue-demi/vue-router). Third-party module presets are deliberately excluded, so the module's auto-import names never depend on which other modules a project installed. A probe ofapps/playground(which has@nuxtjs/i18n) found 35 presets / 214 names, withuseLayoutthe only intersection against our 11 composables.Verification
nuxi prepareinapps/playgroundon nuxt 4.5.2, after:NUXT_B6002+Duplicated importsuseLayoutimport('vuetify')nuxt/dist/app/composables/layoutuseVLayoutimport('vuetify')basicfixture, checked to fail whenprefixComposables: false.prepackgreen.nuxi devand silent underprepare.Upgrading
Projects that used Vuetify's
useLayoutshould rename those call sites touseVLayout. TypeScript flags them, since Nuxt's composable returns a different type. Documented in the composables guide.