Skip to content

useVueValidDefineOptions (JavaScript)

Language JavaScript (and super languages)
biome.json
{
"linter": {
"rules": {
"nursery": {
"useVueValidDefineOptions": "error"
}
}
}
}

Enforce valid usage of Vue’s defineOptions() macro.

In <script setup>, defineOptions() sets component options, such as the component’s name or inheritAttrs. Vue reads the call when it compiles the component, so the call must follow these rules:

  • It is called at most once.
  • It receives the options as an argument.
  • It doesn’t receive type arguments, such as defineOptions<{ name: "Foo" }>().
  • It doesn’t declare props, emits, expose, or slots. <script setup> has dedicated macros for these: defineProps(), defineEmits(), defineExpose(), and defineSlots().
  • It doesn’t use variables or functions declared in <script setup>. Vue moves the options out of <script setup> when it compiles the component, so these declarations aren’t available to them. Imports, and constants whose value is a string, number, or other literal value, can be used.

Breaking one of these rules makes the Vue compiler report an error, or makes the call have no effect.

<script setup>
const options = { name: "Foo" };
defineOptions(options);
</script>
code-block.vue:3:15 lint/nursery/useVueValidDefineOptions ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ defineOptions() uses options, which is declared in <script setup>.

1 │ <script setup>
2 │ const options = { name: "Foo" };
> 3 │ defineOptions(options);
│ ^^^^^^^
4 │ </script>
5 │

ℹ options is declared here.

1 │ <script setup>
> 2 │ const options = { name: "Foo" };
│ ^^^^^^^
3 │ defineOptions(options);
4 │ </script>

ℹ Vue moves the options out of <script setup> when it compiles the component, so variables declared there aren't available to them.

ℹ Move the declaration to a separate <script> block, or import it from another file.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup>
defineOptions({ name: "Foo" });
defineOptions({ inheritAttrs: false });
</script>
code-block.vue:3:1 lint/nursery/useVueValidDefineOptions ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ defineOptions() is called more than once.

1 │ <script setup>
2 │ defineOptions({ name: "Foo" });
> 3 │ defineOptions({ inheritAttrs: false });
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 │ </script>
5 │

ℹ It is first called here.

1 │ <script setup>
> 2 │ defineOptions({ name: "Foo" });
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3 │ defineOptions({ inheritAttrs: false });
4 │ </script>

ℹ Vue accepts only one defineOptions() call per component, and reports an error when it compiles this one.

ℹ Move these options into the first call.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup>
defineOptions();
</script>
code-block.vue:2:1 lint/nursery/useVueValidDefineOptions ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ defineOptions() is called without options.

1 │ <script setup>
> 2 │ defineOptions();
│ ^^^^^^^^^^^^^^^
3 │ </script>
4 │

ℹ Without options, the call doesn't change the component.

ℹ Pass an object with the component options, or remove the call.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup lang="ts">
defineOptions<{ name: "Foo" }>({});
</script>
code-block.vue:2:14 lint/nursery/useVueValidDefineOptions ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ defineOptions() doesn't accept type arguments.

1 │ <script setup lang="ts">
> 2 │ defineOptions<{ name: "Foo" }>({});
│ ^^^^^^^^^^^^^^^^^
3 │ </script>
4 │

ℹ Vue reads the options only from the object passed in parentheses, and reports an error when it compiles a call with type arguments.

ℹ Remove the type arguments, and pass the options as an object.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup>
defineOptions({ props: { msg: String } });
</script>
code-block.vue:2:17 lint/nursery/useVueValidDefineOptions ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ defineOptions() can't declare props.

1 │ <script setup>
> 2 │ defineOptions({ props: { msg: String } });
│ ^^^^^^^^^^^^^^^^^^^^^^
3 │ </script>
4 │

ℹ Vue reports an error when it compiles this option, because <script setup> has a dedicated macro for it.

ℹ Declare props with defineProps() instead.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup>
import { componentName } from "./names";
const inheritAttrs = false;
defineOptions({ name: componentName, inheritAttrs });
defineProps({ msg: String });
</script>