Setting custom directive to empty string causes syntax error in generated code
Vue version
3.2.37
Link to minimal reproduction
Steps to reproduce
Use a custom directive in your template with an empty string as the value, e.g. <span v-custom-directive="">
or <span v-custom-directive:foo="">
What is expected?
The custom directive handler is invoked. I don't know what binding.value
should be, probably some bottom value like ''
or undefined
or null
.
What is actually happening?
When using client-side template interpretation, the custom directive handler is invoked with binding.value = undefined;
, which is fine.
However, when server-side template compilation is used, the JS code that is generated for this template has a syntax error. For v-custom-directive=""
the generated code looks like this: (note trailing comma in array, which is invalid)
_withDirectives(_createElementVNode("span", null, null, 512 /* NEED_PATCH */), [
[_directive_custom_directive, ]
]),
For v-custom-directive:foo=""
it looks like this: (note double comma in array, which is invalid)
_withDirectives(_createElementVNode("span", null, null, 512 /* NEED_PATCH */), [
[_directive_custom_directive, , "foo"]
])
Something similar happens in SSR mode:
// v-custom-directive="" generates:
_ssrRenderAttrs(_ssrGetDirectiveProps(_ctx, _directive_custom_directive, ))
// v-custom-directive:foo="" generates:
_ssrRenderAttrs(_ssrGetDirectiveProps(_ctx, _directive_custom_directive, , "foo"))
This then results in the entire app crashing, because Vue attempts to execute the generated code, which fails with a syntax error.
System Info
System:
OS: Linux 5.4 Ubuntu 20.04.4 LTS (Focal Fossa)
CPU: (8) x64 Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
Memory: 189.98 MB / 15.39 GB
Container: Yes
Shell: 5.0.17 - /bin/bash
Binaries:
Node: 16.9.1 - ~/.nvm/versions/node/v16.9.1/bin/node
Yarn: 1.22.11 - ~/.nvm/versions/node/v16.9.1/bin/yarn
npm: 8.5.3 - ~/.nvm/versions/node/v16.9.1/bin/npm
Browsers:
Chrome: 103.0.5060.114
Chromium: 102.0.5005.115
Firefox: 102.0
npmPackages:
vue: ^3.2.37 => 3.2.37
Any additional comments?
No response
From a quick first look: Both of these Syntax "errors" in arrays are valid Javascript.
Its just that the implentation expects a expression in the directive value and doesnt account for an empty one - much like Vue's own directives dont like empty values.
The SSR ones need a fix though.
Yes, you're right, I didn't realize that double/trailing commas are allowed in arrays, but they are. They're not allowed in function calls though, which is why the SSR ones are broken as you say (and SSR is where I ran into this bug)