diff --git a/src/compile/Component.ts b/src/compile/Component.ts
index 7d4aa72f03..148313773d 100644
--- a/src/compile/Component.ts
+++ b/src/compile/Component.ts
@@ -541,9 +541,21 @@ export default class Component {
}
walk_module_js() {
+ const component = this;
const script = this.ast.module;
if (!script) return;
+ walk(script.content, {
+ enter(node) {
+ if (node.type === 'LabeledStatement' && node.label.name === '$') {
+ component.warn(node, {
+ code: 'module-script-reactive-declaration',
+ message: '$: has no effect in a module script'
+ });
+ }
+ }
+ });
+
this.add_sourcemap_locations(script.content);
let { scope, globals } = create_scopes(script.content);
@@ -735,6 +747,13 @@ export default class Component {
scope = map.get(node);
}
+ if (node.type === 'LabeledStatement' && node.label.name === '$' && parent.type !== 'Program') {
+ component.warn(node, {
+ code: 'non-top-level-reactive-declaration',
+ message: '$: has no effect outside of the top-level'
+ });
+ }
+
if (is_reference(node, parent)) {
const object = get_object(node);
const { name } = object;
diff --git a/test/validator/samples/module-script-reactive-declaration/input.svelte b/test/validator/samples/module-script-reactive-declaration/input.svelte
new file mode 100644
index 0000000000..9df1cd54dd
--- /dev/null
+++ b/test/validator/samples/module-script-reactive-declaration/input.svelte
@@ -0,0 +1,5 @@
+
diff --git a/test/validator/samples/module-script-reactive-declaration/warnings.json b/test/validator/samples/module-script-reactive-declaration/warnings.json
new file mode 100644
index 0000000000..b1aa74dbcc
--- /dev/null
+++ b/test/validator/samples/module-script-reactive-declaration/warnings.json
@@ -0,0 +1,7 @@
+[{
+ "message": "$: has no effect in a module script",
+ "code": "module-script-reactive-declaration",
+ "start": { "line": 4, "column": 1, "character": 54 },
+ "end": { "line": 4, "column": 23, "character": 76 },
+ "pos": 54
+}]
diff --git a/test/validator/samples/reactive-declaration-non-top-level/input.svelte b/test/validator/samples/reactive-declaration-non-top-level/input.svelte
new file mode 100644
index 0000000000..ddba4819e0
--- /dev/null
+++ b/test/validator/samples/reactive-declaration-non-top-level/input.svelte
@@ -0,0 +1,8 @@
+
diff --git a/test/validator/samples/reactive-declaration-non-top-level/warnings.json b/test/validator/samples/reactive-declaration-non-top-level/warnings.json
new file mode 100644
index 0000000000..87944642cd
--- /dev/null
+++ b/test/validator/samples/reactive-declaration-non-top-level/warnings.json
@@ -0,0 +1,7 @@
+[{
+ "message": "$: has no effect outside of the top-level",
+ "code": "non-top-level-reactive-declaration",
+ "start": { "line": 6, "column": 2, "character": 71 },
+ "end": { "line": 6, "column": 22, "character": 91 },
+ "pos": 71
+}]