Skip to content

Commit

Permalink
refactor(nuxt): update to vue v3.5 + native useId (nuxt#28285)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe authored Sep 3, 2024
1 parent de58000 commit 7346d61
Show file tree
Hide file tree
Showing 13 changed files with 217 additions and 297 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"typescript": "5.5.4",
"unbuild": "3.0.0-rc.7",
"vite": "5.4.2",
"vue": "3.4.38"
"vue": "3.5.0"
},
"devDependencies": {
"@eslint/js": "9.9.1",
Expand Down Expand Up @@ -99,7 +99,7 @@
"ufo": "1.5.4",
"vitest": "2.0.5",
"vitest-environment-nuxt": "1.0.1",
"vue": "3.4.38",
"vue": "3.5.0",
"vue-router": "4.4.3",
"vue-tsc": "2.1.4"
},
Expand Down
6 changes: 3 additions & 3 deletions packages/nuxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"@unhead/dom": "^1.10.4",
"@unhead/ssr": "^1.10.4",
"@unhead/vue": "^1.10.4",
"@vue/shared": "^3.4.38",
"@vue/shared": "^3.5.0",
"acorn": "8.12.1",
"c12": "^2.0.0-beta.2",
"chokidar": "^3.6.0",
Expand Down Expand Up @@ -117,7 +117,7 @@
"unplugin-vue-router": "^0.10.7",
"unstorage": "^1.10.2",
"untyped": "^1.4.2",
"vue": "^3.4.38",
"vue": "^3.5.0",
"vue-bundle-renderer": "^2.1.0",
"vue-devtools-stub": "^0.1.0",
"vue-router": "^4.4.3"
Expand All @@ -128,7 +128,7 @@
"@parcel/watcher": "2.4.1",
"@types/estree": "1.0.5",
"@vitejs/plugin-vue": "5.1.3",
"@vue/compiler-sfc": "3.4.38",
"@vue/compiler-sfc": "3.5.0",
"unbuild": "3.0.0-rc.7",
"vite": "5.4.2",
"vitest": "2.0.5"
Expand Down
4 changes: 2 additions & 2 deletions packages/nuxt/src/app/composables/asyncData.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { computed, getCurrentInstance, getCurrentScope, onBeforeMount, onScopeDispose, onServerPrefetch, onUnmounted, ref, shallowRef, toRef, unref, watch } from 'vue'
import type { Ref, WatchSource } from 'vue'
import type { MultiWatchSources, Ref } from 'vue'
import type { NuxtApp } from '../nuxt'
import { useNuxtApp } from '../nuxt'
import { toArray } from '../utils'
Expand Down Expand Up @@ -34,7 +34,7 @@ export type KeysOf<T> = Array<

export type KeyOfRes<Transform extends _Transform> = KeysOf<ReturnType<Transform>>

export type MultiWatchSources = (WatchSource<unknown> | object)[]
export type { MultiWatchSources }

export type NoInfer<T> = [T][T extends any ? 0 : never]

Expand Down
61 changes: 2 additions & 59 deletions packages/nuxt/src/app/composables/id.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,3 @@
import { getCurrentInstance, inject } from 'vue'
import { useNuxtApp } from '../nuxt'
import { clientOnlySymbol } from '#app/components/client-only'
import { useId as _useId } from 'vue'

const ATTR_KEY = 'data-n-ids'
const SEPARATOR = '-'

/**
* Generate an SSR-friendly unique identifier that can be passed to accessibility attributes.
*
* The generated ID is unique in the context of the current Nuxt instance and key.
*/
export function useId (): string
export function useId (key?: string): string {
if (typeof key !== 'string') {
throw new TypeError('[nuxt] [useId] key must be a string.')
}
// TODO: implement in composable-keys
// Make sure key starts with a letter to be a valid selector
key = `n${key.slice(1)}`
const nuxtApp = useNuxtApp()
const instance = getCurrentInstance()

if (!instance) {
// TODO: support auto-incrementing ID for plugins if there is need?
throw new TypeError('[nuxt] `useId` must be called within a component setup function.')
}

nuxtApp._genId ||= 0
instance._nuxtIdIndex ||= {}
instance._nuxtIdIndex[key] ||= 0

const instanceIndex = key + SEPARATOR + instance._nuxtIdIndex[key]++

if (import.meta.server) {
const ids = JSON.parse(instance.attrs[ATTR_KEY] as string | undefined || '{}')
ids[instanceIndex] = key + SEPARATOR + nuxtApp._genId++
instance.attrs[ATTR_KEY] = JSON.stringify(ids)
return ids[instanceIndex]
}

if (nuxtApp.payload.serverRendered && nuxtApp.isHydrating && !inject(clientOnlySymbol, false)) {
// Access data attribute from sibling if root is a comment node and sibling is an element
const el = instance.vnode.el?.nodeType === 8 && instance.vnode.el?.nextElementSibling?.getAttribute
? instance.vnode.el?.nextElementSibling
: instance.vnode.el

const ids = JSON.parse(el?.getAttribute?.(ATTR_KEY) || '{}')
if (ids[instanceIndex]) {
return ids[instanceIndex]
}

if (import.meta.dev && instance.vnode.type && typeof instance.vnode.type === 'object' && 'inheritAttrs' in instance.vnode.type && instance.vnode.type.inheritAttrs === false) {
console.warn('[nuxt] `useId` might not work correctly with components that have `inheritAttrs: false`.')
}
}

// pure client-side ids, avoiding potential collision with server-side ids
return key + '_' + nuxtApp._genId++
}
export const useId = _useId
8 changes: 4 additions & 4 deletions packages/nuxt/src/imports/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,6 @@ const granularAppPresets: InlinePreset[] = [
imports: ['usePreviewMode'],
from: '#app/composables/preview',
},
{
imports: ['useId'],
from: '#app/composables/id',
},
{
imports: ['useRouteAnnouncer'],
from: '#app/composables/route-announcer',
Expand Down Expand Up @@ -231,6 +227,10 @@ const vuePreset = defineUnimportPreset({
'useCssVars',
'useSlots',
'useTransitionState',
'useId',
'useTemplateRef',
'useShadowRoot',
'useCssVars',
],
})

