@vueland/eslint-script-setup
v0.1.1
Published
ESLint plugin for Vue 3 script setup code style
Downloads
169
Readme
Enforces a consistent order of declarations inside <script setup> blocks and provides autofix.
Default order: import → type → macros → composable → reactive → variable → computed → function → watchEffect → watch → lifecycle
Installation
# pnpm
pnpm add -D @vueland/eslint-script-setup
# npm
npm install -D @vueland/eslint-script-setup
# yarn
yarn add -D @vueland/eslint-script-setupRequires ESLint >=9.0.0 (flat config) and vue-eslint-parser.
Setup
// eslint.config.mjs
import vueScriptSetup from '@vueland/eslint-script-setup'
import vueParser from 'vue-eslint-parser'
import tsParser from '@typescript-eslint/parser'
export default [
{
files: ['**/*.vue'],
languageOptions: {
parser: vueParser,
parserOptions: { parser: tsParser },
},
plugins: { '@vueland': vueScriptSetup },
rules: {
'@vueland/script-setup-order': 'warn',
'@vueland/no-multi-declaration': 'error',
'@vueland/no-inline-composable': 'error',
},
},
]Or use the recommended preset:
import vueScriptSetup from '@vueland/eslint-script-setup'
export default [
vueScriptSetup.configs.recommended,
]Rules
script-setup-order
Enforces declaration order inside <script setup>. Provides autofix — runs a single eslint --fix to sort the entire block.
<script setup lang="ts">
// ✓ correct order
import { ref, computed } from 'vue'
type Status = 'idle' | 'done'
const props = defineProps<{ label: string }>()
const router = useRouter()
const count = ref(0)
const MAX = 100
const double = computed(() => count.value * 2)
function increment() { count.value++ }
watchEffect(() => { /* ... */ })
watch(count, () => { /* ... */ })
onMounted(() => { /* ... */ })
</script>Options:
'@vueland/script-setup-order': ['warn', {
// Override the full order (all categories you want enforced must be listed)
order: ['import', 'type', 'macros', 'composable', 'reactive', 'variable',
'computed', 'function', 'watchEffect', 'watch', 'lifecycle'],
// Regex pattern to detect composables (default: /^use[A-Z]/)
composablePattern: '^use[A-Z]',
// Extra APIs appended to each built-in category set
reactiveApis: ['customRef'],
computedApis: ['asyncComputed'],
watchEffectApis: ['watchDebounced'],
watchApis: ['watchThrottled'],
lifecycleApis: ['onIdle'],
}]Dependency conflict handling:
If reordering would place a const before the value it depends on, the rule reports a depConflict instead of applying a broken fix. When the conflicting declaration is an arrow function (e.g. const useFoo = () => {}), the rule automatically converts it to a function declaration (which is hoisted) and sorts the block.
no-multi-declaration
Forbids multiple declarators in a single const/let statement.
// ✗
const a = ref(1), b = ref(2)
// ✓
const a = ref(1)
const b = ref(2)no-inline-composable
Forbids calling a composable inline as a function argument.
// ✗
doSomething(useRouter())
// ✓
const router = useRouter()
doSomething(router)Part of the Vueland platform
@vueland/ui— UI component library@vueland/utils-jit— JIT utility class generation for Vite
⭐ Support the project
License
MIT
