Skip to content

[vue/valid-template-root] Incorrect detection of root element when using v-if/v-else directives #986

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ThibaultVlacich opened this issue Nov 11, 2019 · 13 comments

Comments

@ThibaultVlacich
Copy link

ThibaultVlacich commented Nov 11, 2019

Tell us about your environment

  • ESLint version: 6.6.0
  • eslint-plugin-vue version: 6.0.0
  • Node version: 13.0.1

Please show your full configuration:

module.exports = {
  root: true,
  env: {
    browser: true,
    node: true
  },
  parserOptions: {
    parser: 'babel-eslint'
  },
  extends: [
    '@nuxtjs',
    'prettier',
    'prettier/vue',
    'plugin:prettier/recommended',
    'plugin:nuxt/recommended'
  ],
  plugins: [
    'prettier'
  ],
  // add your custom rules here
  rules: {
    'vue/no-v-html': 'off'
  }
}

What did you do?

<template>
  <div
    v-if="status === 'LOADING'"
    class="d-flex justify-content-center loading"
  >
    Loading comments
    <span class="one">.</span>
    <span class="two">.</span>
    <span class="three">.</span>
  </div>

  <div v-else-if="status === 'LOADED'">
    <h4 class="comments-head">
      <font-awesome-icon :icon="['far', 'comments']" class="mx-2" />
      {{ `${commentsCount} comment${commentsCount > 1 ? 's' : ''}` }}
    </h4>

    <div v-for="comment in comments" :key="comment.id" class="comment">
      <div class="meta">
        <span class="author">{{ comment.author.username }}</span>
        on
        <time :datetime="comment.publishedAt" class="date">
          {{ comment.publishedAt | formatDate }}
        </time>
      </div>

      <div v-html="comment.content" class="content"></div>
    </div>
    <div v-if="comments.length === 0" class="no-comments text-center py-3">
      There are no comments.
    </div>

    <b-pagination
      v-if="comments.length > 0"
      v-model="page"
      :total-rows="commentsCount"
      :per-page="perPage"
      size="sm"
      align="center"
    ></b-pagination>

    <div v-if="$auth.loggedIn" class="add-comment">
      <b-form
        v-if="['WAITING', 'SENDING'].includes(newCommentStatus)"
        @submit.prevent.stop="addComment"
      >
        <h4 class="comments-head">
          Add a comment
        </h4>

        <classic-editor
          id="new-comment-body"
          v-model="newCommentContent"
          :config="{ toolbar: ['bold', 'italic'], readOnly: true }"
          :disabled="newCommentStatus === 'SENDING'"
        ></classic-editor>

        <div class="mt-3 d-flex justify-content-end">
          <b-button
            :disabled="
              newCommentStatus === 'SENDING' || newCommentContent.length === 0
            "
            variant="primary"
            type="submit"
          >
            <font-awesome-icon
              v-if="newCommentStatus === 'SENDING'"
              icon="spinner"
              spin
              class="mr-2"
            />
            Send
          </b-button>
        </div>
      </b-form>

      <b-alert :show="newCommentStatus === 'SENT'" variant="success">
        Your comment has been successfully added.
      </b-alert>
      <b-alert :show="newCommentStatus === 'ERROR'" variant="danger">
        {{ newCommentErrorMessage }}
      </b-alert>
    </div>
  </div>
</template>

What did you expect to happen?

This code does not trigger an error

What actually happened?

The vue/valid-template-root rule throws an error. This exact same code was working on ESLint 5 / eslint-plugin-nuxt 5.2.3, and I'm seeing nothing in the changelog that could explain why it's not working anymore.

components\poll\Comments.vue
12:3 error The template root requires exactly one element vue/valid-template-root

@ota-meshi
Copy link
Member

Thank you for this issue.

I checked your issue in the DEMO but could not reproduce it.
Also, I tried it on my local PC [email protected] but could not reproduce it.

Can you tell me the version of eslint-plugin-vue you are using?

eslint-plugin-vue version: 6.6.0

The latest version of current eslint-plugin-vue is 6.0.0.

@ThibaultVlacich
Copy link
Author

My bad, typo. I am indeed using [email protected], not 6.6.0.
Your demo link seems to be using [email protected], which does not raise any error as expected.

The issue is present only on the 6.0.0 version. I have the issue both on my local PC, and my CI integration.

@ota-meshi
Copy link
Member

Thank you for telling me which version you are using.

The eslint-plugin-nuxt version may be affected.
If you use eslint-plugin-nuxt version 0.4.3 or earlier with [email protected], the vue-eslint-parser version not match, which may cause issues.
What version of eslint-plugin-nuxt are you using?

