From 483435ba34a2cb08253384c3ecda4c45c5a633eb Mon Sep 17 00:00:00 2001 From: Julien Huang Date: Fri, 20 Dec 2024 11:13:46 +0100 Subject: [PATCH] fix(nuxt): use `useId` for `client-fallback` component uid (#30314) --- .../app/components/client-fallback.client.ts | 7 +-- .../app/components/client-fallback.server.ts | 13 ++--- packages/nuxt/src/components/module.ts | 6 -- .../plugins/client-fallback-auto-id.ts | 55 ------------------- 4 files changed, 6 insertions(+), 75 deletions(-) delete mode 100644 packages/nuxt/src/components/plugins/client-fallback-auto-id.ts diff --git a/packages/nuxt/src/app/components/client-fallback.client.ts b/packages/nuxt/src/app/components/client-fallback.client.ts index f92dfb7a31..857d7d3437 100644 --- a/packages/nuxt/src/app/components/client-fallback.client.ts +++ b/packages/nuxt/src/app/components/client-fallback.client.ts @@ -1,13 +1,10 @@ -import { createElementBlock, defineComponent, onMounted, ref } from 'vue' +import { createElementBlock, defineComponent, onMounted, ref, useId } from 'vue' import { useState } from '../composables/state' export default defineComponent({ name: 'NuxtClientFallback', inheritAttrs: false, props: { - uid: { - type: String, - }, fallbackTag: { type: String, default: () => 'div', @@ -31,7 +28,7 @@ export default defineComponent({ setup (props, ctx) { const mounted = ref(false) // This is deliberate - `uid` should not be provided by user but by a transform plugin and will not be reactive. - const ssrFailed = useState(`${props.uid}`) + const ssrFailed = useState(useId()) if (ssrFailed.value) { onMounted(() => { mounted.value = true }) diff --git a/packages/nuxt/src/app/components/client-fallback.server.ts b/packages/nuxt/src/app/components/client-fallback.server.ts index dd4e0cdb28..aa42355537 100644 --- a/packages/nuxt/src/app/components/client-fallback.server.ts +++ b/packages/nuxt/src/app/components/client-fallback.server.ts @@ -1,18 +1,14 @@ -import { defineComponent, getCurrentInstance, onErrorCaptured, ref } from 'vue' +import { defineComponent, getCurrentInstance, onErrorCaptured, ref, useId } from 'vue' import { ssrRenderAttrs, ssrRenderSlot, ssrRenderVNode } from 'vue/server-renderer' import { isPromise } from '@vue/shared' import { useState } from '../composables/state' -import { useNuxtApp } from '../nuxt' import { createBuffer } from './utils' const NuxtClientFallbackServer = defineComponent({ name: 'NuxtClientFallback', inheritAttrs: false, props: { - uid: { - type: String, - }, fallbackTag: { type: String, default: () => 'div', @@ -37,11 +33,10 @@ const NuxtClientFallbackServer = defineComponent({ return true }, }, - async setup (props, ctx) { + async setup (_, ctx) { const vm = getCurrentInstance() const ssrFailed = ref(false) - const nuxtApp = useNuxtApp() - const error = useState(`${props.uid}`) + const error = useState(useId()) onErrorCaptured((err) => { error.value = true @@ -68,7 +63,7 @@ const NuxtClientFallbackServer = defineComponent({ return { ssrFailed, ssrVNodes } } catch (ssrError) { // catch in dev - nuxtApp.runWithContext(() => useState(`${props.uid}`, () => true)) + error.value = true ctx.emit('ssr-error', ssrError) return { ssrFailed: true, ssrVNodes: [] } } diff --git a/packages/nuxt/src/components/module.ts b/packages/nuxt/src/components/module.ts index 624d18b158..2b23687d10 100644 --- a/packages/nuxt/src/components/module.ts +++ b/packages/nuxt/src/components/module.ts @@ -7,7 +7,6 @@ import { distDir } from '../dirs' import { componentNamesTemplate, componentsIslandsTemplate, componentsMetadataTemplate, componentsPluginTemplate, componentsTypeTemplate } from './templates' import { scanComponents } from './scan' -import { ClientFallbackAutoIdPlugin } from './plugins/client-fallback-auto-id' import { LoaderPlugin } from './plugins/loader' import { ComponentsChunkPlugin, IslandsTransformPlugin } from './plugins/islands-transform' import { TransformPlugin } from './plugins/transform' @@ -220,11 +219,6 @@ export default defineNuxtModule({ addBuildPlugin(TreeShakeTemplatePlugin({ sourcemap: !!nuxt.options.sourcemap.server, getComponents }), { client: false }) } - if (nuxt.options.experimental.clientFallback) { - addBuildPlugin(ClientFallbackAutoIdPlugin({ sourcemap: !!nuxt.options.sourcemap.client, rootDir: nuxt.options.rootDir }), { server: false }) - addBuildPlugin(ClientFallbackAutoIdPlugin({ sourcemap: !!nuxt.options.sourcemap.server, rootDir: nuxt.options.rootDir }), { client: false }) - } - const sharedLoaderOptions = { getComponents, serverComponentRuntime, diff --git a/packages/nuxt/src/components/plugins/client-fallback-auto-id.ts b/packages/nuxt/src/components/plugins/client-fallback-auto-id.ts deleted file mode 100644 index 85c3d8b82d..0000000000 --- a/packages/nuxt/src/components/plugins/client-fallback-auto-id.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { createUnplugin } from 'unplugin' -import type { ComponentsOptions } from '@nuxt/schema' -import MagicString from 'magic-string' -import { isAbsolute, relative } from 'pathe' -import { hash } from 'ohash' -import { isVue } from '../../core/utils' - -interface LoaderOptions { - sourcemap?: boolean - transform?: ComponentsOptions['transform'] - rootDir: string -} -const CLIENT_FALLBACK_RE = /<(?:NuxtClientFallback|nuxt-client-fallback)(?: [^>]*)?>/ -const CLIENT_FALLBACK_GLOBAL_RE = /<(NuxtClientFallback|nuxt-client-fallback)( [^>]*)?>/g -const UID_RE = / :?uid=/ -export const ClientFallbackAutoIdPlugin = (options: LoaderOptions) => createUnplugin(() => { - const exclude = options.transform?.exclude || [] - const include = options.transform?.include || [] - - return { - name: 'nuxt:client-fallback-auto-id', - enforce: 'pre', - transformInclude (id) { - if (exclude.some(pattern => pattern.test(id))) { - return false - } - if (include.some(pattern => pattern.test(id))) { - return true - } - return isVue(id) - }, - transform (code, id) { - if (!CLIENT_FALLBACK_RE.test(code)) { return } - - const s = new MagicString(code) - const relativeID = isAbsolute(id) ? relative(options.rootDir, id) : id - let count = 0 - - s.replace(CLIENT_FALLBACK_GLOBAL_RE, (full, name, attrs) => { - count++ - if (UID_RE.test(attrs)) { return full } - return `<${name} :uid="'${hash(relativeID)}' + JSON.stringify($props) + '${count}'" ${attrs ?? ''}>` - }) - - if (s.hasChanged()) { - return { - code: s.toString(), - map: options.sourcemap - ? s.generateMap({ hires: true }) - : undefined, - } - } - }, - } -})