feat(nuxt): allow fallback production content in `<DevOnly>` (#20817)

This commit is contained in:
Inesh Bose 2023-05-13 23:32:31 +01:00 committed by GitHub
parent 900ee6dc8b
commit d077c10c41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 18 additions and 3 deletions

View File

@ -336,6 +336,11 @@ The content will not be included in production builds and tree-shaken.
<DevOnly> <DevOnly>
<!-- this component will only be rendered during development --> <!-- this component will only be rendered during development -->
<LazyDebugBar /> <LazyDebugBar />
<!-- if you ever require to have a replacement during production -->
<template #fallback>
<div><!-- empty div for flex.justify-between --></div>
</template>
</DevOnly> </DevOnly>
</div> </div>
</template> </template>

View File

@ -6,6 +6,6 @@ export default defineComponent({
if (process.dev) { if (process.dev) {
return () => props.slots.default?.() return () => props.slots.default?.()
} }
return () => null return () => props.slots.fallback?.()
} }
}) })

View File

@ -9,7 +9,7 @@ interface DevOnlyPluginOptions {
} }
export const DevOnlyPlugin = createUnplugin((options: DevOnlyPluginOptions) => { export const DevOnlyPlugin = createUnplugin((options: DevOnlyPluginOptions) => {
const DEVONLY_COMP_RE = /<(dev-only|DevOnly)>[\s\S]*?<\/(dev-only|DevOnly)>/g const DEVONLY_COMP_RE = /<(?:dev-only|DevOnly)>[^<]*(?:<template\s+#fallback>(?<fallback>[\s\S]*?)<\/template>)?[\s\S]*?<\/(?:dev-only|DevOnly)>/g
return { return {
name: 'nuxt:server-devonly:transform', name: 'nuxt:server-devonly:transform',
@ -29,7 +29,7 @@ export const DevOnlyPlugin = createUnplugin((options: DevOnlyPluginOptions) => {
const s = new MagicString(code) const s = new MagicString(code)
const strippedCode = stripLiteral(code) const strippedCode = stripLiteral(code)
for (const match of strippedCode.matchAll(DEVONLY_COMP_RE) || []) { for (const match of strippedCode.matchAll(DEVONLY_COMP_RE) || []) {
s.remove(match.index!, match.index! + match[0].length) s.overwrite(match.index!, match.index! + match[0].length, match.groups?.fallback || '')
} }
if (s.hasChanged()) { if (s.hasChanged()) {

View File

@ -83,6 +83,8 @@ describe('pages', () => {
expect(html).toContain('Composable | star: auto imported from ~/composables/nested/bar.ts via star export') expect(html).toContain('Composable | star: auto imported from ~/composables/nested/bar.ts via star export')
// should import components // should import components
expect(html).toContain('This is a custom component with a named export.') expect(html).toContain('This is a custom component with a named export.')
// should remove dev-only and replace with any fallback content
expect(html).toContain(isDev() ? 'Some dev-only info' : 'Some prod-only info')
// should apply attributes to client-only components // should apply attributes to client-only components
expect(html).toContain('<div style="color:red;" class="client-only"></div>') expect(html).toContain('<div style="color:red;" class="client-only"></div>')
// should render server-only components // should render server-only components

View File

@ -11,6 +11,14 @@
<div>Composable | star: {{ useNestedBar() }}</div> <div>Composable | star: {{ useNestedBar() }}</div>
<DevOnly>Some dev-only info</DevOnly> <DevOnly>Some dev-only info</DevOnly>
<div><DevOnly>Some dev-only info</DevOnly></div> <div><DevOnly>Some dev-only info</DevOnly></div>
<div>
<DevOnly>
Some dev-only info
<template #fallback>
Some prod-only info
</template>
</DevOnly>
</div>
<div>Path: {{ $route.fullPath }}</div> <div>Path: {{ $route.fullPath }}</div>
<NuxtLink to="/"> <NuxtLink to="/">
Link Link