Skip to content

Commit 62c1b2f

Browse files
committed
fix(compiler-sfc): fix defineProps/defineEmits usage in multi-variable declarations
fix #3739
1 parent 2973b6c commit 62c1b2f

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap

+32
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,38 @@ return { props, bar }
108108
}"
109109
`;
110110
111+
exports[`SFC compile <script setup> defineProps/defineEmits in multi-variable decalration (full removal) 1`] = `
112+
"export default {
113+
props: ['item'],
114+
emits: ['a'],
115+
setup(__props, { expose, emit }) {
116+
expose()
117+
118+
const props = __props
119+
120+
121+
return { props, emit }
122+
}
123+
124+
}"
125+
`;
126+
127+
exports[`SFC compile <script setup> defineProps/defineEmits in multi-variable decalration 1`] = `
128+
"export default {
129+
props: ['item'],
130+
emits: ['a'],
131+
setup(__props, { expose, emit }) {
132+
expose()
133+
134+
const props = __props
135+
const a = 1;
136+
137+
return { props, a, emit }
138+
}
139+
140+
}"
141+
`;
142+
111143
exports[`SFC compile <script setup> errors should allow defineProps/Emit() referencing imported binding 1`] = `
112144
"import { bar } from './bar'
113145

packages/compiler-sfc/__tests__/compileScript.spec.ts

+26
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,32 @@ const myEmit = defineEmits(['foo', 'bar'])
9797
emits: ['foo', 'bar'],`)
9898
})
9999

100+
test('defineProps/defineEmits in multi-variable decalration', () => {
101+
const { content } = compile(`
102+
<script setup>
103+
const props = defineProps(['item']),
104+
a = 1,
105+
emit = defineEmits(['a']);
106+
</script>
107+
`)
108+
assertCode(content)
109+
expect(content).toMatch(`const a = 1;`) // test correct removal
110+
expect(content).toMatch(`props: ['item'],`)
111+
expect(content).toMatch(`emits: ['a'],`)
112+
})
113+
114+
test('defineProps/defineEmits in multi-variable decalration (full removal)', () => {
115+
const { content } = compile(`
116+
<script setup>
117+
const props = defineProps(['item']),
118+
emit = defineEmits(['a']);
119+
</script>
120+
`)
121+
assertCode(content)
122+
expect(content).toMatch(`props: ['item'],`)
123+
expect(content).toMatch(`emits: ['a'],`)
124+
})
125+
100126
test('defineExpose()', () => {
101127
const { content } = compile(`
102128
<script setup>

packages/compiler-sfc/src/compileScript.ts

+16-3
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,10 @@ export function compileScript(
820820
}
821821

822822
if (node.type === 'VariableDeclaration' && !node.declare) {
823-
for (const decl of node.declarations) {
823+
const total = node.declarations.length
824+
let left = total
825+
for (let i = 0; i < total; i++) {
826+
const decl = node.declarations[i]
824827
if (decl.init) {
825828
const isDefineProps =
826829
processDefineProps(decl.init) || processWithDefaults(decl.init)
@@ -838,10 +841,20 @@ export function compileScript(
838841
)
839842
}
840843
if (isDefineProps || isDefineEmits)
841-
if (node.declarations.length === 1) {
844+
if (left === 1) {
842845
s.remove(node.start! + startOffset, node.end! + startOffset)
843846
} else {
844-
s.remove(decl.start! + startOffset, decl.end! + startOffset)
847+
let start = decl.start! + startOffset
848+
let end = decl.end! + startOffset
849+
if (i < total - 1) {
850+
// not the last one, locate the start of the next
851+
end = node.declarations[i + 1].start! + startOffset
852+
} else {
853+
// last one, locate the end of the prev
854+
start = node.declarations[i - 1].end! + startOffset
855+
}
856+
s.remove(start, end)
857+
left--
845858
}
846859
}
847860
}

0 commit comments

Comments
 (0)