mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-18 17:35:57 +00:00
fix(nuxt): use useId
for client-fallback
component uid (#30314)
This commit is contained in:
parent
f5df827a90
commit
483435ba34
@ -1,13 +1,10 @@
|
|||||||
import { createElementBlock, defineComponent, onMounted, ref } from 'vue'
|
import { createElementBlock, defineComponent, onMounted, ref, useId } from 'vue'
|
||||||
import { useState } from '../composables/state'
|
import { useState } from '../composables/state'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'NuxtClientFallback',
|
name: 'NuxtClientFallback',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
uid: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
fallbackTag: {
|
fallbackTag: {
|
||||||
type: String,
|
type: String,
|
||||||
default: () => 'div',
|
default: () => 'div',
|
||||||
@ -31,7 +28,7 @@ export default defineComponent({
|
|||||||
setup (props, ctx) {
|
setup (props, ctx) {
|
||||||
const mounted = ref(false)
|
const mounted = ref(false)
|
||||||
// This is deliberate - `uid` should not be provided by user but by a transform plugin and will not be reactive.
|
// 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) {
|
if (ssrFailed.value) {
|
||||||
onMounted(() => { mounted.value = true })
|
onMounted(() => { mounted.value = true })
|
||||||
|
@ -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 { ssrRenderAttrs, ssrRenderSlot, ssrRenderVNode } from 'vue/server-renderer'
|
||||||
|
|
||||||
import { isPromise } from '@vue/shared'
|
import { isPromise } from '@vue/shared'
|
||||||
import { useState } from '../composables/state'
|
import { useState } from '../composables/state'
|
||||||
import { useNuxtApp } from '../nuxt'
|
|
||||||
import { createBuffer } from './utils'
|
import { createBuffer } from './utils'
|
||||||
|
|
||||||
const NuxtClientFallbackServer = defineComponent({
|
const NuxtClientFallbackServer = defineComponent({
|
||||||
name: 'NuxtClientFallback',
|
name: 'NuxtClientFallback',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
uid: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
fallbackTag: {
|
fallbackTag: {
|
||||||
type: String,
|
type: String,
|
||||||
default: () => 'div',
|
default: () => 'div',
|
||||||
@ -37,11 +33,10 @@ const NuxtClientFallbackServer = defineComponent({
|
|||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async setup (props, ctx) {
|
async setup (_, ctx) {
|
||||||
const vm = getCurrentInstance()
|
const vm = getCurrentInstance()
|
||||||
const ssrFailed = ref(false)
|
const ssrFailed = ref(false)
|
||||||
const nuxtApp = useNuxtApp()
|
const error = useState<boolean | undefined>(useId())
|
||||||
const error = useState<boolean | undefined>(`${props.uid}`)
|
|
||||||
|
|
||||||
onErrorCaptured((err) => {
|
onErrorCaptured((err) => {
|
||||||
error.value = true
|
error.value = true
|
||||||
@ -68,7 +63,7 @@ const NuxtClientFallbackServer = defineComponent({
|
|||||||
return { ssrFailed, ssrVNodes }
|
return { ssrFailed, ssrVNodes }
|
||||||
} catch (ssrError) {
|
} catch (ssrError) {
|
||||||
// catch in dev
|
// catch in dev
|
||||||
nuxtApp.runWithContext(() => useState(`${props.uid}`, () => true))
|
error.value = true
|
||||||
ctx.emit('ssr-error', ssrError)
|
ctx.emit('ssr-error', ssrError)
|
||||||
return { ssrFailed: true, ssrVNodes: [] }
|
return { ssrFailed: true, ssrVNodes: [] }
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import { distDir } from '../dirs'
|
|||||||
import { componentNamesTemplate, componentsIslandsTemplate, componentsMetadataTemplate, componentsPluginTemplate, componentsTypeTemplate } from './templates'
|
import { componentNamesTemplate, componentsIslandsTemplate, componentsMetadataTemplate, componentsPluginTemplate, componentsTypeTemplate } from './templates'
|
||||||
import { scanComponents } from './scan'
|
import { scanComponents } from './scan'
|
||||||
|
|
||||||
import { ClientFallbackAutoIdPlugin } from './plugins/client-fallback-auto-id'
|
|
||||||
import { LoaderPlugin } from './plugins/loader'
|
import { LoaderPlugin } from './plugins/loader'
|
||||||
import { ComponentsChunkPlugin, IslandsTransformPlugin } from './plugins/islands-transform'
|
import { ComponentsChunkPlugin, IslandsTransformPlugin } from './plugins/islands-transform'
|
||||||
import { TransformPlugin } from './plugins/transform'
|
import { TransformPlugin } from './plugins/transform'
|
||||||
@ -220,11 +219,6 @@ export default defineNuxtModule<ComponentsOptions>({
|
|||||||
addBuildPlugin(TreeShakeTemplatePlugin({ sourcemap: !!nuxt.options.sourcemap.server, getComponents }), { client: false })
|
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 = {
|
const sharedLoaderOptions = {
|
||||||
getComponents,
|
getComponents,
|
||||||
serverComponentRuntime,
|
serverComponentRuntime,
|
||||||
|
@ -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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
Loading…
Reference in New Issue
Block a user