Skip to content

noVueExposeAfterAwait (JavaScript)

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

Disallow calling expose() or defineExpose() after an await in setup().

expose() and defineExpose() choose which properties of a component a parent component can use through a template ref. Vue expects them to be called before the component’s setup code pauses at its first await. The setup code is the setup() function, or all the code in <script setup>. A call that comes after the pause runs too late, so the parent component might not receive the exposed properties.

This rule reports these calls when they come after an await:

  • expose() from the second parameter of setup(), written as setup(props, { expose }) or as setup(props, context) followed by context.expose().
  • defineExpose() in <script setup>.

An await inside a nested function doesn’t count, because it doesn’t pause the setup code.

<script>
export default {
async setup(props, { expose }) {
await fetchUser();
expose({ reload });
},
};
</script>
code-block.vue:5:5 lint/nursery/noVueExposeAfterAwait ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ This expose() call comes after an await, so it runs too late.

3 │ async setup(props, { expose }) {
4 │ await fetchUser();
> 5 │ expose({ reload });
│ ^^^^^^^^^^^^^^^^^^
6 │ },
7 │ };

ℹ The component's setup code pauses here. A parent component might not receive the exposed properties.

2 │ export default {
3 │ async setup(props, { expose }) {
> 4 │ await fetchUser();
│ ^^^^^
5 │ expose({ reload });
6 │ },

ℹ Call expose() before the first await.

ℹ 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>
await fetchUser();
defineExpose({ reload });
</script>
code-block.vue:3:1 lint/nursery/noVueExposeAfterAwait ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ This defineExpose() call comes after an await, so it runs too late.

1 │ <script setup>
2 │ await fetchUser();
> 3 │ defineExpose({ reload });
│ ^^^^^^^^^^^^^^^^^^^^^^^^
4 │ </script>
5 │

ℹ The component's setup code pauses here. A parent component might not receive the exposed properties.

1 │ <script setup>
> 2 │ await fetchUser();
│ ^^^^^
3 │ defineExpose({ reload });
4 │ </script>

ℹ Call defineExpose() before the first await.

ℹ 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>
export default {
async setup(props, { expose }) {
expose({ reload });
await fetchUser();
},
};
</script>
<script setup>
defineExpose({ reload });
await fetchUser();
</script>