@ThibaultVlacich
Copy link
Author

[email protected], but I think @nuxtjs/eslint-config has not been updated yet.
I'll wait for this package to be updated and see if issue it still present.

@ota-meshi
Copy link
Member

If you have a problem with the version of vue-eslint-parser, you may be able to solve the problem by:

  • Install vue-eslint-parser explicitly.
npm install -D vue-eslint-parser@^6.0.5
  • Specify vue-eslint-parser clearly in eslintrc.js.
+  parser: require.resolve('vue-eslint-parser'),

Can you try this?

@Miaoxingren
Copy link

Same problem here. Please look at this repo: https://github.com/Miaoxingren/test-nuxt-eslint. Downgrade eslint-plugin-nuxt to @0.4.3 solved the problem.

@ota-meshi
Copy link
Member

Hi @Miaoxingren
I checked package-lock.json which reproduced the phenomenon. There seems to be a problem with the dependency of @nuxtjs/eslint-config.
It seems that the version of eslint-plugin-vue and vue-eslint-parser is in conflicts because of the dependency of @nuxtjs/eslint-config.

@ThibaultVlacich
Copy link
Author

If you have a problem with the version of vue-eslint-parser, you may be able to solve the problem by:

* Install `vue-eslint-parser` explicitly.
npm install -D vue-eslint-parser@^6.0.5
* Specify `vue-eslint-parser` clearly in eslintrc.js.
+  parser: require.resolve('vue-eslint-parser'),

Can you try this?

No success.

@ota-meshi
Copy link
Member

@ThibaultVlacich
I still don't know the cause of this issue.
If you can, please tell me your repository where this issue can be reproduced.

@ThibaultVlacich
Copy link
Author

I made a simple repro project that showcase the issue: https://github.com/ThibaultVlacich/valid-template-root-eslint-6

The master branch is update to ESLint 6, and the issue is present. There is also an eslint-5 branch, to show that it was working without any problem before.

@ota-meshi
Copy link
Member

Thank you for telling me your repository.

I checked the node_modules in your repository.
In node_modules, [email protected] and [email protected] were actually used.

[email protected] and [email protected] are not compatible.
I think you can avoid this problem by installing [email protected].

@ThibaultVlacich
Copy link
Author

I've been able to temporarily fix my issue by adding this to my package.json (using Yarn), until https://github.com/nuxt/eslint-config is updated :

"resolutions": {
  "@nuxtjs/eslint-config/eslint-plugin-vue": "^6.0.1"
}

@ota-meshi
Copy link
Member

I close this isssue because I found that the dependency of @nuxtjs/eslint-config was the cause.
Keep track of the nuxt/eslint#69.

wmfgerrit pushed a commit to wikimedia/mediawiki-extensions-Wikibase that referenced this issue Feb 6, 2020
This should fix all medium-and-above severity security issues reported
by npm audit. The only remaining issue that cannot be fixed by running
`npm upgrade` or `npm audit fix` will be fixed in a follow-up commit.

The rule to enforce a single root in vue templates seems to be a bit
overzealous. This has already been reported upstream in
vuejs/eslint-plugin-vue#971 and was also discussed in
vuejs/eslint-plugin-vue#884 and vuejs/eslint-plugin-vue#986 without
obvious solution that would be applicable here. Solved by adding a not
strictly necessary wrapping span.

Change-Id: I3153c0f45ce53704ef2c02d7e2e2e4f6d67e3fc7
wmfgerrit pushed a commit to wikimedia/mediawiki-extensions that referenced this issue Feb 6, 2020
* Update Wikibase from branch 'master'
  to e7ada5fde5f187fef50badd632676363f322691f
  - Merge "bridge: Upgrade dependencies"
  - bridge: Upgrade dependencies
    
    This should fix all medium-and-above severity security issues reported
    by npm audit. The only remaining issue that cannot be fixed by running
    `npm upgrade` or `npm audit fix` will be fixed in a follow-up commit.
    
    The rule to enforce a single root in vue templates seems to be a bit
    overzealous. This has already been reported upstream in
    vuejs/eslint-plugin-vue#971 and was also discussed in
    vuejs/eslint-plugin-vue#884 and vuejs/eslint-plugin-vue#986 without
    obvious solution that would be applicable here. Solved by adding a not
    strictly necessary wrapping span.
    
    Change-Id: I3153c0f45ce53704ef2c02d7e2e2e4f6d67e3fc7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants