fix: warn when using rest or identifier in custom elements without props option

pull/16003/head
paoloricciuti 4 months ago
parent fbb6444fd8
commit 6ee684ed9a

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: warn when using rest or identifier in custom elements without props option

@ -632,6 +632,12 @@ In some situations a selector may target an element that is not 'visible' to the
</style>
```
### custom_element_props_identifier
```
Using an identifier or a rest element as the declarator for `$props` when compiling to custom elements without declaring `props` in the component options means that Svelte can't know which props to expose as properties on the DOM element. Consider explicitly destructure all the props or add the `customElement.props` option.
```
### element_implicitly_closed
```

@ -1,3 +1,7 @@
## custom_element_props_identifier
> Using an identifier or a rest element as the declarator for `$props` when compiling to custom elements without declaring `props` in the component options means that Svelte can't know which props to expose as properties on the DOM element. Consider explicitly destructure all the props or add the `customElement.props` option.
## export_let_unused
> Component has unused export property '%name%'. If it is for external reference only, please consider using `export const %name%`

@ -4,6 +4,7 @@
import { get_rune } from '../../scope.js';
import { ensure_no_module_import_conflict, validate_identifier_name } from './shared/utils.js';
import * as e from '../../../errors.js';
import * as w from '../../../warnings.js';
import { extract_paths } from '../../../utils/ast.js';
import { equal } from '../../../utils/assert.js';
@ -52,6 +53,19 @@ export function VariableDeclarator(node, context) {
e.props_invalid_identifier(node);
}
if (
context.state.analysis.custom_element &&
context.state.options.customElementOptions?.props == null
) {
let warn_on;
if (
node.id.type === 'Identifier' ||
(warn_on = node.id.properties.find((p) => p.type === 'RestElement')) != null
) {
w.custom_element_props_identifier(warn_on ?? node.id);
}
}
context.state.analysis.needs_props = true;
if (node.id.type === 'Identifier') {

@ -96,6 +96,7 @@ export const codes = [
'options_removed_hydratable',
'options_removed_loop_guard_timeout',
'options_renamed_ssr_dom',
'custom_element_props_identifier',
'export_let_unused',
'legacy_component_creation',
'non_reactive_update',
@ -592,6 +593,14 @@ export function options_renamed_ssr_dom(node) {
w(node, 'options_renamed_ssr_dom', `\`generate: "dom"\` and \`generate: "ssr"\` options have been renamed to "client" and "server" respectively\nhttps://svelte.dev/e/options_renamed_ssr_dom`);
}
/**
* Using an identifier or a rest element as the declarator for `$props` when compiling to custom elements without declaring `props` in the component options means that Svelte can't know which props to expose as properties on the DOM element. Consider explicitly destructure all the props or add the `customElement.props` option.
* @param {null | NodeLike} node
*/
export function custom_element_props_identifier(node) {
w(node, 'custom_element_props_identifier', `Using an identifier or a rest element as the declarator for \`$props\` when compiling to custom elements without declaring \`props\` in the component options means that Svelte can't know which props to expose as properties on the DOM element. Consider explicitly destructure all the props or add the \`customElement.props\` option.\nhttps://svelte.dev/e/custom_element_props_identifier`);
}
/**
* Component has unused export property '%name%'. If it is for external reference only, please consider using `export const %name%`
* @param {null | NodeLike} node

@ -0,0 +1,7 @@
<svelte:options customElement={{
props: {}
}} />
<script>
let props = $props();
</script>

@ -0,0 +1,14 @@
[
{
"code": "options_missing_custom_element",
"end": {
"column": 2,
"line": 3
},
"message": "The `customElement` option is used when generating a custom element. Did you forget the `customElement: true` compile option?",
"start": {
"column": 16,
"line": 1
}
}
]

@ -0,0 +1,5 @@
<svelte:options customElement={{}} />
<script>
let { ...props } = $props();
</script>

@ -0,0 +1,26 @@
[
{
"code": "options_missing_custom_element",
"end": {
"column": 34,
"line": 1
},
"message": "The `customElement` option is used when generating a custom element. Did you forget the `customElement: true` compile option?",
"start": {
"column": 16,
"line": 1
}
},
{
"code": "custom_element_props_identifier",
"end": {
"column": 15,
"line": 4
},
"message": "Using an identifier or a rest element as the declarator for `$props` when compiling to custom elements without declaring `props` in the component options means that Svelte can't know which props to expose as properties on the DOM element. Consider explicitly destructure all the props or add the `customElement.props` option.",
"start": {
"column": 7,
"line": 4
}
}
]

@ -0,0 +1,5 @@
<svelte:options customElement={{}} />
<script>
let props = $props();
</script>

@ -0,0 +1,26 @@
[
{
"code": "options_missing_custom_element",
"end": {
"column": 34,
"line": 1
},
"message": "The `customElement` option is used when generating a custom element. Did you forget the `customElement: true` compile option?",
"start": {
"column": 16,
"line": 1
}
},
{
"code": "custom_element_props_identifier",
"end": {
"column": 10,
"line": 4
},
"message": "Using an identifier or a rest element as the declarator for `$props` when compiling to custom elements without declaring `props` in the component options means that Svelte can't know which props to expose as properties on the DOM element. Consider explicitly destructure all the props or add the `customElement.props` option.",
"start": {
"column": 5,
"line": 4
}
}
]
Loading…
Cancel
Save