Vue version
3.5.26
Link to minimal reproduction
https://play.vuejs.org/#eNp9kE9LAzEQxb9KmEsVSgpWPdRV/EMPelBRjwFZ0umamk1CMlkXlv3uJimtPUhPCe/95vFmBrhzjncRYQEVYet0TXgjDGOVMi4Suy3PtYB1NJKUNezklA1scjVhowA2S2w1OxiEKVCQ1qxVwzfBmpQ75DgB0rZOafQvLscEAQtWnOzVWtufp6KRjzjd6fIL5fc/+ib0WRPw6jGg71DA3qPaN0hbe/n+jH36783WrqJO9BHzDYPVMXfcYvfRrFLtA660fWyd9aRM8xGWPaEJu6Vy0UyOhReQjvtwZPW/unN+XuaEGdMVPzv0OTMdcM4v+NkljL9dnInL
Steps to reproduce
Any function expression with semicolon inside it:
<template>
<input @input="function () { ';' }" />
</template>
What is expected?
No parsing errors.
What is actually happening?
(2:18) Error parsing JavaScript expression: Unexpected token (1:10)
When an event handler's source code string contains at least one semicolon (;), the handler is parsed as a statement. However, in JS, function declarations must have a name function DECL() {}. When the handler doesn't contain a semicolon, it's parsed as an expression; in that case a function expression may not have a name function () {}, so no parsing error is raised.
|
const hasMultipleStatements = exp.content.includes(`;`) |
Workarounds:
- Use an arrow functions
@input="() => { ';' }"
- Wrap the function in parens (enforcing it to be parsed as a function expression rather than a function declaration)
@input="(function () { ';' })"
What if, instead of using a heuristic (exp.content.includes(';')), the Vue parser tried to parse the event handler as an expression first (by wrapping the handler code in parens), and then, if a parser error occurred, fell back to parsing it as statements?
System Info
Any additional comments?
Doing so will also probably fix #8854
Vue version
3.5.26
Link to minimal reproduction
https://play.vuejs.org/#eNp9kE9LAzEQxb9KmEsVSgpWPdRV/EMPelBRjwFZ0umamk1CMlkXlv3uJimtPUhPCe/95vFmBrhzjncRYQEVYet0TXgjDGOVMi4Suy3PtYB1NJKUNezklA1scjVhowA2S2w1OxiEKVCQ1qxVwzfBmpQ75DgB0rZOafQvLscEAQtWnOzVWtufp6KRjzjd6fIL5fc/+ib0WRPw6jGg71DA3qPaN0hbe/n+jH36783WrqJO9BHzDYPVMXfcYvfRrFLtA660fWyd9aRM8xGWPaEJu6Vy0UyOhReQjvtwZPW/unN+XuaEGdMVPzv0OTMdcM4v+NkljL9dnInL
Steps to reproduce
Any function expression with semicolon inside it:
What is expected?
No parsing errors.
What is actually happening?
When an event handler's source code string contains at least one semicolon (
;), the handler is parsed as a statement. However, in JS, function declarations must have a namefunction DECL() {}. When the handler doesn't contain a semicolon, it's parsed as an expression; in that case a function expression may not have a namefunction () {}, so no parsing error is raised.core/packages/compiler-core/src/transforms/vOn.ts
Line 86 in aac7e18
Workarounds:
@input="() => { ';' }"@input="(function () { ';' })"What if, instead of using a heuristic (
exp.content.includes(';')), the Vue parser tried to parse the event handler as an expression first (by wrapping the handler code in parens), and then, if a parser error occurred, fell back to parsing it as statements?System Info
Any additional comments?
Doing so will also probably fix #8854