File tree 9 files changed +140
-0
lines changed
fixtures/rules/require-each-key
9 files changed +140
-0
lines changed Original file line number Diff line number Diff line change @@ -346,6 +346,7 @@ These rules relate to better ways of doing things to help you avoid problems:
346
346
| [ svelte/no-unused-svelte-ignore] ( https://sveltejs.github.io/eslint-plugin-svelte/rules/no-unused-svelte-ignore/ ) | disallow unused svelte-ignore comments | :star : |
347
347
| [ svelte/no-useless-mustaches] ( https://sveltejs.github.io/eslint-plugin-svelte/rules/no-useless-mustaches/ ) | disallow unnecessary mustache interpolations | :wrench : |
348
348
| [ svelte/prefer-destructured-store-props] ( https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-destructured-store-props/ ) | destructure values from object stores for better change tracking & fewer redraws | :bulb : |
349
+ | [ svelte/require-each-key] ( https://sveltejs.github.io/eslint-plugin-svelte/rules/require-each-key/ ) | require keyed ` {#each} ` block | |
349
350
| [ svelte/require-event-dispatcher-types] ( https://sveltejs.github.io/eslint-plugin-svelte/rules/require-event-dispatcher-types/ ) | require type parameters for ` createEventDispatcher ` | |
350
351
| [ svelte/require-optimized-style-attribute] ( https://sveltejs.github.io/eslint-plugin-svelte/rules/require-optimized-style-attribute/ ) | require style attributes that can be optimized | |
351
352
| [ svelte/require-stores-init] ( https://sveltejs.github.io/eslint-plugin-svelte/rules/require-stores-init/ ) | require initial value in store | |
Original file line number Diff line number Diff line change @@ -59,6 +59,7 @@ These rules relate to better ways of doing things to help you avoid problems:
59
59
| [ svelte/no-unused-svelte-ignore] ( ./rules/no-unused-svelte-ignore.md ) | disallow unused svelte-ignore comments | :star : |
60
60
| [ svelte/no-useless-mustaches] ( ./rules/no-useless-mustaches.md ) | disallow unnecessary mustache interpolations | :wrench : |
61
61
| [ svelte/prefer-destructured-store-props] ( ./rules/prefer-destructured-store-props.md ) | destructure values from object stores for better change tracking & fewer redraws | :bulb : |
62
+ | [ svelte/require-each-key] ( ./rules/require-each-key.md ) | require keyed ` {#each} ` block | |
62
63
| [ svelte/require-event-dispatcher-types] ( ./rules/require-event-dispatcher-types.md ) | require type parameters for ` createEventDispatcher ` | |
63
64
| [ svelte/require-optimized-style-attribute] ( ./rules/require-optimized-style-attribute.md ) | require style attributes that can be optimized | |
64
65
| [ svelte/require-stores-init] ( ./rules/require-stores-init.md ) | require initial value in store | |
Original file line number Diff line number Diff line change
1
+ ---
2
+ pageClass : " rule-details"
3
+ sidebarDepth : 0
4
+ title : " svelte/require-each-key"
5
+ description : " require keyed `{#each}` block"
6
+ ---
7
+
8
+ # svelte/require-each-key
9
+
10
+ > require keyed ` {#each} ` block
11
+
12
+ - :exclamation : <badge text =" This rule has not been released yet. " vertical =" middle " type =" error " > ** _ This rule has not been released yet._ ** </badge >
13
+
14
+ ## :book : Rule Details
15
+
16
+ This rule reports ` {#each} ` block without key
17
+
18
+ <ESLintCodeBlock >
19
+
20
+ <!-- eslint-skip-->
21
+
22
+ ``` svelte
23
+ <script>
24
+ /* eslint svelte/require-each-key: "error" */
25
+ </script>
26
+
27
+ <!-- ✓ GOOD -->
28
+ {#each things as thing (thing.id)}
29
+ <Thing name={thing.name} />
30
+ {/each}
31
+
32
+ <!-- ✗ BAD -->
33
+ {#each things as thing}
34
+ <Thing name={thing.name} />
35
+ {/each}
36
+ ```
37
+
38
+ </ESLintCodeBlock >
39
+
40
+ ## :wrench : Options
41
+
42
+ Nothing.
43
+
44
+ ## :books : Further Reading
45
+
46
+ - [ Svelte - Tutorial > 4. Logic / Keyed each blocks] ( https://svelte.dev/tutorial/keyed-each-blocks )
47
+
48
+ ## :mag : Implementation
49
+
50
+ - [ Rule source] ( https://github.com/sveltejs/eslint-plugin-svelte/blob/main/src/rules/require-each-key.ts )
51
+ - [ Test source] ( https://github.com/sveltejs/eslint-plugin-svelte/blob/main/tests/src/rules/require-each-key.ts )
Original file line number Diff line number Diff line change
1
+ import type { AST } from "svelte-eslint-parser"
2
+ import { createRule } from "../utils"
3
+
4
+ export default createRule ( "require-each-key" , {
5
+ meta : {
6
+ docs : {
7
+ description : "require keyed `{#each}` block" ,
8
+ category : "Best Practices" ,
9
+ recommended : false ,
10
+ } ,
11
+ schema : [ ] ,
12
+ messages : { expectedKey : "Each block should have a key" } ,
13
+ type : "suggestion" ,
14
+ } ,
15
+ create ( context ) {
16
+ return {
17
+ SvelteEachBlock ( node : AST . SvelteEachBlock ) {
18
+ if ( node . key == null ) {
19
+ context . report ( {
20
+ node,
21
+ messageId : "expectedKey" ,
22
+ } )
23
+ }
24
+ } ,
25
+ }
26
+ } ,
27
+ } )
Original file line number Diff line number Diff line change @@ -45,6 +45,7 @@ import noUselessMustaches from "../rules/no-useless-mustaches"
45
45
import preferClassDirective from "../rules/prefer-class-directive"
46
46
import preferDestructuredStoreProps from "../rules/prefer-destructured-store-props"
47
47
import preferStyleDirective from "../rules/prefer-style-directive"
48
+ import requireEachKey from "../rules/require-each-key"
48
49
import requireEventDispatcherTypes from "../rules/require-event-dispatcher-types"
49
50
import requireOptimizedStyleAttribute from "../rules/require-optimized-style-attribute"
50
51
import requireStoreCallbacksUseSetParam from "../rules/require-store-callbacks-use-set-param"
@@ -102,6 +103,7 @@ export const rules = [
102
103
preferClassDirective ,
103
104
preferDestructuredStoreProps ,
104
105
preferStyleDirective ,
106
+ requireEachKey ,
105
107
requireEventDispatcherTypes ,
106
108
requireOptimizedStyleAttribute ,
107
109
requireStoreCallbacksUseSetParam ,
Original file line number Diff line number Diff line change
1
+ - message : Each block should have a key
2
+ line : 19
3
+ column : 1
4
+ suggestions : null
Original file line number Diff line number Diff line change
1
+ <script >
2
+ import Thing from " ./Thing.svelte"
3
+
4
+ let things = [
5
+ { id: 1 , name: " apple" },
6
+ { id: 2 , name: " banana" },
7
+ { id: 3 , name: " carrot" },
8
+ { id: 4 , name: " doughnut" },
9
+ { id: 5 , name: " egg" },
10
+ ]
11
+
12
+ function handleClick () {
13
+ things = things .slice (1 )
14
+ }
15
+ </script >
16
+
17
+ <button on:click ={handleClick }> Remove first thing </button >
18
+
19
+ {#each things as thing }
20
+ <Thing name ={thing .name } />
21
+ {/each }
Original file line number Diff line number Diff line change
1
+ <script >
2
+ import Thing from " ./Thing.svelte"
3
+
4
+ let things = [
5
+ { id: 1 , name: " apple" },
6
+ { id: 2 , name: " banana" },
7
+ { id: 3 , name: " carrot" },
8
+ { id: 4 , name: " doughnut" },
9
+ { id: 5 , name: " egg" },
10
+ ]
11
+
12
+ function handleClick () {
13
+ things = things .slice (1 )
14
+ }
15
+ </script >
16
+
17
+ <button on:click ={handleClick }> Remove first thing </button >
18
+
19
+ {#each things as thing (thing .id )}
20
+ <Thing name ={thing .name } />
21
+ {/each }
Original file line number Diff line number Diff line change
1
+ import { RuleTester } from "eslint"
2
+ import rule from "../../../src/rules/require-each-key"
3
+ import { loadTestCases } from "../../utils/utils"
4
+
5
+ const tester = new RuleTester ( {
6
+ parserOptions : {
7
+ ecmaVersion : 2020 ,
8
+ sourceType : "module" ,
9
+ } ,
10
+ } )
11
+
12
+ tester . run ( "require-each-key" , rule as any , loadTestCases ( "require-each-key" ) )
You can’t perform that action at this time.
0 commit comments