2.4.2
https://github.com/Justineo/vue-esnext-in-template
vue init webpack esnext-in-template
src/components/Hello.vue
:
<template>
<div :class="{ a: true, ...b }"></div>
</template>
<script>
export default {
data () {
return { b: true }
}
}
</script>
(babel-preset-stage-2
is already enabled after initializing with vue-cli
.)
The class
value should be a b
.
Error compiling template:
- invalid expression: :class="{ a: true, ...b }"
vue-template-compiler
seems to be validating the expression before it goes through Babel with trying to evaluate new Function(exp)
. This makes ES features that can be used in templates limited to those Node supports and causes confusion: I can translate spread operators for arrays both in templates and elsewhere but I can translate spread operators for objects anywhere except in templates. I think this might not be intentional so I mark this as a bug.
As a workaround for now you can use latest Node with --harmony
flag to build it.
@nickmessing
Thanks for the work around. But there are still some problem for this solution:
--harmony
flag.@Justineo, I personally would not like to change this mechanism because if we move that away from babel-template-compiler it would result in runtime errors which make it hard to track down mistakes in templates. Another way is to try and parse it with babel instead of new Function()
but that is slow and I need to research actual performance impact.
@Justineo, unfortunately, using babylon
to parse expression breaks our current solution since it parses keywords successfully (ex: (do + 1)
) and adds extra dependency. Looks like it's not an option and we are limited to use only code that is supported by node in expressions. --harmony
solves the spread problem at the moment.
Thanks Nick. I think it's better to point this out in the docs to prevent confusion. I'll make a PR later if you don't mind.
i have learned a lot
Closing this issue, doesn't seem that we can consider this further.
@nickmessing Any reason we couldn't just use babel-node
instead of node
for the build step in the Webpack template?
@chrisvfritz I wouldn't recommend using babel-node, it has some performance overhead
@posva How much slower are we talking about though? I think predictable behavior is worth slightly slower builds - or even moderately slower builds. Isn't that already a trade-off we're choosing when we write tests? Or when we include a build system that compiles to more predictably supported JavaScript? 馃槈
My concern is that adding a note to the documentation won't be sufficient. When people encounter this problem, it will be nearly impossible to find that note and they could easily waste a day trying to figure out why this feature isn't working correctly - or probably more likely, just give up, assuming the Vue template compiler is buggy or lied about supporting Babel features.
If it _really_ isn't feasible to find a consistent workaround, I think we'll need some other way to communicate to users, like catch errors in the Vue template compiler to provide a warning about this behavior.
@chrisvfritz I haven't tested using babel-node with the webpack template (nor do I know if it's possible). I cannot remember what it was, but I keep a slightly bad memory of using it for node projects.
@posva, @chrisvfritz, it's not an option here anyway since it doesn't transpire code from new Function
, I think I know a way to make it work with babylon
but only if we make it a dependency of template compiler, can this be considered?
@nickmessing @posva While we investigate, would either of you mind if we reopened this for now, just to make sure we don't forget about it? Since it's not really a problem documentation can solve, I'm thinking we should only close when we can do one of these:
@nickmessing I think most users aren't too concerned about the size of dev dependencies, so that would be alright for me if it would make things work as users expect. 馃檪
@chrisvfritz, unfortunately I don't know how to have it without bundling Babylon into runtime build :-S
@chrisvfritz No worries 馃槅
@nickmessing Ah, I see. Crazy idea then: could we avoid pulling babylon into the template compiler with something like below at the beginning of the checkExpression
function?
if (envIsNode) {
exp = eval('require("babylon")').parse(exp, userBabelConfig)
}
That's closer to pseudocode than a real solution, but do you think the strategy I'm getting at might be feasible?
@chrisvfritz, actually yes, I'll try that way.
With spread operators natively supported in Node 8.3+, I'll close this as a wontfix for now.
In order to use Object rest spread in templates, you need to:
Use Node v8.3+
Configure buble
option for vue-loader
:
buble: { objectAssign: 'Object.assign' }
If targeting any IE, make sure to include polyfill for Object.assign
.
In 2.6 we will likely coordinate the configuration so that in a vue-cli
project you will be able to use object rest spread without any configuration.
@LinusBorg @yyx990803 During Vue CLI 3 builds, perhaps we should also emit a warning for older versions of Node.
What about optional chaining and other babel plugins in the templates?
when the vue-loader support optional chaining ? This is a very important feature
@Justineo it is cumbersome. it is not like vue style (simple)
Hi guys,
I want to use chaining operator in template part, is there any solution to do that ?
My problem is that i'm in a "v-if" hell! I need to check every nested structure with v-if to avoid bugs and errors in case of null value ... so this operator would be nice to avoid too many v-if.
I could use the operator in a computed properties, but my point is to clean my code of useless syntax, and calling a method with argument is bigger than writing a v-if...
Right now optional chaining has been officially part of ECMAScript 2020 (Chrome 80), therefore I think maybe we should reconsider this feature request again.
I want to use chaining operator in template part too, is there any solution to do that ?
Most helpful comment
Right now optional chaining has been officially part of ECMAScript 2020 (Chrome 80), therefore I think maybe we should reconsider this feature request again.