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

Feature: Add support for Vue order in components rules

Open alexkiro opened this issue 1 year ago • 1 comments

What rule do you want to change?

sort-objects

Describe the problem

Currently the sort-objects rule is incompatible with the order-in-components.

It would be nice if these two could be used together somehow. As far as I can tell there is no way of making them compatible as is.

Code example

<template>
  <foo-bar></foo-bar>
</template>

<script lang="ts">
import FooBar from "@/components/FooBar.vue";

export default {
  name: "HomeView",
  components: { FooBar },
};
</script>

perfectionist/sort-objects would like to put components first, but vue/order-in-components would like to put name first since it has it's custom hardcoded order.

Additional comments

I tried using ignore-pattern but it doesn't seem to work. Presumably since there is no variable identifier available, so presumably it just skips checking for null names such as this.

Validations

  • [X] Read the docs.
  • [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.

alexkiro avatar Mar 09 '24 15:03 alexkiro

Currently I'm using something like this:

    'perfectionist/sort-vue-attributes': [
      'error',
      {
        // Based on: https://vuejs.org/style-guide/rules-recommended.html#element-attribute-order
        'custom-groups': {
          /* eslint-disable perfectionist/sort-objects */
          DEFINITION: 'is',
          LIST_RENDERING: 'v-for',
          CONDITIONALS: 'v-*(else-if|if|else|show|cloak)',
          RENDER_MODIFIERS: 'v-*(pre|once)',
          GLOBAL: 'id',
          UNIQUE: '*(ref|key)',
          SLOT: '*(v-slot|slot)',
          TWO_WAY_BINDING: 'v-model',
          EVENTS: '*(v-on|@*)',
          CONTENT: 'v-*(html|text)',
          /* eslint-enable perfectionist/sort-objects */
        },
        groups: [
          'DEFINITION',
          'LIST_RENDERING',
          'CONDITIONALS',
          'RENDER_MODIFIERS',
          'GLOBAL',
          'UNIQUE',
          'SLOT',
          'TWO_WAY_BINDING',
          'unknown',
          'EVENTS',
          'CONTENT',
        ],
        type: 'natural',
      },
    ],

Tragio avatar Mar 12 '24 17:03 Tragio

Currently I'm using something like this:

    'perfectionist/sort-vue-attributes': [
      'error',
      {
        // Based on: https://vuejs.org/style-guide/rules-recommended.html#element-attribute-order
        'custom-groups': {
          /* eslint-disable perfectionist/sort-objects */
          DEFINITION: 'is',
          LIST_RENDERING: 'v-for',
          CONDITIONALS: 'v-*(else-if|if|else|show|cloak)',
          RENDER_MODIFIERS: 'v-*(pre|once)',
          GLOBAL: 'id',
          UNIQUE: '*(ref|key)',
          SLOT: '*(v-slot|slot)',
          TWO_WAY_BINDING: 'v-model',
          EVENTS: '*(v-on|@*)',
          CONTENT: 'v-*(html|text)',
          /* eslint-enable perfectionist/sort-objects */
        },
        groups: [
          'DEFINITION',
          'LIST_RENDERING',
          'CONDITIONALS',
          'RENDER_MODIFIERS',
          'GLOBAL',
          'UNIQUE',
          'SLOT',
          'TWO_WAY_BINDING',
          'unknown',
          'EVENTS',
          'CONTENT',
        ],
        type: 'natural',
      },
    ],

Thank you for this, just what I was looking for.

Although I feel it would be better to have this as the default setting, or at least an easy option to turn on via the groups option like so:

  "rules": {
    "perfectionist/sort-vue-attributes": [
      "error",
      {
        "groups": ["vue-order"]
      }
    ]
  }

BenJackGill avatar Jun 06 '24 05:06 BenJackGill

I was having issues with the other groups. It seems the style guide docs are not as correct as the eslint-plugin-vue docs.

I will try to come back and edit this as I find more edge cases, so you can assume it is the most correct and update to date version.

Here is my current version:

"perfectionist/sort-vue-attributes": [
      "error",
      {
        // Based on: https://eslint.vuejs.org/rules/attributes-order.html
        // Note: I think this matches on attribute strings for everything that comes BEFORE the equal sign (=), if there is one. This makes some things impossible to match.
        // See issue: https://github.com/azat-io/eslint-plugin-perfectionist/issues/112
        // See guide on extended glob matching: https://www.linuxjournal.com/content/bash-extended-globbing
        "custom-groups": {
          /* eslint-disable perfectionist/sort-objects */
          DEFINITION: "@(is|v-is)",
          LIST_RENDERING: "v-for",
          CONDITIONALS: "v-@(if|else-if|else|show|cloak)",
          RENDER_MODIFIERS: "v-@(pre|once)",
          GLOBAL: "@(id|:id)",
          UNIQUE: "@(ref|:ref|key|:key)",
          SLOT: "@(v-slot|slot|#*)",
          TWO_WAY_BINDING: "@(v-model|v-model:*)",
          OTHER_DIRECTIVES: "@(v-!(on|bind|html|text))", // Matches all "v-" directives except v-on, v-bind, v-html, v-text (these are defined separately below, which are lower in the order of operations)
          ATTR_DYNAMIC: "@(v-bind:*|:*)", // For dynamic bindings, like v-bind:prop or :prop.
          // ATTR_STATIC: "", // For normal props, like prop="example". No glob patterns possible since we are matching on everything BEFORE the equal sign (=), if there is one. Therefore we can't differentiate boolean props from static props.
          // ATTR_SHORTHAND_BOOL: "", // For boolean props, like custom-prop. No glob patterns possible since we are matching on everything BEFORE the equal sign (=), if there is one. Therefore we can't differentiate boolean props from static props.
          EVENTS: "@(v-on|@*)",
          CONTENT: "v-@(html|text)",
          /* eslint-enable perfectionist/sort-objects */
        },
        groups: [
          "DEFINITION",
          "LIST_RENDERING",
          "CONDITIONALS",
          "RENDER_MODIFIERS",
          "GLOBAL",
          ["UNIQUE", "SLOT"],
          "TWO_WAY_BINDING",
          "OTHER_DIRECTIVES",
          ["ATTR_DYNAMIC", "unknown"], // 'unknown' is a workaround because perfectionist/sort-vue-attributes cannot match on ATTR_STATIC or ATTR_SHORTHAND_BOOL
          "EVENTS",
          "CONTENT",
        ],
        type: "natural",
      },
    ],

BenJackGill avatar Jun 14 '24 06:06 BenJackGill

Thank you for your issue!

I think this problem can be easily solved by creating custom groups.

azat-io avatar Jul 22 '24 12:07 azat-io