Skip to content

Commit 843730d

Browse files
authored
feat: added the prefer-svelte-reactivity rule (#1151)
1 parent 4e33ba4 commit 843730d

File tree

155 files changed

+1363
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

155 files changed

+1363
-0
lines changed

.changeset/rich-colts-nail.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'eslint-plugin-svelte': minor
3+
---
4+
5+
feat: added the `prefer-svelte-reactivity` rule

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ These rules relate to possible syntax or logic errors in Svelte code:
273273
| [svelte/no-store-async](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-store-async/) | disallow using async/await inside svelte stores because it causes issues with the auto-unsubscribing features | :star: |
274274
| [svelte/no-top-level-browser-globals](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-top-level-browser-globals/) | disallow using top-level browser global variables | |
275275
| [svelte/no-unknown-style-directive-property](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-unknown-style-directive-property/) | disallow unknown `style:property` | :star: |
276+
| [svelte/prefer-svelte-reactivity](https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-svelte-reactivity/) | disallow using mutable instances of built-in classes where a reactive alternative is provided by svelte/reactivity | :star: |
276277
| [svelte/require-store-callbacks-use-set-param](https://sveltejs.github.io/eslint-plugin-svelte/rules/require-store-callbacks-use-set-param/) | store callbacks must use `set` param | :bulb: |
277278
| [svelte/require-store-reactive-access](https://sveltejs.github.io/eslint-plugin-svelte/rules/require-store-reactive-access/) | disallow to use of the store itself as an operand. Need to use $ prefix or get function. | :star::wrench: |
278279
| [svelte/valid-compile](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-compile/) | disallow warnings when compiling. | |

docs/rules.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ These rules relate to possible syntax or logic errors in Svelte code:
3030
| [svelte/no-store-async](./rules/no-store-async.md) | disallow using async/await inside svelte stores because it causes issues with the auto-unsubscribing features | :star: |
3131
| [svelte/no-top-level-browser-globals](./rules/no-top-level-browser-globals.md) | disallow using top-level browser global variables | |
3232
| [svelte/no-unknown-style-directive-property](./rules/no-unknown-style-directive-property.md) | disallow unknown `style:property` | :star: |
33+
| [svelte/prefer-svelte-reactivity](./rules/prefer-svelte-reactivity.md) | disallow using mutable instances of built-in classes where a reactive alternative is provided by svelte/reactivity | :star: |
3334
| [svelte/require-store-callbacks-use-set-param](./rules/require-store-callbacks-use-set-param.md) | store callbacks must use `set` param | :bulb: |
3435
| [svelte/require-store-reactive-access](./rules/require-store-reactive-access.md) | disallow to use of the store itself as an operand. Need to use $ prefix or get function. | :star::wrench: |
3536
| [svelte/valid-compile](./rules/valid-compile.md) | disallow warnings when compiling. | |
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
---
2+
pageClass: 'rule-details'
3+
sidebarDepth: 0
4+
title: 'svelte/prefer-svelte-reactivity'
5+
description: 'disallow using mutable instances of built-in classes where a reactive alternative is provided by svelte/reactivity'
6+
---
7+
8+
# svelte/prefer-svelte-reactivity
9+
10+
> disallow using mutable instances of built-in classes where a reactive alternative is provided by svelte/reactivity
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+
- :gear: This rule is included in `"plugin:svelte/recommended"`.
14+
15+
## :book: Rule Details
16+
17+
The built-in `Date`, `Map`, `Set`, `URL` and `URLSearchParams` classes are often used in frontend code, however, their properties and methods are not reactive. Because of that, Svelte provides reactive versions of these 5 builtins as part of the "svelte/reactivity" package. This rule reports usage of mutable instances of the built-in versions in Svelte code.
18+
19+
<!--eslint-skip-->
20+
21+
```svelte
22+
<script>
23+
/* eslint svelte/prefer-svelte-reactivity: "error" */
24+
25+
import {
26+
SvelteDate,
27+
SvelteMap,
28+
SvelteSet,
29+
SvelteURL,
30+
SvelteURLSearchParams
31+
} from 'svelte/reactivity';
32+
33+
/* ✓ GOOD */
34+
35+
const a = new Date(8.64e15);
36+
const b = new Map([
37+
[1, 'one'],
38+
[2, 'two']
39+
]);
40+
const c = new Set([1, 2, 1, 3, 3]);
41+
const d = new URL('https://svelte.dev/');
42+
const e = new URLSearchParams('foo=1&bar=2');
43+
44+
// These don't modify the instances
45+
a.getTime();
46+
b.keys();
47+
c.has(1);
48+
d.port;
49+
e.entries();
50+
51+
const f = new SvelteDate(8.64e15);
52+
const g = new SvelteMap([
53+
[1, 'one'],
54+
[2, 'two']
55+
]);
56+
const h = new SvelteSet([1, 2, 1, 3, 3]);
57+
const i = new SvelteURL('https://svelte.dev/');
58+
const j = new SvelteURLSearchParams('foo=1&bar=2');
59+
60+
// These modify the instances
61+
f.getTime();
62+
g.keys();
63+
h.has(1);
64+
i.port;
65+
j.entries();
66+
67+
/* ✗ BAD */
68+
69+
const k = new Date(8.64e15);
70+
const l = new Map([
71+
[1, 'one'],
72+
[2, 'two']
73+
]);
74+
const m = new Set([1, 2, 1, 3, 3]);
75+
const n = new URL('https://svelte.dev/');
76+
const o = new URLSearchParams('foo=1&bar=2');
77+
78+
// These modify the instances
79+
k.setMonth(3);
80+
l.clear();
81+
m.delete(2);
82+
n.port = 80;
83+
o.sort();
84+
</script>
85+
```
86+
87+
```js
88+
// In svelte.js files, exported variables are also reported
89+
/* eslint svelte/prefer-svelte-reactivity: "error" */
90+
91+
/* ✗ BAD */
92+
93+
const a = new Date(8.64e15);
94+
const b = new Map([
95+
[1, 'one'],
96+
[2, 'two']
97+
]);
98+
const c = new Set([1, 2, 1, 3, 3]);
99+
const d = new URL('https://svelte.dev/');
100+
const e = new URLSearchParams('foo=1&bar=2');
101+
102+
export { a, b, c, d as dd };
103+
export default e;
104+
```
105+
106+
## :wrench: Options
107+
108+
Nothing.
109+
110+
## :books: Further Reading
111+
112+
- [svelte/reactivity documentation](https://svelte.dev/docs/svelte/svelte-reactivity)
113+
114+
## :mag: Implementation
115+
116+
- [Rule source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/src/rules/prefer-svelte-reactivity.ts)
117+
- [Test source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/tests/src/rules/prefer-svelte-reactivity.ts)

packages/eslint-plugin-svelte/src/configs/flat/recommended.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const config: Linter.Config[] = [
3737
'svelte/no-unused-svelte-ignore': 'error',
3838
'svelte/no-useless-children-snippet': 'error',
3939
'svelte/no-useless-mustaches': 'error',
40+
'svelte/prefer-svelte-reactivity': 'error',
4041
'svelte/prefer-writable-derived': 'error',
4142
'svelte/require-each-key': 'error',
4243
'svelte/require-event-dispatcher-types': 'error',

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,11 @@ export interface RuleOptions {
316316
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-style-directive/
317317
*/
318318
'svelte/prefer-style-directive'?: Linter.RuleEntry<[]>
319+
/**
320+
* disallow using mutable instances of built-in classes where a reactive alternative is provided by svelte/reactivity
321+
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-svelte-reactivity/
322+
*/
323+
'svelte/prefer-svelte-reactivity'?: Linter.RuleEntry<[]>
319324
/**
320325
* Prefer using writable $derived instead of $state and $effect
321326
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-writable-derived/

0 commit comments

Comments
 (0)