mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 15:15:19 +00:00
fix(nuxt): don't treeshake client-only fallback templates (#7659)
This commit is contained in:
parent
42cf48e45d
commit
f8a23564c3
@ -6,7 +6,7 @@ import type { Component } from '@nuxt/schema'
|
||||
|
||||
interface TreeShakeTemplatePluginOptions {
|
||||
sourcemap?: boolean
|
||||
getComponents(): Component[]
|
||||
getComponents (): Component[]
|
||||
}
|
||||
|
||||
export const TreeShakeTemplatePlugin = createUnplugin((options: TreeShakeTemplatePluginOptions) => {
|
||||
@ -26,7 +26,7 @@ export const TreeShakeTemplatePlugin = createUnplugin((options: TreeShakeTemplat
|
||||
.filter(c => c.mode === 'client' && !components.some(other => other.mode !== 'client' && other.pascalName === c.pascalName))
|
||||
.map(c => `${c.pascalName}|${c.kebabName}`)
|
||||
.concat('ClientOnly|client-only')
|
||||
.map(component => `<(${component})[^>]*>[\\s\\S]*?<\\/(${component})>`)
|
||||
.map(component => `<(${component})(| [^>]*)>[\\s\\S]*?<\\/(${component})>`)
|
||||
|
||||
regexpMap.set(components, new RegExp(`(${clientOnlyComponents.join('|')})`, 'g'))
|
||||
}
|
||||
@ -34,8 +34,12 @@ export const TreeShakeTemplatePlugin = createUnplugin((options: TreeShakeTemplat
|
||||
const COMPONENTS_RE = regexpMap.get(components)!
|
||||
const s = new MagicString(code)
|
||||
|
||||
// Do not render client-only slots on SSR, but preserve attributes
|
||||
s.replace(COMPONENTS_RE, r => r.replace(/<([^>]*[^/])\/?>[\s\S]*$/, '<$1 />'))
|
||||
// Do not render client-only slots on SSR, but preserve attributes and fallback/placeholder slots
|
||||
s.replace(COMPONENTS_RE, r => r.replace(/<([^>]*[^/])\/?>[\s\S]*$/, (chunk: string, el: string) => {
|
||||
const fallback = chunk.match(/<template[^>]*(#|v-slot:)(fallback|placeholder)[^>]*>[\s\S]*?<\/template>/)?.[0] || ''
|
||||
const tag = el.split(' ').shift()
|
||||
return `<${el}>${fallback}</${tag}>`
|
||||
}))
|
||||
|
||||
if (s.hasChanged()) {
|
||||
return {
|
||||
|
@ -137,6 +137,8 @@ describe('pages', () => {
|
||||
const html = await $fetch('/client-only-components')
|
||||
expect(html).toContain('<div class="client-only-script" foo="bar">')
|
||||
expect(html).toContain('<div class="client-only-script-setup" foo="hello">')
|
||||
expect(html).toContain('<div>Fallback</div>')
|
||||
expect(html).not.toContain('Should not be server rendered')
|
||||
|
||||
await expectNoClientErrors('/client-only-components')
|
||||
})
|
||||
|
@ -8,5 +8,11 @@
|
||||
</div>
|
||||
</template>
|
||||
</ClientOnlySetupScript>
|
||||
<ClientOnly>
|
||||
Should not be server rendered.
|
||||
<template #fallback>
|
||||
<div>Fallback</div>
|
||||
</template>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
</template>
|
||||
|
Loading…
Reference in New Issue
Block a user