vuejs/eslint-plugin-vue

Add support for unknown macro in `vue/define-macros-order`

Closed this issue · 7 comments

What rule do you want to change?
vue/define-macros-order

Does this change cause the rule to produce more or fewer warnings?
More

How will the change be implemented? (New option, new default behavior, etc.)?
New default behavior

Please provide some example code that this change will affect:

<script setup>
import { useBreakpoints } from '@vueuse/core';
import { useRoute } from 'vue-router';

+defineProps({
+    data: {
+        type: Array,
+        default: () => [],
+    },
+});

const { t } = useI18n();
const { formatSessionTime } = useTimeFormatter();

const route = useRoute();
const breakpoints = useBreakpoints({ lg: 1024 }, { ssrWidth: 1024 });
const showPlace = breakpoints.smaller('lg');
const day = route.params.day;

definePageMeta({
    scrollToTop: false,
});

-defineProps({
-    data: {
-        type: Array,
-        default: () => [],
-    },
-});

defineI18nRoute({
    paths: {
        fr: '/programmation/[day]',
    },
});
</script>

What does the rule currently do for this code?
Currently, only defineProps would be marked as error and not definePageMeta, defineI18nRoute.

What will the rule do after it's changed?
Although we can't specifically sort unknown macro, since all macro are starting with define..., we can easily sort them at the top in the order they are already defined in the code.
So I think the default should be changed from:

{
  "vue/define-macros-order": ["error", {
    "order": ["defineProps", "defineEmits"],
    "defineExposeLast": false
  }]

to something like this:

{
  "vue/define-macros-order": ["error", {
    "order": ["defineProps", "defineEmits", "unknowns"],
    "defineExposeLast": false
  }]

which would result in this code change:

<script setup>
import { useBreakpoints } from '@vueuse/core';
import { useRoute } from 'vue-router';

+defineProps({
+    data: {
+        type: Array,
+        default: () => [],
+    },
+});

+definePageMeta({
+    scrollToTop: false,
+});

+defineI18nRoute({
+    paths: {
+        fr: '/programmation/[day]',
+    },
+});

const { t } = useI18n();
const { formatSessionTime } = useTimeFormatter();

const route = useRoute();
const breakpoints = useBreakpoints({ lg: 1024 }, { ssrWidth: 1024 });
const showPlace = breakpoints.smaller('lg');
const day = route.params.day;

-definePageMeta({
-    scrollToTop: false,
-});

-defineProps({
-    data: {
-        type: Array,
-        default: () => [],
-    },
-});

-defineI18nRoute({
-    paths: {
-        fr: '/programmation/[day]',
-    },
-});
</script>

Additional context

This plugin does not know the names of custom macros, so it cannot determine that definePageMeta or defineI18nRoute are macros.

If you want to enforce the order of custom macros, define them as follows.

{
  "vue/define-macros-order": ["error", {
    "order": ["defineProps", "defineEmits", "definePageMeta", "defineI18nRoute"],
    "defineExposeLast": false
  }]
}

https://eslint.vuejs.org/rules/define-macros-order.html

All macro start with define... so why wouldn't it be able to infer them ?

Because some people might write functions called define… that are not macros and thus should not be reordered. Also the exact ordering has to be defined somewhere.

@FloEdelmann Thats why you would need to add unknowns to the array, and the order would stay the same as define in the code, but they would be moved to the top

I don't see how adding "unknowns" instead of e.g. "definePageMeta", "defineI18nRoute" would be an advantage. It makes it less clear what happens, is less flexible (you could want to sort definePageMeta before defineProps but defineI18nRoute after it) and less greppable. And as I said, putting unknowns in the default sort order might lead to false positives for functions called define… that are not macros.

@FloEdelmann We don't have to include it in the default, what's wrong with giving people more option ? I don't care about the macro order, but I care that they are all at the top. Forcing me to hardcode the order in every projects feels useless. Both could be easily supported

what's wrong with giving people more option

It's a new option that needs to be implemented and maintained. We need to weigh that effort against its potential usage. And our opinion is that the effort is not worth it. If more people disagree, then that opinion might change.

Forcing me to hardcode the order in every projects feels useless.

But you'd still need to configure the rule to add "unknowns" in the rule order, so the copy/paste effort of specifying "definePageMeta", "defineI18nRoute" instead is not that much greater.