|
1 | 1 | # vue-modular/sfc-order |
2 | 2 |
|
3 | | -Require a conventional order for Single File Component (SFC) blocks when those blocks exist. |
| 3 | +Enforce a conventional order for Single File Component (SFC) blocks. |
4 | 4 |
|
5 | | -This rule parses `.vue` files using `@vue/compiler-sfc` and validates the relative order of blocks that are present in the file. Missing blocks are allowed — only the relative order among present blocks is checked. |
| 5 | +This rule parses Vue component files using `@vue/compiler-sfc` and validates the relative order of SFC blocks (`<script>`, `<template>`, `<style>`). The rule only enforces order among blocks that are present — missing blocks are allowed. |
6 | 6 |
|
7 | | -By default the recommended order is: |
| 7 | +Default order: |
8 | 8 |
|
9 | 9 | 1. `<script>` / `<script setup>` |
10 | 10 | 2. `<template>` |
11 | 11 | 3. `<style>` (one or more) |
12 | 12 |
|
13 | 13 | ## Rule Details |
14 | 14 |
|
15 | | -- The rule runs only for on-disk `.vue` files under the configured `src` segment (default: `src`). |
16 | | -- Virtual inputs (filenames starting with `<...>`) and files matched by the `ignore` option are skipped. |
17 | | -- The rule computes the actual block order from the SFC descriptor and validates that the sequence of present blocks respects the relative order defined by the `order` option (or the default order). |
18 | | -- This rule intentionally does not report missing blocks — use `vue-modular/sfc-required` to enforce presence of `<template>`/`<script>`. |
| 15 | +- **Component detection**: Only runs on `.vue` files located in the configured components folder. Files outside component folders are ignored. |
| 16 | +- **SFC parsing**: Uses `@vue/compiler-sfc` to parse the Vue file and extract block positions. |
| 17 | +- **Order validation**: Checks that present blocks follow the configured relative order. Missing blocks are allowed. |
| 18 | +- **Early exit**: If a component has neither `<template>` nor `<script>` blocks, the rule skips validation (no meaningful content to order). |
19 | 19 |
|
20 | 20 | ## Options |
21 | 21 |
|
22 | 22 | The rule accepts a single options object: |
23 | 23 |
|
24 | | -- `src` (string, default: `"src"`) — path segment used to identify the repository source area where the rule should run. |
25 | | -- `ignore` (string[], default: `[]`) — minimatch-style patterns to ignore files or folders. |
26 | | -- `order` (string[], default: `['script','template','style']`) — the desired relative block ordering. Allowed values are `"script"`, `"template"`, and `"style"`. Missing blocks are permitted. |
| 24 | +- `order` (string[], default: `["script", "template", "style"]`) — desired relative block ordering. Allowed values: `"script"`, `"template"`, `"style"` |
| 25 | +- `ignores` (string[], default: `[""]`) — minimatch-style patterns to exclude specific files |
| 26 | + |
| 27 | +### Project Configuration |
| 28 | + |
| 29 | +The rule uses project-wide settings from your ESLint configuration's `settings['vue-modular']`: |
| 30 | + |
| 31 | +- `componentsFolderName` (string, default: `"components"`) — name of the folder that contains components |
| 32 | +- `rootPath` (string, default: `"src"`) — root path of the project |
| 33 | +- `rootAlias` (string, default: `"@"`) — alias for the root path |
27 | 34 |
|
28 | 35 | ### Example configuration |
29 | 36 |
|
30 | 37 | ```js |
| 38 | +// ESLint config |
31 | 39 | { |
32 | | - "vue-modular/sfc-order": ["error", { "src": "src", "ignore": [], "order": ["script", "template", "style"] }] |
| 40 | + "settings": { |
| 41 | + "vue-modular": { |
| 42 | + "componentsFolderName": "components", |
| 43 | + "rootPath": "src", |
| 44 | + "rootAlias": "@" |
| 45 | + } |
| 46 | + }, |
| 47 | + "rules": { |
| 48 | + "vue-modular/sfc-order": ["error", { |
| 49 | + "order": ["script", "template", "style"], |
| 50 | + "ignores": [] |
| 51 | + }] |
| 52 | + } |
33 | 53 | } |
34 | 54 | ``` |
35 | 55 |
|
36 | 56 | ## Incorrect |
37 | 57 |
|
38 | 58 | ```vue |
| 59 | +<!-- Wrong order: template before script --> |
39 | 60 | <template> |
40 | | - <div /> |
| 61 | + <div>Hello</div> |
41 | 62 | </template> |
42 | | -<script> |
43 | | -export default {} |
| 63 | +<script setup> |
| 64 | +const message = 'Hello' |
| 65 | +</script> |
| 66 | +``` |
| 67 | + |
| 68 | +```vue |
| 69 | +<!-- Wrong order: style before template --> |
| 70 | +<script setup> |
| 71 | +const message = 'Hello' |
44 | 72 | </script> |
| 73 | +<style> |
| 74 | +.hello { |
| 75 | + color: blue; |
| 76 | +} |
| 77 | +</style> |
| 78 | +<template> |
| 79 | + <div>Hello</div> |
| 80 | +</template> |
45 | 81 | ``` |
46 | 82 |
|
47 | 83 | ## Correct |
48 | 84 |
|
49 | 85 | ```vue |
| 86 | +<!-- Correct order: script, template, style --> |
50 | 87 | <script setup> |
51 | | -const a = 1 |
| 88 | +const message = 'Hello' |
52 | 89 | </script> |
53 | 90 | <template> |
54 | | - <div /> |
| 91 | + <div>{{ message }}</div> |
55 | 92 | </template> |
56 | 93 | <style> |
57 | | -/* css */ |
| 94 | +.hello { |
| 95 | + color: blue; |
| 96 | +} |
| 97 | +</style> |
| 98 | +``` |
| 99 | + |
| 100 | +```vue |
| 101 | +<!-- Missing blocks are allowed --> |
| 102 | +<script setup> |
| 103 | +// Script-only component |
| 104 | +export function useUtils() {} |
| 105 | +</script> |
| 106 | +``` |
| 107 | + |
| 108 | +```vue |
| 109 | +<!-- Custom order example --> |
| 110 | +<style> |
| 111 | +/* Custom order: style first */ |
| 112 | +.component { |
| 113 | + display: block; |
| 114 | +} |
58 | 115 | </style> |
| 116 | +<script setup> |
| 117 | +const props = defineProps({}) |
| 118 | +</script> |
| 119 | +<template> |
| 120 | + <div class="component">Content</div> |
| 121 | +</template> |
59 | 122 | ``` |
60 | 123 |
|
61 | 124 | ## Usage Notes |
62 | 125 |
|
63 | | -- The rule uses `@vue/compiler-sfc` to parse SFCs, so `<script setup>` and other modern SFC syntax are handled correctly. |
64 | | -- The rule checks order only; it does not assert the presence of template/script blocks. Use `vue-modular/sfc-required` to require those blocks. |
65 | | -- The `ignore` option accepts minimatch patterns — match feature folder names (for example `"**/legacy/**"`) to skip legacy areas. |
| 126 | +- The rule uses `@vue/compiler-sfc` to parse Vue files reliably, supporting `<script setup>` and other modern SFC syntax. |
| 127 | +- Only files identified as components (`.vue` files in the components folder) are checked. |
| 128 | +- Both `<script>` and `<script setup>` blocks are treated as `"script"` type for ordering purposes. |
| 129 | +- Multiple `<style>` blocks are allowed and treated as individual `"style"` blocks. |
| 130 | +- Files with only style blocks (no template or script) are skipped entirely. |
| 131 | +- Files can be excluded using the `ignores` option with minimatch patterns. |
| 132 | + |
| 133 | +## When Not To Use |
| 134 | + |
| 135 | +- Disable this rule if your project doesn't follow consistent SFC block ordering conventions. |
| 136 | +- Use the `ignores` option to exclude specific files or patterns rather than disabling the rule entirely. |
0 commit comments