feat(nuxt): allow remote sources for islands (#21592)

This commit is contained in:
Julien Huang 2023-07-30 23:00:41 +02:00 committed by GitHub
parent 620097241a
commit ffc4e798cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -36,12 +36,17 @@ export default defineComponent({
context: { context: {
type: Object, type: Object,
default: () => ({}) default: () => ({})
},
source: {
type: String,
default: () => undefined
} }
}, },
async setup (props, { slots }) { async setup (props, { slots }) {
const error = ref<unknown>(null)
const config = useRuntimeConfig() const config = useRuntimeConfig()
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
const hashId = computed(() => hash([props.name, props.props, props.context])) const hashId = computed(() => hash([props.name, props.props, props.context, props.source]))
const instance = getCurrentInstance()! const instance = getCurrentInstance()!
const event = useRequestEvent() const event = useRequestEvent()
// TODO: remove use of `$fetch.raw` when nitro 503 issues on windows dev server are resolved // TODO: remove use of `$fetch.raw` when nitro 503 issues on windows dev server are resolved
@ -100,7 +105,8 @@ export default defineComponent({
const key = `${props.name}_${hashId.value}` const key = `${props.name}_${hashId.value}`
if (nuxtApp.payload.data[key] && !force) { return nuxtApp.payload.data[key] } if (nuxtApp.payload.data[key] && !force) { return nuxtApp.payload.data[key] }
const url = `/__nuxt_island/${key}` const url = props.source ? new URL(`/__nuxt_island/${key}`, props.source).href : `/__nuxt_island/${key}`
if (process.server && process.env.prerender) { if (process.server && process.env.prerender) {
// Hint to Nitro to prerender the island component // Hint to Nitro to prerender the island component
appendResponseHeader(event, 'x-nitro-prerender', url) appendResponseHeader(event, 'x-nitro-prerender', url)
@ -130,18 +136,23 @@ export default defineComponent({
delete nuxtApp[pKey]![uid.value] delete nuxtApp[pKey]![uid.value]
}) })
} }
const res: NuxtIslandResponse = await nuxtApp[pKey][uid.value] try {
cHead.value.link = res.head.link const res: NuxtIslandResponse = await nuxtApp[pKey][uid.value]
cHead.value.style = res.head.style cHead.value.link = res.head.link
ssrHTML.value = res.html.replace(UID_ATTR, () => { cHead.value.style = res.head.style
return `nuxt-ssr-component-uid="${getId()}"` ssrHTML.value = res.html.replace(UID_ATTR, () => {
}) return `nuxt-ssr-component-uid="${getId()}"`
key.value++ })
if (process.client) { key.value++
// must await next tick for Teleport to work correctly with static node re-rendering error.value = null
await nextTick() if (process.client) {
// must await next tick for Teleport to work correctly with static node re-rendering
await nextTick()
}
setUid()
} catch (e) {
error.value = e
} }
setUid()
} }
if (import.meta.hot) { if (import.meta.hot) {
@ -160,6 +171,9 @@ export default defineComponent({
} }
return () => { return () => {
if (error.value && slots.fallback) {
return [slots.fallback({ error: error.value })]
}
const nodes = [createVNode(Fragment, { const nodes = [createVNode(Fragment, {
key: key.value key: key.value
}, [h(createStaticVNode(html.value, 1))])] }, [h(createStaticVNode(html.value, 1))])]