Expand Down
10 changes: 8 additions & 2 deletions packages/nuxt/test/auto-imports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('imports:transform', () => {
})
})

const excludedNuxtHelpers = ['useHydration', 'useHead', 'useSeoMeta', 'useServerSeoMeta']
const excludedNuxtHelpers = ['useHydration', 'useHead', 'useSeoMeta', 'useServerSeoMeta', 'useId']

describe('imports:nuxt', () => {
try {
Expand Down Expand Up @@ -171,7 +171,6 @@ const excludedVueHelpers = [
'hydrate',
'initDirectivesForSSR',
'render',
'useCssVars',
'vModelCheckbox',
'vModelDynamic',
'vModelRadio',
Expand All @@ -183,6 +182,13 @@ const excludedVueHelpers = [
'ErrorCodes',
'TrackOpTypes',
'TriggerOpTypes',
'useHost',
'hydrateOnVisible',
'hydrateOnMediaQuery',
'hydrateOnInteraction',
'hydrateOnIdle',
'onWatcherCleanup',
'getCurrentWatcher',
]

describe('imports:vue', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/nuxt/test/treeshake-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,10 @@ describe('treeshake client only in ssr', () => {
const ssrResult = await SFCCompile(`SomeComponent${state.index}.vue`, WithClientOnly, state.options, true)

const treeshaken = await treeshake(ssrResult)
const [_, scopeId] = clientResult.match(/_pushScopeId\("(.*)"\)/)!
const [_, scopeId] = clientResult.match(/['"]__scopeId['"],\s*['"](data-v-[^'"]+)['"]/)!

// ensure the id is correctly passed between server and client
expect(clientResult).toContain(`pushScopeId("${scopeId}")`)
expect(clientResult).toContain(`'__scopeId',"${scopeId}"`)
expect(treeshaken).toContain(`<div ${scopeId}>`)

expect(clientResult).toContain('should-be-treeshaken')
Expand Down
6 changes: 3 additions & 3 deletions packages/schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
"@unhead/schema": "1.10.4",
"@vitejs/plugin-vue": "5.1.3",
"@vitejs/plugin-vue-jsx": "4.0.1",
"@vue/compiler-core": "3.4.38",
"@vue/compiler-sfc": "3.4.38",
"@vue/compiler-core": "3.5.0",
"@vue/compiler-sfc": "3.5.0",
"@vue/language-core": "2.1.4",
"c12": "2.0.0-beta.2",
"esbuild-loader": "4.2.2",
Expand All @@ -55,7 +55,7 @@
"unctx": "2.3.1",
"unenv": "1.10.0",
"vite": "5.4.2",
"vue": "3.4.38",
"vue": "3.5.0",
"vue-bundle-renderer": "2.1.0",
"vue-loader": "17.4.2",
"vue-router": "4.4.3",
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@types/estree": "1.0.5",
"rollup": "4.21.2",
"unbuild": "3.0.0-rc.7",
"vue": "3.4.38"
"vue": "3.5.0"
},
"dependencies": {
"@nuxt/kit": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
"@types/webpack-hot-middleware": "2.25.9",
"rollup": "4.21.2",
"unbuild": "3.0.0-rc.7",
"vue": "3.4.38"
"vue": "3.5.0"
},
"peerDependencies": {
"vue": "^3.3.4"
Expand Down
Loading

0 comments on commit 7346d61

Please sign in to comment.