vuejs / language-tools

⚡ High-performance Vue language tooling based-on Volar.js
https://marketplace.visualstudio.com/items?itemName=Vue.volar
MIT License
5.86k stars 399 forks source link

v-else is unexpected token #13

Closed pipe01 closed 4 years ago

pipe01 commented 4 years ago

I just installed this extension, and I must say it's really well done! My only complaint is that v-else is not recognized when using Pug, as in the following image:

imagen

The issue is solved when doing v-else="", but that's far from ideal.

johnsoncodehk commented 4 years ago

Thank you for your report~ currently, this is the expected result, if the following pug is converted to html:

div(v-if="true")
div(v-else)

Will get the following results:

<div v-if="true"></div>
<div v-else="v-else"></div>

So the error is from here:

螢幕截圖 2020-10-29 上午12 21 50

Vue does get this error when compiling the template, I guess Vue just ignored it.

pipe01 commented 4 years ago

Ah, I understand. Do you know of any way to make it output v-else="" instead?

johnsoncodehk commented 4 years ago

I think we can't, this is pug rule, see: https://pugjs.org/language/attributes.html

pipe01 commented 4 years ago

Hmm, well that's a bummer

johnsoncodehk commented 4 years ago

I can hide this error, but it is a hack, and I think reminding users to avoid this error will be more friendly to the vue compiler.

pipe01 commented 4 years ago

I think hiding it would be fine, since it's the recommended way to do it on the Vue docs

johnsoncodehk commented 4 years ago

I tried vue-cli-service to compile the following code and there will be an error:

<template>
<div v-if="true"></div>
<div v-else="v-else"></div>
</template>

But the following code will not give an error:

<template lang="pug">
div(v-if="true")
div(v-else)
</template>

I guess pug-plain-loader does some special work, and I will cooperate to hide this error :)

pipe01 commented 4 years ago

Interesting, thank you!

johnsoncodehk commented 4 years ago

fixed in 0.14.5

qnp commented 3 years ago

Hi @johnsoncodehk ,

I just came across this issue while looking for something similar happening in vue-docgen-cli.

You answer https://github.com/johnsoncodehk/volar/issues/13#issuecomment-718076785 has prompted me.

I have made some deep insights and I feel I had to share with you what I found. As I previously get into the code of pug-plain-loader to write a pug loader of my own, I remembered that this loader was only a wrapper of pug.compile, not much about handling v-else or ignoring errors. Indeed, check the 14 lines of the source code:

const pug = require('pug')
const loaderUtils = require('loader-utils')

module.exports = function (source) {
  const options = Object.assign({
    filename: this.resourcePath,
    doctype: 'html',
    compileDebug: this.debug || false
  }, loaderUtils.getOptions(this))

  const template = pug.compile(source, options)
  template.dependencies.forEach(this.addDependency)
  return template(options.data || {})
}

What is of interest here is that it uses option doctype: 'html' which avoid compilation of v-else into v-else="v-else" but makes it v-else only.

So the commit (https://github.com/johnsoncodehk/volar/commit/2f757dee4fc5eaf529833ea2f3e99b658898e0e2) fixing this issue could avoid importing pug-plain-loader which is designed to be a webpack loader and avoid the mock around this loader to in fact only apply doctype: 'html' to pug.copmile.

Best regards.

johnsoncodehk commented 3 years ago

@qnp thanks your time to sharing! now I can remove one depend ^^.