Skip to content

Commit dc60b36

Browse files
ota-meshitivac
andauthored
feat: add svelte/prefer-destructured-store-props rule (#270)
* wip: add prefer-destructured-store-props rule * chore: remove log * chore: trying to figure out lint invocations Editor doesn't like this but maybe it's ok? * wip: better query * wip: suggest reactive statement in <script> Also add a description * wip: address feedbakc * Update .eslintrc.js * wip: feedback * wip: also track imported names * chore: fix lint errors * fix: update prefer-destructured-store-props rule * fix: add testcases and fix * docs: add changeset * fix: use esutils Co-authored-by: Pat Cavit <[email protected]>
1 parent f3a2c4e commit dc60b36

32 files changed

+956
-8
lines changed

.changeset/real-buses-complain.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-svelte": minor
3+
---
4+
5+
feat: add `svelte/prefer-destructured-store-props` rule

.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ module.exports = {
5050
},
5151
{
5252
files: ["*.svelte"],
53+
extends: ["plugin:svelte/base"],
5354
parser: "svelte-eslint-parser",
5455
parserOptions: {
5556
parser: {

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ These rules relate to better ways of doing things to help you avoid problems:
294294
| [svelte/no-reactive-literals](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-reactive-literals/) | don't assign literal values in reactive statements | :bulb: |
295295
| [svelte/no-unused-svelte-ignore](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-unused-svelte-ignore/) | disallow unused svelte-ignore comments | :star: |
296296
| [svelte/no-useless-mustaches](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-useless-mustaches/) | disallow unnecessary mustache interpolations | :wrench: |
297+
| [svelte/prefer-destructured-store-props](https://ota-meshi.github.io/eslint-plugin-svelte/rules/prefer-destructured-store-props/) | destructure values from object stores for better change tracking & fewer redraws | :bulb: |
297298
| [svelte/require-optimized-style-attribute](https://ota-meshi.github.io/eslint-plugin-svelte/rules/require-optimized-style-attribute/) | require style attributes that can be optimized | |
298299
| [svelte/require-stores-init](https://ota-meshi.github.io/eslint-plugin-svelte/rules/require-stores-init/) | require initial value in store | |
299300

docs-svelte-kit/src/lib/eslint/ESLintEditor.svelte

+2-1
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,11 @@
219219
edits: [
220220
{
221221
resource: model.uri,
222-
edit: {
222+
textEdit: {
223223
range: editRange,
224224
text: fix.text,
225225
},
226+
versionId: model.getVersionId(),
226227
},
227228
],
228229
},

docs-svelte-kit/src/lib/eslint/MonacoEditor.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
monaco.languages.registerCodeActionProvider(language, {
5959
provideCodeActions(model, range, context) {
6060
const editor = getLeftEditor?.()
61-
if (editor?.getModel().url !== model.url) {
61+
if (editor?.getModel().uri !== model.uri) {
6262
return {
6363
actions: [],
6464
dispose() {

docs/rules.md

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ These rules relate to better ways of doing things to help you avoid problems:
4747
| [svelte/no-reactive-literals](./rules/no-reactive-literals.md) | don't assign literal values in reactive statements | :bulb: |
4848
| [svelte/no-unused-svelte-ignore](./rules/no-unused-svelte-ignore.md) | disallow unused svelte-ignore comments | :star: |
4949
| [svelte/no-useless-mustaches](./rules/no-useless-mustaches.md) | disallow unnecessary mustache interpolations | :wrench: |
50+
| [svelte/prefer-destructured-store-props](./rules/prefer-destructured-store-props.md) | destructure values from object stores for better change tracking & fewer redraws | :bulb: |
5051
| [svelte/require-optimized-style-attribute](./rules/require-optimized-style-attribute.md) | require style attributes that can be optimized | |
5152
| [svelte/require-stores-init](./rules/require-stores-init.md) | require initial value in store | |
5253

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
pageClass: "rule-details"
3+
sidebarDepth: 0
4+
title: "svelte/prefer-destructured-store-props"
5+
description: "destructure values from object stores for better change tracking & fewer redraws"
6+
---
7+
8+
# svelte/prefer-destructured-store-props
9+
10+
> destructure values from object stores for better change tracking & fewer redraws
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+
- :bulb: Some problems reported by this rule are manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).
14+
15+
## :book: Rule Details
16+
17+
This rule reports on directly accessing properties of a store containing an object in templates. These usages can instead be written as a reactive statement using destructuring to allow for more granular change-tracking and reduced redraws in the component.
18+
19+
An example of the improvements can be see in this [REPL](https://svelte.dev/repl/7de86fea94ff40c48abb82da534dfb89)
20+
21+
<ESLintCodeBlock>
22+
23+
<!--eslint-skip-->
24+
25+
```svelte
26+
<script>
27+
/* eslint svelte/prefer-destructured-store-props: "error" */
28+
import store from "./store.js"
29+
$: ({ foo } = $store)
30+
</script>
31+
32+
<!-- ✓ GOOD -->
33+
{foo}
34+
35+
<!-- ✗ BAD -->
36+
{$store.foo}
37+
```
38+
39+
</ESLintCodeBlock>
40+
41+
## :wrench: Options
42+
43+
Nothing
44+
45+
## :heart: Compatibility
46+
47+
This rule was taken from [@tivac/eslint-plugin-svelte].
48+
This rule is compatible with `@tivac/svelte/store-prop-destructuring` rule.
49+
50+
[@tivac/eslint-plugin-svelte]: https://github.com/tivac/eslint-plugin-svelte/
51+
52+
## :mag: Implementation
53+
54+
- [Rule source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/src/rules/prefer-destructured-store-props.ts)
55+
- [Test source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/tests/src/rules/prefer-destructured-store-props.ts)

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
"dependencies": {
6868
"debug": "^4.3.1",
6969
"eslint-utils": "^3.0.0",
70+
"esutils": "^2.0.3",
7071
"known-css-properties": "^0.25.0",
7172
"postcss": "^8.4.5",
7273
"postcss-load-config": "^3.1.4",
@@ -100,6 +101,7 @@
100101
"@types/eslint-utils": "^3.0.1",
101102
"@types/eslint-visitor-keys": "^1.0.0",
102103
"@types/estree": "^1.0.0",
104+
"@types/esutils": "^2.0.0",
103105
"@types/less": "^3.0.3",
104106
"@types/markdown-it": "^12.2.3",
105107
"@types/markdown-it-container": "^2.0.5",
@@ -172,7 +174,7 @@
172174
"access": "public"
173175
},
174176
"typeCoverage": {
175-
"atLeast": 98.64,
177+
"atLeast": 98.71,
176178
"cache": true,
177179
"detail": true,
178180
"ignoreAsAssertion": true,

0 commit comments

Comments
 (0)