fix: add warning when you read object property within attachments in legacy mode

warn-attachments-legacy-member-access
paoloricciuti 4 months ago
parent 42e7e8168d
commit fc896a779f

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: add warning when you read object property within attachments in legacy mode

@ -556,6 +556,12 @@ Elements with ARIA roles must use a valid, non-abstract ARIA role. A reference t
<div role="toooltip"></div> <div role="toooltip"></div>
``` ```
### attachment_legacy_member_access
```
Using `@attach` with a function from an object in legacy mode can cause unnecessary reruns of the attachment function if you mutate that object.
```
### attribute_avoid_is ### attribute_avoid_is
``` ```

@ -1,3 +1,7 @@
## attachment_legacy_member_access
> Using `@attach` with a function from an object in legacy mode can cause unnecessary reruns of the attachment function if you mutate that object.
## attribute_avoid_is ## attribute_avoid_is
> The "is" attribute is not supported cross-browser and should be avoided > The "is" attribute is not supported cross-browser and should be avoided

@ -1,7 +1,9 @@
/** @import { AST } from '#compiler' */ /** @import { AST } from '#compiler' */
/** @import { Context } from '../types' */ /** @import { Context } from '../types' */
import { walk } from 'zimmerframe';
import { mark_subtree_dynamic } from './shared/fragment.js'; import { mark_subtree_dynamic } from './shared/fragment.js';
import * as w from '../../../warnings.js';
/** /**
* @param {AST.AttachTag} node * @param {AST.AttachTag} node
@ -9,5 +11,16 @@ import { mark_subtree_dynamic } from './shared/fragment.js';
*/ */
export function AttachTag(node, context) { export function AttachTag(node, context) {
mark_subtree_dynamic(context.path); mark_subtree_dynamic(context.path);
if (!context.state.analysis.runes) {
walk(
node.expression,
{},
{
MemberExpression(node) {
w.attachment_legacy_member_access(node);
}
}
);
}
context.next({ ...context.state, expression: node.metadata.expression }); context.next({ ...context.state, expression: node.metadata.expression });
} }

@ -106,6 +106,7 @@ export const codes = [
'state_referenced_locally', 'state_referenced_locally',
'store_rune_conflict', 'store_rune_conflict',
'css_unused_selector', 'css_unused_selector',
'attachment_legacy_member_access',
'attribute_avoid_is', 'attribute_avoid_is',
'attribute_global_event_reference', 'attribute_global_event_reference',
'attribute_illegal_colon', 'attribute_illegal_colon',
@ -677,6 +678,14 @@ export function css_unused_selector(node, name) {
w(node, 'css_unused_selector', `Unused CSS selector "${name}"\nhttps://svelte.dev/e/css_unused_selector`); w(node, 'css_unused_selector', `Unused CSS selector "${name}"\nhttps://svelte.dev/e/css_unused_selector`);
} }
/**
* Using `@attach` with a function from an object in legacy mode can cause unnecessary reruns of the attachment function if you mutate that object.
* @param {null | NodeLike} node
*/
export function attachment_legacy_member_access(node) {
w(node, 'attachment_legacy_member_access', `Using \`@attach\` with a function from an object can cause unnecessary reruns of the attachment function if you mutate that object in legacy mode.\nhttps://svelte.dev/e/attachment_legacy_member_access`);
}
/** /**
* The "is" attribute is not supported cross-browser and should be avoided * The "is" attribute is not supported cross-browser and should be avoided
* @param {null | NodeLike} node * @param {null | NodeLike} node

@ -0,0 +1,14 @@
<script>
let state = {
count: 0,
attachment(){
}
};
</script>
<button onclick={()=>{
state.count++;
}}>{state.count}</button>
<div {@attach state.attachment}></div>

@ -0,0 +1,14 @@
[
{
"code": "attachment_legacy_member_access",
"message": "Using `@attach` with a function from an object in legacy mode can cause unnecessary reruns of the attachment function if you mutate that object.",
"start": {
"line": 14,
"column": 14
},
"end": {
"line": 14,
"column": 30
}
}
]
Loading…
Cancel
Save