eslint-plugin-vue icon indicating copy to clipboard operation
eslint-plugin-vue copied to clipboard

vue/no-multi-spaces and global no-multi-spaces settings inconsistency

Open dsl101 opened this issue 10 months ago • 2 comments

I wasn't sure if this was a bug report or rule change, so posting here (didn't see a Discussion section in this repo).

The problem you want to solve. I have 'no-multi-spaces': [ 'warn', { ignoreEOLComments: true }] in my general eslint config, which allows multiple spaces for comments:

const meaning = 42;  // obviously

But when using JS inside Vue templates, this rule isn't respected:

<div
  :class="{
    'is-good': isGood(thing)  // hopefully
  }"
>

Warning: Multiple spaces found before '// hopefully'.

Your take on the correct solution to problem. It would be ideal if vue/no-multi-spaces were able to use the global setting and ignore comments in this case. Alternatively, could vue/no-multi-spaces support the same ignoreEOLComments option?

Additional context

I tried using the ignoreProperties option, but that only appears to consider spaces after the property name up to the ':'

dsl101 avatar Jan 09 '25 13:01 dsl101

It would be ideal if vue/no-multi-spaces were able to use the global setting and ignore comments in this case.

That is not possible; the rule only knows its own options.

Alternatively, could vue/no-multi-spaces support the same ignoreEOLComments option?

That would need to be implemented which is certainly possible. PR welcome :slightly_smiling_face:

FloEdelmann avatar Jan 10 '25 10:01 FloEdelmann

OK, I'm happy to take a stab at that. But looking at the innards of the existing rule, it doesn't look like it's trivial to detect comments at the end of the line. For example, this content:

<template>
  <div
    :class="{
      'is-good': isGood(thing)  // hopefully
    }"
  >
</template>

is parsed as the following sequence of tokens:

HTMLTagOpen: template
HTMLTagClose:
HTMLWhitespace:

HTMLTagOpen: div
Punctuator: :
HTMLIdentifier: class
HTMLAssociation:
Punctuator: "
Punctuator: {
String: 'is-good'
Punctuator: :
Identifier: isGood
Punctuator: (
Identifier: thing
Punctuator: )
Line:  hopefully            ← comment contents
Punctuator: }
Punctuator: "
HTMLTagClose:
HTMLWhitespace:

HTMLEndTagOpen: template
HTMLTagClose:

The comment is of type 'Line'. Similarly, if the template is:

<template>
  <div
    :class="{
      'is-good': isGood(thing)  /* hopefully */
    }"
  >
</template>

then the token containing the comment is of type 'Block'. It seems like ignoring spaces when a Line or Block is the last token on a line might have a lot of unintended side-effects. Any thoughts on that?

dsl101 avatar Jan 17 '25 17:01 dsl101