perf(nuxt): allow hmr for server components in dev mode (#21916)

This commit is contained in:
Daniel Roe 2023-07-04 05:21:27 +01:00 committed by GitHub
parent d15df420a3
commit 435ac87961
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 7 deletions

View File

@ -67,9 +67,9 @@ export default defineComponent({
const cHead = ref<Record<'link' | 'style', Array<Record<string, string>>>>({ link: [], style: [] })
useHead(cHead)
async function _fetchComponent () {
async function _fetchComponent (force = false) {
const key = `${props.name}_${hashId.value}`
if (nuxtApp.payload.data[key]) { return nuxtApp.payload.data[key] }
if (nuxtApp.payload.data[key] && !force) { return nuxtApp.payload.data[key] }
const url = `/__nuxt_island/${key}`
if (process.server && process.env.prerender) {
@ -106,10 +106,10 @@ export default defineComponent({
return result
}
const key = ref(0)
async function fetchComponent () {
async function fetchComponent (force = false) {
nuxtApp[pKey] = nuxtApp[pKey] || {}
if (!nuxtApp[pKey][uid.value]) {
nuxtApp[pKey][uid.value] = _fetchComponent().finally(() => {
nuxtApp[pKey][uid.value] = _fetchComponent(force).finally(() => {
delete nuxtApp[pKey]![uid.value]
})
}
@ -127,10 +127,17 @@ export default defineComponent({
setUid()
}
if (process.client) {
watch(props, debounce(fetchComponent, 100))
if (import.meta.hot) {
import.meta.hot.on(`nuxt-server-component:${props.name}`, () => {
fetchComponent(true)
})
}
if (process.client) {
watch(props, debounce(() => fetchComponent(), 100))
}
// TODO: allow lazy loading server islands
if (process.server || !nuxtApp.isHydrating) {
await fetchComponent()
}

View File

@ -1,5 +1,5 @@
import { statSync } from 'node:fs'
import { relative, resolve } from 'pathe'
import { normalize, relative, resolve } from 'pathe'
import { addPluginTemplate, addTemplate, addVitePlugin, addWebpackPlugin, defineNuxtModule, resolveAlias, updateTemplates } from '@nuxt/kit'
import type { Component, ComponentsDir, ComponentsOptions } from 'nuxt/schema'
@ -227,6 +227,22 @@ export default defineNuxtModule<ComponentsOptions>({
getComponents
}))
}
if (!isServer && nuxt.options.experimental.componentIslands) {
config.plugins.push({
name: 'nuxt-server-component-hmr',
handleHotUpdate (ctx) {
const components = getComponents()
const filePath = normalize(ctx.file)
const comp = components.find(c => c.filePath === filePath)
if (comp?.mode === 'server') {
ctx.server.ws.send({
event: `nuxt-server-component:${comp.pascalName}`,
type: 'custom'
})
}
}
})
}
})
nuxt.hook('webpack:config', (configs) => {
configs.forEach((config) => {