From df38770bfbfb00f0af0bc4b002e647e5099ce7e5 Mon Sep 17 00:00:00 2001
From: zhiyuanzmj <260480378@qq.com>
Date: Sun, 9 Mar 2025 08:53:37 +0800
Subject: [PATCH 1/2] feat(compiler-vapor): remove unused empty DOM from slots
 when whitespace is preserve

---
 .../__snapshots__/vSlot.spec.ts.snap          | 65 +++++++++++++++++++
 .../__tests__/transforms/vSlot.spec.ts        | 56 ++++++++++++++++
 .../compiler-vapor/src/transforms/vSlot.ts    | 18 +++--
 3 files changed, 134 insertions(+), 5 deletions(-)

diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap
index bab5c104605..5357027052f 100644
--- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap
+++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap
@@ -249,3 +249,68 @@ export function render(_ctx) {
   return n1
 }"
 `;
+
+exports[`compiler: transform slot > with whitespace: 'preserve' > implicit default slot 1`] = `
+"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback, template as _template } from 'vue';
+const t0 = _template(" Header ")
+const t1 = _template(" ")
+const t2 = _template("<p></p>")
+
+export function render(_ctx) {
+  const _component_Comp = _resolveComponent("Comp")
+  const n4 = _createComponentWithFallback(_component_Comp, null, {
+    "header": () => {
+      const n0 = t0()
+      return n0
+    }, 
+    "default": () => {
+      const n2 = t1()
+      const n3 = t2()
+      return [n2, n3]
+    }
+  }, true)
+  return n4
+}"
+`;
+
+exports[`compiler: transform slot > with whitespace: 'preserve' > named default slot + implicit whitespace content 1`] = `
+"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback, template as _template } from 'vue';
+const t0 = _template(" Header ")
+const t1 = _template(" Default ")
+
+export function render(_ctx) {
+  const _component_Comp = _resolveComponent("Comp")
+  const n4 = _createComponentWithFallback(_component_Comp, null, {
+    "header": () => {
+      const n0 = t0()
+      return n0
+    }, 
+    "default": () => {
+      const n2 = t1()
+      return n2
+    }
+  }, true)
+  return n4
+}"
+`;
+
+exports[`compiler: transform slot > with whitespace: 'preserve' > should not generate whitespace only default slot 1`] = `
+"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback, template as _template } from 'vue';
+const t0 = _template(" Header ")
+const t1 = _template(" Footer ")
+
+export function render(_ctx) {
+  const _component_Comp = _resolveComponent("Comp")
+  const n4 = _createComponentWithFallback(_component_Comp, null, {
+    "header": () => {
+      const n0 = t0()
+      return n0
+    }, 
+    "footer": () => {
+      const n2 = t1()
+      return n2
+    }
+  }, true)
+  return n4
+}"
+`;
diff --git a/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts b/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts
index caa45681a24..2e70298a864 100644
--- a/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts
+++ b/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts
@@ -519,4 +519,60 @@ describe('compiler: transform slot', () => {
       })
     })
   })
+
+  describe(`with whitespace: 'preserve'`, () => {
+    test('named default slot + implicit whitespace content', () => {
+      const source = `
+      <Comp>
+        <template #header> Header </template>
+        <template #default> Default </template>
+      </Comp>
+      `
+      const { code } = compileWithSlots(source, {
+        whitespace: 'preserve',
+      })
+
+      expect(
+        `Extraneous children found when component already has explicitly named default slot.`,
+      ).not.toHaveBeenWarned()
+      // expect(code).toMatchSnapshot()
+      expect(code).toMatchSnapshot()
+    })
+
+    test('implicit default slot', () => {
+      const source = `
+      <Comp>
+        <template #header> Header </template>
+        <p/>
+      </Comp>
+      `
+      const { code } = compileWithSlots(source, {
+        whitespace: 'preserve',
+      })
+
+      expect(
+        `Extraneous children found when component already has explicitly named default slot.`,
+      ).not.toHaveBeenWarned()
+      expect(code).toMatchSnapshot()
+    })
+
+    test('should not generate whitespace only default slot', () => {
+      const source = `
+      <Comp>
+        <template #header> Header </template>
+        <template #footer> Footer </template>
+      </Comp>
+      `
+      const { code, ir } = compileWithSlots(source, {
+        whitespace: 'preserve',
+      })
+
+      const slots = (ir.block.operation[0] as any).slots[0].slots
+      // should be: header, footer (no default)
+      expect(Object.keys(slots).length).toBe(2)
+      expect(!!slots['default']).toBe(false)
+
+      expect(code).toMatchSnapshot()
+    })
+  })
 })
diff --git a/packages/compiler-vapor/src/transforms/vSlot.ts b/packages/compiler-vapor/src/transforms/vSlot.ts
index d1bf1c6b05f..a375b79a94e 100644
--- a/packages/compiler-vapor/src/transforms/vSlot.ts
+++ b/packages/compiler-vapor/src/transforms/vSlot.ts
@@ -66,11 +66,19 @@ function transformComponentSlot(
 ) {
   const { children } = node
   const arg = dir && dir.arg
-  const nonSlotTemplateChildren = children.filter(
-    n =>
-      isNonWhitespaceContent(node) &&
-      !(n.type === NodeTypes.ELEMENT && n.props.some(isVSlot)),
-  )
+
+  // whitespace: 'preserve'
+  let indexes: number[] = []
+  const nonSlotTemplateChildren = children.filter((n, i) => {
+    if (isNonWhitespaceContent(n)) {
+      return !(n.type === NodeTypes.ELEMENT && n.props.some(isVSlot))
+    } else {
+      indexes.push(i)
+    }
+  })
+  if (!nonSlotTemplateChildren.length) {
+    indexes.forEach(i => children.splice(i, 1))
+  }
 
   const [block, onExit] = createSlotBlock(node, dir, context)
 

From 622c684eb5e80c47c8b69957116408c76f7032dd Mon Sep 17 00:00:00 2001
From: zhiyuanzmj <260480378@qq.com>
Date: Mon, 10 Mar 2025 15:52:51 +0800
Subject: [PATCH 2/2] fix: typo

---
 packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts b/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts
index 2e70298a864..d02e543e116 100644
--- a/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts
+++ b/packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts
@@ -535,7 +535,6 @@ describe('compiler: transform slot', () => {
       expect(
         `Extraneous children found when component already has explicitly named default slot.`,
       ).not.toHaveBeenWarned()
-      // expect(code).toMatchSnapshot()
       expect(code).toMatchSnapshot()
     })