Skip to content

Commit f4a0fa7

Browse files
authored
feat: added the no-useless-children-snippet rule (#922)
1 parent b384d57 commit f4a0fa7

16 files changed

+145
-0
lines changed

.changeset/loud-zoos-kiss.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'eslint-plugin-svelte': minor
3+
---
4+
5+
feat: added the no-useless-children-snippet rule

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ These rules relate to better ways of doing things to help you avoid problems:
366366
| [svelte/no-svelte-internal](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-svelte-internal/) | svelte/internal will be removed in Svelte 6. | |
367367
| [svelte/no-unused-class-name](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-unused-class-name/) | disallow the use of a class in the template without a corresponding style | |
368368
| [svelte/no-unused-svelte-ignore](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-unused-svelte-ignore/) | disallow unused svelte-ignore comments | :star: |
369+
| [svelte/no-useless-children-snippet](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-useless-children-snippet/) | disallow explicit children snippet where it's not needed | |
369370
| [svelte/no-useless-mustaches](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-useless-mustaches/) | disallow unnecessary mustache interpolations | :wrench: |
370371
| [svelte/prefer-const](https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-const/) | Require `const` declarations for variables that are never reassigned after declared | :wrench: |
371372
| [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: |

docs/rules.md

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ These rules relate to better ways of doing things to help you avoid problems:
6363
| [svelte/no-svelte-internal](./rules/no-svelte-internal.md) | svelte/internal will be removed in Svelte 6. | |
6464
| [svelte/no-unused-class-name](./rules/no-unused-class-name.md) | disallow the use of a class in the template without a corresponding style | |
6565
| [svelte/no-unused-svelte-ignore](./rules/no-unused-svelte-ignore.md) | disallow unused svelte-ignore comments | :star: |
66+
| [svelte/no-useless-children-snippet](./rules/no-useless-children-snippet.md) | disallow explicit children snippet where it's not needed | |
6667
| [svelte/no-useless-mustaches](./rules/no-useless-mustaches.md) | disallow unnecessary mustache interpolations | :wrench: |
6768
| [svelte/prefer-const](./rules/prefer-const.md) | Require `const` declarations for variables that are never reassigned after declared | :wrench: |
6869
| [svelte/prefer-destructured-store-props](./rules/prefer-destructured-store-props.md) | destructure values from object stores for better change tracking & fewer redraws | :bulb: |
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
pageClass: 'rule-details'
3+
sidebarDepth: 0
4+
title: 'svelte/no-useless-children-snippet'
5+
description: "disallow explicit children snippet where it's not needed"
6+
---
7+
8+
# svelte/no-useless-children-snippet
9+
10+
> disallow explicit children snippet where it's not needed
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+
Any content inside component tags that is not a snippet declaration implicitly becomes part of the children snippet. Thus, declaring the children snippet explicitly is only necessary when the snippet has parameters.
17+
18+
<!--eslint-skip-->
19+
20+
```svelte
21+
<script>
22+
/* eslint svelte/no-useless-children-snippet: "error" */
23+
24+
import { Foo } from './Foo.svelte';
25+
</script>
26+
27+
<!-- ✓ GOOD -->
28+
<Foo>
29+
{#snippet bar()}
30+
Hello
31+
{/snippet}
32+
</Foo>
33+
34+
<Foo>
35+
{#snippet children(val)}
36+
Hello {val}
37+
{/snippet}
38+
</Foo>
39+
40+
<Foo>Hello</Foo>
41+
42+
<!-- ✗ BAD -->
43+
<Foo>
44+
{#snippet children()}
45+
Hello
46+
{/snippet}
47+
</Foo>
48+
```
49+
50+
## :wrench: Options
51+
52+
Nothing.
53+
54+
## :mag: Implementation
55+
56+
- [Rule source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/src/rules/no-useless-children-snippet.ts)
57+
- [Test source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/tests/src/rules/no-useless-children-snippet.ts)

packages/eslint-plugin-svelte/src/rule-types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ export interface RuleOptions {
260260
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-unused-svelte-ignore/
261261
*/
262262
'svelte/no-unused-svelte-ignore'?: Linter.RuleEntry<[]>
263+
/**
264+
* disallow explicit children snippet where it's not needed
265+
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-useless-children-snippet/
266+
*/
267+
'svelte/no-useless-children-snippet'?: Linter.RuleEntry<[]>
263268
/**
264269
* disallow unnecessary mustache interpolations
265270
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-useless-mustaches/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { createRule } from '../utils/index.js';
2+
3+
export default createRule('no-useless-children-snippet', {
4+
meta: {
5+
docs: {
6+
description: "disallow explicit children snippet where it's not needed",
7+
category: 'Best Practices',
8+
recommended: false
9+
},
10+
schema: [],
11+
messages: {
12+
uselessSnippet: 'Found an unnecessary children snippet.'
13+
},
14+
type: 'suggestion'
15+
},
16+
create(context) {
17+
return {
18+
SvelteSnippetBlock(node) {
19+
if (
20+
node.parent.type === 'SvelteElement' &&
21+
node.id.name === 'children' &&
22+
node.params.length === 0
23+
) {
24+
context.report({ node, messageId: 'uselessSnippet' });
25+
}
26+
}
27+
};
28+
}
29+
});

packages/eslint-plugin-svelte/src/utils/rules.ts

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import noTrailingSpaces from '../rules/no-trailing-spaces.js';
5151
import noUnknownStyleDirectiveProperty from '../rules/no-unknown-style-directive-property.js';
5252
import noUnusedClassName from '../rules/no-unused-class-name.js';
5353
import noUnusedSvelteIgnore from '../rules/no-unused-svelte-ignore.js';
54+
import noUselessChildrenSnippet from '../rules/no-useless-children-snippet.js';
5455
import noUselessMustaches from '../rules/no-useless-mustaches.js';
5556
import preferClassDirective from '../rules/prefer-class-directive.js';
5657
import preferConst from '../rules/prefer-const.js';
@@ -121,6 +122,7 @@ export const rules = [
121122
noUnknownStyleDirectiveProperty,
122123
noUnusedClassName,
123124
noUnusedSvelteIgnore,
125+
noUselessChildrenSnippet,
124126
noUselessMustaches,
125127
preferClassDirective,
126128
preferConst,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"svelte": ">=5.0.0"
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- message: Found an unnecessary children snippet.
2+
line: 2
3+
column: 3
4+
suggestions: null
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<Foo>
2+
{#snippet children()}
3+
Hello
4+
{/snippet}
5+
</Foo>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"svelte": ">=5.0.0"
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<Foo>
2+
Hello
3+
</Foo>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<Foo>
2+
{#snippet bar()}
3+
Hello
4+
{/snippet}
5+
</Foo>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<Foo>
2+
{#snippet children(val)}
3+
Hello {val}
4+
{/snippet}
5+
</Foo>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{#snippet children()}
2+
Hello
3+
{/snippet}
4+
5+
{@render children()}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { RuleTester } from '../../utils/eslint-compat';
2+
import rule from '../../../src/rules/no-useless-children-snippet';
3+
import { loadTestCases } from '../../utils/utils';
4+
5+
const tester = new RuleTester({
6+
languageOptions: {
7+
ecmaVersion: 2020,
8+
sourceType: 'module'
9+
}
10+
});
11+
12+
tester.run('no-useless-children-snippet', rule as any, loadTestCases('no-useless-children-snippet'));

0 commit comments

Comments
 (0)