From f3f594f7f98a1c15beee9fa429c80abb4a06fe23 Mon Sep 17 00:00:00 2001 From: tbitw2549 Date: Fri, 16 Aug 2024 17:52:26 +0300 Subject: [PATCH] chore: rebase to vue 3.5 branch rebases to #28285 --- packages/nuxt/src/app/composables/id.ts | 61 +-------------------- packages/nuxt/src/imports/presets.ts | 12 ++-- packages/nuxt/test/auto-imports.test.ts | 2 +- packages/nuxt/test/treeshake-client.test.ts | 4 +- test/bundle.test.ts | 8 +-- test/nuxt/composables.test.ts | 31 +---------- 6 files changed, 18 insertions(+), 100 deletions(-) diff --git a/packages/nuxt/src/app/composables/id.ts b/packages/nuxt/src/app/composables/id.ts index ba920a8f84..7b3fdd6076 100644 --- a/packages/nuxt/src/app/composables/id.ts +++ b/packages/nuxt/src/app/composables/id.ts @@ -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 diff --git a/packages/nuxt/src/imports/presets.ts b/packages/nuxt/src/imports/presets.ts index b34b6df9d0..f2d9a1904d 100644 --- a/packages/nuxt/src/imports/presets.ts +++ b/packages/nuxt/src/imports/presets.ts @@ -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', @@ -231,6 +227,14 @@ const vuePreset = defineUnimportPreset({ 'useCssVars', 'useSlots', 'useTransitionState', + 'useId', + 'useTemplateRef', + 'hydrateOnInteraction', + 'hydrateOnMediaQuery', + 'hydrateOnVisible', + 'hydrateOnIdle', + 'useHost', + 'useShadowRoot', ], }) diff --git a/packages/nuxt/test/auto-imports.test.ts b/packages/nuxt/test/auto-imports.test.ts index c974c8998f..ab6f18a319 100644 --- a/packages/nuxt/test/auto-imports.test.ts +++ b/packages/nuxt/test/auto-imports.test.ts @@ -56,7 +56,7 @@ describe('imports:transform', () => { }) }) -const excludedNuxtHelpers = ['useHydration', 'useHead', 'useSeoMeta', 'useServerSeoMeta'] +const excludedNuxtHelpers = ['useHydration', 'useHead', 'useSeoMeta', 'useServerSeoMeta', 'useId'] describe('imports:nuxt', () => { try { diff --git a/packages/nuxt/test/treeshake-client.test.ts b/packages/nuxt/test/treeshake-client.test.ts index 77b3c3ea93..375ceff182 100644 --- a/packages/nuxt/test/treeshake-client.test.ts +++ b/packages/nuxt/test/treeshake-client.test.ts @@ -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(`
`) expect(clientResult).toContain('should-be-treeshaken') diff --git a/test/bundle.test.ts b/test/bundle.test.ts index 6f874ab733..b284c375ba 100644 --- a/test/bundle.test.ts +++ b/test/bundle.test.ts @@ -19,7 +19,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM for (const outputDir of ['.output', '.output-inline']) { it('default client bundle size', async () => { const clientStats = await analyzeSizes('**/*.js', join(rootDir, outputDir, 'public')) - expect.soft(roundToKilobytes(clientStats.totalBytes)).toMatchInlineSnapshot(`"107k"`) + expect.soft(roundToKilobytes(clientStats.totalBytes)).toMatchInlineSnapshot(`"112k"`) expect(clientStats.files.map(f => f.replace(/\..*\.js/, '.js'))).toMatchInlineSnapshot(` [ "_nuxt/entry.js", @@ -32,10 +32,10 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM const serverDir = join(rootDir, '.output/server') const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir) - expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"211k"`) + expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"205k"`) const modules = await analyzeSizes('node_modules/**/*', serverDir) - expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1348k"`) + expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1370k"`) const packages = modules.files .filter(m => m.endsWith('package.json')) @@ -74,7 +74,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM const serverDir = join(rootDir, '.output-inline/server') const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir) - expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"535k"`) + expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"549k"`) const modules = await analyzeSizes('node_modules/**/*', serverDir) expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"80.3k"`) diff --git a/test/nuxt/composables.test.ts b/test/nuxt/composables.test.ts index d308e3cb07..7342ebfa0b 100644 --- a/test/nuxt/composables.test.ts +++ b/test/nuxt/composables.test.ts @@ -4,7 +4,6 @@ import { describe, expect, it, vi } from 'vitest' import { defineEventHandler } from 'h3' import { destr } from 'destr' -import { mount } from '@vue/test-utils' import { mountSuspended, registerEndpoint } from '@nuxt/test-utils/runtime' import { hasProtocol } from 'ufo' @@ -17,7 +16,6 @@ import { setResponseStatus, useRequestEvent, useRequestFetch, useRequestHeaders import { clearNuxtState, useState } from '#app/composables/state' import { useRequestURL } from '#app/composables/url' import { getAppManifest, getRouteRules } from '#app/composables/manifest' -import { useId } from '#app/composables/id' import { callOnce } from '#app/composables/once' import { useLoadingIndicator } from '#app/composables/loading-indicator' import { useRouteAnnouncer } from '#app/composables/route-announcer' @@ -79,7 +77,6 @@ describe('composables', () => { 'clearNuxtState', 'useState', 'useRequestURL', - 'useId', 'useRoute', 'navigateTo', 'abortNavigation', @@ -101,6 +98,7 @@ describe('composables', () => { 'reloadNuxtApp', 'refreshCookie', 'onPrehydrate', + 'useId', 'useFetch', 'useHead', 'useLazyFetch', @@ -459,33 +457,6 @@ describe('clearNuxtState', () => { }) }) -describe('useId', () => { - it('default', () => { - const vals = new Set() - for (let index = 0; index < 100; index++) { - mount(defineComponent({ - setup () { - const id = useId() - vals.add(id) - return () => h('div', id) - }, - })) - } - expect(vals.size).toBe(100) - }) - - it('generates unique ids per-component', () => { - const component = defineComponent({ - setup () { - const id = useId() - return () => h('div', id) - }, - }) - - expect(mount(component).html()).not.toBe(mount(component).html()) - }) -}) - describe('url', () => { it('useRequestURL', () => { const url = useRequestURL()