Skip to content

Commit f2ee7ef

Browse files
authored
add dev runtime warning for unknown slot names (#4501)
1 parent 926a2ae commit f2ee7ef

File tree

15 files changed

+67
-12
lines changed

15 files changed

+67
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Unreleased
44

5+
* In `dev` mode, display a runtime warning when a component is passed an unexpected slot ([#1020](https://github.com/sveltejs/svelte/issues/1020), [#1447](https://github.com/sveltejs/svelte/issues/1447))
56
* In `vars` array, correctly indicate whether `module` variables are `mutated` or `reassigned` ([#3215](https://github.com/sveltejs/svelte/issues/3215))
67
* Fix spread props not updating in certain situations ([#3521](https://github.com/sveltejs/svelte/issues/3521), [#4480](https://github.com/sveltejs/svelte/issues/4480))
78
* Use the fallback content for slots if they are passed only whitespace ([#4092](https://github.com/sveltejs/svelte/issues/4092))

src/compiler/compile/render_dom/Block.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,7 @@ export default class Block {
412412
}
413413

414414
has_content() {
415-
return this.renderer.options.dev ||
416-
this.first ||
415+
return this.first ||
417416
this.event_listeners.length > 0 ||
418417
this.chunks.intro.length > 0 ||
419418
this.chunks.outro.length > 0 ||

src/compiler/compile/render_dom/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ export default function dom(
264264
args.push(x`$$props`);
265265
}
266266

267-
const has_create_fragment = block.has_content();
267+
const has_create_fragment = component.compile_options.dev || block.has_content();
268268
if (has_create_fragment) {
269269
body.push(b`
270270
function create_fragment(#ctx) {
@@ -412,7 +412,8 @@ export default function dom(
412412
413413
${unknown_props_check}
414414
415-
${component.slots.size ? b`let { $$slots = {}, $$scope } = $$props;` : null}
415+
${component.slots.size || component.compile_options.dev ? b`let { $$slots = {}, $$scope } = $$props;` : null}
416+
${component.compile_options.dev && b`@validate_slots('${component.tag}', $$slots, [${[...component.slots.keys()].map(key => `'${key}'`).join(',')}]);`}
416417
417418
${renderer.binding_groups.length > 0 && b`const $$binding_groups = [${renderer.binding_groups.map(_ => x`[]`)}];`}
418419

src/runtime/internal/dev.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ export function validate_each_argument(arg) {
8989
}
9090
}
9191

92+
export function validate_slots(name, slot, keys) {
93+
for (const slot_key of Object.keys(slot)) {
94+
if (!~keys.indexOf(slot_key)) {
95+
console.warn(`<${name}> received an unexpected slot "${slot_key}".`);
96+
}
97+
}
98+
}
9299

93100
type Props = Record<string, any>;
94101
export interface SvelteComponentDev {

test/js/samples/capture-inject-state/expected.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
space,
1515
subscribe,
1616
text,
17+
validate_slots,
1718
validate_store
1819
} from "svelte/internal";
1920

@@ -114,6 +115,9 @@ function instance($$self, $$props, $$invalidate) {
114115
if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<Component> was created with unknown prop '${key}'`);
115116
});
116117

118+
let { $$slots = {}, $$scope } = $$props;
119+
validate_slots("Component", $$slots, []);
120+
117121
$$self.$set = $$props => {
118122
if ("prop" in $$props) $$subscribe_prop($$invalidate(0, prop = $$props.prop));
119123
if ("alias" in $$props) $$invalidate(1, realName = $$props.alias);

test/js/samples/debug-empty/expected.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import {
1212
safe_not_equal,
1313
set_data_dev,
1414
space,
15-
text
15+
text,
16+
validate_slots
1617
} from "svelte/internal";
1718

1819
const file = undefined;
@@ -75,6 +76,9 @@ function instance($$self, $$props, $$invalidate) {
7576
if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<Component> was created with unknown prop '${key}'`);
7677
});
7778

79+
let { $$slots = {}, $$scope } = $$props;
80+
validate_slots("Component", $$slots, []);
81+
7882
$$self.$set = $$props => {
7983
if ("name" in $$props) $$invalidate(0, name = $$props.name);
8084
};

test/js/samples/debug-foo-bar-baz-things/expected.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import {
1414
set_data_dev,
1515
space,
1616
text,
17-
validate_each_argument
17+
validate_each_argument,
18+
validate_slots
1819
} from "svelte/internal";
1920

2021
const file = undefined;
@@ -179,6 +180,9 @@ function instance($$self, $$props, $$invalidate) {
179180
if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<Component> was created with unknown prop '${key}'`);
180181
});
181182

183+
let { $$slots = {}, $$scope } = $$props;
184+
validate_slots("Component", $$slots, []);
185+
182186
$$self.$set = $$props => {
183187
if ("things" in $$props) $$invalidate(0, things = $$props.things);
184188
if ("foo" in $$props) $$invalidate(1, foo = $$props.foo);

test/js/samples/debug-foo/expected.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import {
1414
set_data_dev,
1515
space,
1616
text,
17-
validate_each_argument
17+
validate_each_argument,
18+
validate_slots
1819
} from "svelte/internal";
1920

2021
const file = undefined;
@@ -171,6 +172,9 @@ function instance($$self, $$props, $$invalidate) {
171172
if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<Component> was created with unknown prop '${key}'`);
172173
});
173174

175+
let { $$slots = {}, $$scope } = $$props;
176+
validate_slots("Component", $$slots, []);
177+
174178
$$self.$set = $$props => {
175179
if ("things" in $$props) $$invalidate(0, things = $$props.things);
176180
if ("foo" in $$props) $$invalidate(1, foo = $$props.foo);

test/js/samples/debug-hoisted/expected.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {
44
dispatch_dev,
55
init,
66
noop,
7-
safe_not_equal
7+
safe_not_equal,
8+
validate_slots
89
} from "svelte/internal";
910

1011
const file = undefined;
@@ -56,6 +57,8 @@ function instance($$self, $$props, $$invalidate) {
5657
if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<Component> was created with unknown prop '${key}'`);
5758
});
5859

60+
let { $$slots = {}, $$scope } = $$props;
61+
validate_slots("Component", $$slots, []);
5962
$$self.$capture_state = () => ({ obj, kobzol });
6063

6164
$$self.$inject_state = $$props => {

test/js/samples/debug-no-dependencies/expected.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111
safe_not_equal,
1212
space,
1313
text,
14-
validate_each_argument
14+
validate_each_argument,
15+
validate_slots
1516
} from "svelte/internal";
1617

1718
const file = undefined;
@@ -141,6 +142,8 @@ function instance($$self, $$props) {
141142
if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<Component> was created with unknown prop '${key}'`);
142143
});
143144

145+
let { $$slots = {}, $$scope } = $$props;
146+
validate_slots("Component", $$slots, []);
144147
return [];
145148
}
146149

test/js/samples/dev-warning-missing-data-computed/expected.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import {
1212
safe_not_equal,
1313
set_data_dev,
1414
space,
15-
text
15+
text,
16+
validate_slots
1617
} from "svelte/internal";
1718

1819
const file = undefined;
@@ -72,6 +73,9 @@ function instance($$self, $$props, $$invalidate) {
7273
if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<Component> was created with unknown prop '${key}'`);
7374
});
7475

76+
let { $$slots = {}, $$scope } = $$props;
77+
validate_slots("Component", $$slots, []);
78+
7579
$$self.$set = $$props => {
7680
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
7781
};

test/js/samples/loop-protect/expected.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111
insert_dev,
1212
loop_guard,
1313
noop,
14-
safe_not_equal
14+
safe_not_equal,
15+
validate_slots
1516
} from "svelte/internal";
1617

1718
const { console: console_1 } = globals;
@@ -110,6 +111,9 @@ function instance($$self, $$props, $$invalidate) {
110111
if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console_1.warn(`<Component> was created with unknown prop '${key}'`);
111112
});
112113

114+
let { $$slots = {}, $$scope } = $$props;
115+
validate_slots("Component", $$slots, []);
116+
113117
function div_binding($$value) {
114118
binding_callbacks[$$value ? "unshift" : "push"](() => {
115119
$$invalidate(0, node = $$value);
@@ -161,4 +165,4 @@ class Component extends SvelteComponentDev {
161165
}
162166
}
163167

164-
export default Component;
168+
export default Component;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<slot name="slot2"></slot>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export default {
2+
compileOptions: {
3+
dev: true
4+
},
5+
warnings: [
6+
'<Nested> received an unexpected slot "default".',
7+
'<Nested> received an unexpected slot "slot1".'
8+
]
9+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script>
2+
import Nested from "./Nested.svelte";
3+
</script>
4+
<Nested>
5+
<input slot="slot1">
6+
<input slot="slot2">
7+
</Nested>

0 commit comments

Comments
 (0)