Skip to content

Commit

Permalink
add dev runtime warning for unknown slot names (#4501)
Browse files Browse the repository at this point in the history
  • Loading branch information
Conduitry authored Mar 5, 2020
1 parent 926a2ae commit f2ee7ef
Show file tree
Hide file tree
Showing 15 changed files with 67 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

* 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))
* In `vars` array, correctly indicate whether `module` variables are `mutated` or `reassigned` ([#3215](https://github.com/sveltejs/svelte/issues/3215))
* Fix spread props not updating in certain situations ([#3521](https://github.com/sveltejs/svelte/issues/3521), [#4480](https://github.com/sveltejs/svelte/issues/4480))
* Use the fallback content for slots if they are passed only whitespace ([#4092](https://github.com/sveltejs/svelte/issues/4092))
Expand Down
3 changes: 1 addition & 2 deletions src/compiler/compile/render_dom/Block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,7 @@ export default class Block {
}

has_content() {
return this.renderer.options.dev ||
this.first ||
return this.first ||
this.event_listeners.length > 0 ||
this.chunks.intro.length > 0 ||
this.chunks.outro.length > 0 ||
Expand Down
5 changes: 3 additions & 2 deletions src/compiler/compile/render_dom/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ export default function dom(
args.push(x`$$props`);
}

const has_create_fragment = block.has_content();
const has_create_fragment = component.compile_options.dev || block.has_content();
if (has_create_fragment) {
body.push(b`
function create_fragment(#ctx) {
Expand Down Expand Up @@ -412,7 +412,8 @@ export default function dom(
${unknown_props_check}
${component.slots.size ? b`let { $$slots = {}, $$scope } = $$props;` : null}
${component.slots.size || component.compile_options.dev ? b`let { $$slots = {}, $$scope } = $$props;` : null}
${component.compile_options.dev && b`@validate_slots('${component.tag}', $$slots, [${[...component.slots.keys()].map(key => `'${key}'`).join(',')}]);`}
${renderer.binding_groups.length > 0 && b`const $$binding_groups = [${renderer.binding_groups.map(_ => x`[]`)}];`}
Expand Down
7 changes: 7 additions & 0 deletions src/runtime/internal/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ export function validate_each_argument(arg) {
}
}

export function validate_slots(name, slot, keys) {
for (const slot_key of Object.keys(slot)) {
if (!~keys.indexOf(slot_key)) {
console.warn(`<${name}> received an unexpected slot "${slot_key}".`);
}
}
}

type Props = Record<string, any>;
export interface SvelteComponentDev {
Expand Down
4 changes: 4 additions & 0 deletions test/js/samples/capture-inject-state/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
space,
subscribe,
text,
validate_slots,
validate_store
} from "svelte/internal";

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

let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);

$$self.$set = $$props => {
if ("prop" in $$props) $$subscribe_prop($$invalidate(0, prop = $$props.prop));
if ("alias" in $$props) $$invalidate(1, realName = $$props.alias);
Expand Down
6 changes: 5 additions & 1 deletion test/js/samples/debug-empty/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
safe_not_equal,
set_data_dev,
space,
text
text,
validate_slots
} from "svelte/internal";

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

let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);

$$self.$set = $$props => {
if ("name" in $$props) $$invalidate(0, name = $$props.name);
};
Expand Down
6 changes: 5 additions & 1 deletion test/js/samples/debug-foo-bar-baz-things/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
set_data_dev,
space,
text,
validate_each_argument
validate_each_argument,
validate_slots
} from "svelte/internal";

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

let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);

$$self.$set = $$props => {
if ("things" in $$props) $$invalidate(0, things = $$props.things);
if ("foo" in $$props) $$invalidate(1, foo = $$props.foo);
Expand Down
6 changes: 5 additions & 1 deletion test/js/samples/debug-foo/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
set_data_dev,
space,
text,
validate_each_argument
validate_each_argument,
validate_slots
} from "svelte/internal";

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

let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);

$$self.$set = $$props => {
if ("things" in $$props) $$invalidate(0, things = $$props.things);
if ("foo" in $$props) $$invalidate(1, foo = $$props.foo);
Expand Down
5 changes: 4 additions & 1 deletion test/js/samples/debug-hoisted/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
dispatch_dev,
init,
noop,
safe_not_equal
safe_not_equal,
validate_slots
} from "svelte/internal";

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

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

$$self.$inject_state = $$props => {
Expand Down
5 changes: 4 additions & 1 deletion test/js/samples/debug-no-dependencies/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
safe_not_equal,
space,
text,
validate_each_argument
validate_each_argument,
validate_slots
} from "svelte/internal";

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

let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);
return [];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
safe_not_equal,
set_data_dev,
space,
text
text,
validate_slots
} from "svelte/internal";

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

let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);

$$self.$set = $$props => {
if ("foo" in $$props) $$invalidate(0, foo = $$props.foo);
};
Expand Down
8 changes: 6 additions & 2 deletions test/js/samples/loop-protect/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
insert_dev,
loop_guard,
noop,
safe_not_equal
safe_not_equal,
validate_slots
} from "svelte/internal";

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

let { $$slots = {}, $$scope } = $$props;
validate_slots("Component", $$slots, []);

function div_binding($$value) {
binding_callbacks[$$value ? "unshift" : "push"](() => {
$$invalidate(0, node = $$value);
Expand Down Expand Up @@ -161,4 +165,4 @@ class Component extends SvelteComponentDev {
}
}

export default Component;
export default Component;
1 change: 1 addition & 0 deletions test/runtime/samples/component-slot-warning/Nested.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<slot name="slot2"></slot>
9 changes: 9 additions & 0 deletions test/runtime/samples/component-slot-warning/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default {
compileOptions: {
dev: true
},
warnings: [
'<Nested> received an unexpected slot "default".',
'<Nested> received an unexpected slot "slot1".'
]
};
7 changes: 7 additions & 0 deletions test/runtime/samples/component-slot-warning/main.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script>
import Nested from "./Nested.svelte";
</script>
<Nested>
<input slot="slot1">
<input slot="slot2">
</Nested>

0 comments on commit f2ee7ef

Please sign in to comment.