mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 05:35:13 +00:00
feat(nuxt): allow fallback production content in <DevOnly>
(#20817)
This commit is contained in:
parent
900ee6dc8b
commit
d077c10c41
@ -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>
|
||||||
|
@ -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?.()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -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()) {
|
||||||
|
@ -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
|
||||||
|
8
test/fixtures/basic/pages/index.vue
vendored
8
test/fixtures/basic/pages/index.vue
vendored
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user