fix(nuxt): add mergeProps import in islands transform (#27622)

This commit is contained in:
Daniel Roe 2024-06-15 12:15:54 +01:00 committed by GitHub
parent 460d205edd
commit ae5806518a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 48 additions and 2 deletions

View File

@ -28,7 +28,7 @@ const SCRIPT_RE = /<script[^>]*>/g
const HAS_SLOT_OR_CLIENT_RE = /<slot[^>]*>|nuxt-client/ const HAS_SLOT_OR_CLIENT_RE = /<slot[^>]*>|nuxt-client/
const TEMPLATE_RE = /<template>([\s\S]*)<\/template>/ const TEMPLATE_RE = /<template>([\s\S]*)<\/template>/
const NUXTCLIENT_ATTR_RE = /\s:?nuxt-client(="[^"]*")?/g const NUXTCLIENT_ATTR_RE = /\s:?nuxt-client(="[^"]*")?/g
const IMPORT_CODE = '\nimport { vforToArray as __vforToArray } from \'#app/components/utils\'' + '\nimport NuxtTeleportIslandComponent from \'#app/components/nuxt-teleport-island-component\'' + '\nimport NuxtTeleportSsrSlot from \'#app/components/nuxt-teleport-island-slot\'' const IMPORT_CODE = '\nimport { mergeProps as __mergeProps } from \'vue\'' + '\nimport { vforToArray as __vforToArray } from \'#app/components/utils\'' + '\nimport NuxtTeleportIslandComponent from \'#app/components/nuxt-teleport-island-component\'' + '\nimport NuxtTeleportSsrSlot from \'#app/components/nuxt-teleport-island-slot\''
const EXTRACTED_ATTRS_RE = /v-(?:if|else-if|else)(="[^"]*")?/g const EXTRACTED_ATTRS_RE = /v-(?:if|else-if|else)(="[^"]*")?/g
function wrapWithVForDiv (code: string, vfor: string): string { function wrapWithVForDiv (code: string, vfor: string): string {
@ -156,7 +156,7 @@ function getPropsToString (bindings: Record<string, string>): string {
const vfor = bindings['v-for']?.split(' in ').map((v: string) => v.trim()) as [string, string] | undefined const vfor = bindings['v-for']?.split(' in ').map((v: string) => v.trim()) as [string, string] | undefined
if (Object.keys(bindings).length === 0) { return 'undefined' } if (Object.keys(bindings).length === 0) { return 'undefined' }
const content = Object.entries(bindings).filter(b => b[0] && (b[0] !== '_bind' && b[0] !== 'v-for')).map(([name, value]) => isBinding(name) ? `[\`${name.slice(1)}\`]: ${value}` : `[\`${name}\`]: \`${value}\``).join(',') const content = Object.entries(bindings).filter(b => b[0] && (b[0] !== '_bind' && b[0] !== 'v-for')).map(([name, value]) => isBinding(name) ? `[\`${name.slice(1)}\`]: ${value}` : `[\`${name}\`]: \`${value}\``).join(',')
const data = bindings._bind ? `mergeProps(${bindings._bind}, { ${content} })` : `{ ${content} }` const data = bindings._bind ? `__mergeProps(${bindings._bind}, { ${content} })` : `{ ${content} }`
if (!vfor) { if (!vfor) {
return `[${data}]` return `[${data}]`
} else { } else {

View File

@ -71,6 +71,7 @@ describe('islandTransform - server and island components', () => {
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { mergeProps as __mergeProps } from 'vue'
import { vforToArray as __vforToArray } from '#app/components/utils' import { vforToArray as __vforToArray } from '#app/components/utils'
import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component' import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component'
import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot' import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'
@ -80,6 +81,42 @@ describe('islandTransform - server and island components', () => {
`) `)
}) })
it('generates bindings when props are needed to be merged', async () => {
const result = await viteTransform(`<script setup lang="ts">
withDefaults(defineProps<{ things?: any[]; somethingElse?: string }>(), {
things: () => [],
somethingElse: "yay",
});
</script>
<template>
<template v-for="thing in things">
<slot name="thing" v-bind="thing" />
</template>
</template>
`, 'hello.server.vue')
expect(normalizeLineEndings(result)).toMatchInlineSnapshot(`
"<script setup lang="ts">
import { mergeProps as __mergeProps } from 'vue'
import { vforToArray as __vforToArray } from '#app/components/utils'
import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component'
import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'
withDefaults(defineProps<{ things?: any[]; somethingElse?: string }>(), {
things: () => [],
somethingElse: "yay",
});
</script>
<template>
<template v-for="thing in things">
<NuxtTeleportSsrSlot name="thing" :props="[__mergeProps(thing, { })]"><slot name="thing" v-bind="thing" /></NuxtTeleportSsrSlot>
</template>
</template>
"
`)
})
it('expect slot fallback transform to match inline snapshot', async () => { it('expect slot fallback transform to match inline snapshot', async () => {
const result = await viteTransform(`<template> const result = await viteTransform(`<template>
<div> <div>
@ -103,6 +140,7 @@ describe('islandTransform - server and island components', () => {
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { mergeProps as __mergeProps } from 'vue'
import { vforToArray as __vforToArray } from '#app/components/utils' import { vforToArray as __vforToArray } from '#app/components/utils'
import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component' import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component'
import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot' import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'
@ -168,6 +206,7 @@ describe('islandTransform - server and island components', () => {
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { mergeProps as __mergeProps } from 'vue'
import { vforToArray as __vforToArray } from '#app/components/utils' import { vforToArray as __vforToArray } from '#app/components/utils'
import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component' import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component'
import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot' import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'
@ -195,6 +234,7 @@ describe('islandTransform - server and island components', () => {
expect(normalizeLineEndings(result)).toMatchInlineSnapshot(` expect(normalizeLineEndings(result)).toMatchInlineSnapshot(`
"<script setup lang="ts"> "<script setup lang="ts">
import { mergeProps as __mergeProps } from 'vue'
import { vforToArray as __vforToArray } from '#app/components/utils' import { vforToArray as __vforToArray } from '#app/components/utils'
import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component' import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component'
import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot' import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'
@ -234,6 +274,7 @@ describe('islandTransform - server and island components', () => {
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { mergeProps as __mergeProps } from 'vue'
import { vforToArray as __vforToArray } from '#app/components/utils' import { vforToArray as __vforToArray } from '#app/components/utils'
import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component' import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component'
import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot' import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'
@ -267,6 +308,7 @@ describe('islandTransform - server and island components', () => {
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { mergeProps as __mergeProps } from 'vue'
import { vforToArray as __vforToArray } from '#app/components/utils' import { vforToArray as __vforToArray } from '#app/components/utils'
import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component' import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component'
import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot' import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'
@ -302,6 +344,7 @@ describe('islandTransform - server and island components', () => {
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { mergeProps as __mergeProps } from 'vue'
import { vforToArray as __vforToArray } from '#app/components/utils' import { vforToArray as __vforToArray } from '#app/components/utils'
import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component' import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component'
import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot' import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'
@ -325,6 +368,7 @@ describe('islandTransform - server and island components', () => {
expect(result).toMatchInlineSnapshot(` expect(result).toMatchInlineSnapshot(`
"<script setup> "<script setup>
import { mergeProps as __mergeProps } from 'vue'
import { vforToArray as __vforToArray } from '#app/components/utils' import { vforToArray as __vforToArray } from '#app/components/utils'
import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component' import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component'
import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'</script><template> import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'</script><template>
@ -351,6 +395,7 @@ describe('islandTransform - server and island components', () => {
expect(result).toMatchInlineSnapshot(` expect(result).toMatchInlineSnapshot(`
"<script setup> "<script setup>
import { mergeProps as __mergeProps } from 'vue'
import { vforToArray as __vforToArray } from '#app/components/utils' import { vforToArray as __vforToArray } from '#app/components/utils'
import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component' import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component'
import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'</script><template> import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'</script><template>
@ -396,6 +441,7 @@ describe('islandTransform - server and island components', () => {
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { mergeProps as __mergeProps } from 'vue'
import { vforToArray as __vforToArray } from '#app/components/utils' import { vforToArray as __vforToArray } from '#app/components/utils'
import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component' import NuxtTeleportIslandComponent from '#app/components/nuxt-teleport-island-component'
import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot' import NuxtTeleportSsrSlot from '#app/components/nuxt-teleport-island-slot'