compiler-sfc: invalid declaration while using multiple variables with `defineEmits` and `defineProps`
Vue version
3.2.45
Link to minimal reproduction
Steps to reproduce
Define a set of variable with multiple declarations in SFC with <script setup>
:
const props = defineProps(),
emits = defineEmits(), //b
a = 0, //c
b = 0; //d
It will lead to wrong transpile result:
const , //b
a = 0, //c
b = 0; //d
What is expected?
It should be compiled into:
const a = 0, //c
b = 0; //d
Without any syntax error.
What is actually happening?
This bug is introduced in #6778, compiler-sfc fixed a bug #6757, which is also related to multiple variable declaration. Can reproduce in #6778's sfc-playgroound preview, but works perfectly in #6777 and older version.
Briefly, it occurs while we're processing a macro token with define*
, with the following steps:
https://github.com/vuejs/core/blob/c6e5bda27d13554675d68dbe33b07f3474467aa6/packages/compiler-sfc/src/compileScript.ts#L1222-L1228
- Get the actual position of the declaration of macros
- Remove the variable declaration of macros, based on the position, it has different behavior in multiple declarations:
- If the variable declaration is the first one, remove all the characters between the begin of current declaration and begin of next declaration
- If the variable declaration is not the first one, remove all the characters between the end of previous declaration and end of current declaration
We can notice that, if the declaration is the last macro but not the last variable declaration, it will keep the redundant part of the declaration, which leads to the final syntax error.
To fix this issue, we can make the characters between the beginning of current and begin of next (if have) are unconditionally removed:
if (i < total - 1) {
// not the last one, locate the start of the next
end = node.declarations[i + 1].start + startOffset
}
if (i != 0) {
// not first one, locate the end of the prev
start = node.declarations[i - 1].end + startOffset
}
I will submit a PR trying to fix that if you like this solution.
System Info
No response
Any additional comments?
No response