Skip to content

Commit d270f50

Browse files
committed
fix exports error
1 parent d239ebd commit d270f50

File tree

8 files changed

+39
-4
lines changed

8 files changed

+39
-4
lines changed

documentation/docs/98-reference/.generated/compile-errors.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,12 @@ Cannot use `<slot>` syntax and `{@render ...}` tags in the same component. Migra
694694
Cannot use explicit children snippet at the same time as implicit children content. Remove either the non-whitespace content or the children snippet block
695695
```
696696

697+
### snippet_invalid_export
698+
699+
```
700+
Cannot export snippet from a `<script module>` if it references logic or expressions inside the component
701+
```
702+
697703
### snippet_invalid_rest_parameter
698704

699705
```

packages/svelte/messages/compile-errors/script.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@
134134

135135
> %name% cannot be used in runes mode
136136
137+
## snippet_invalid_export
138+
139+
> Cannot export snippet from a `<script module>` if it references logic or expressions inside the component
140+
137141
## snippet_parameter_assignment
138142

139143
> Cannot reassign or bind to snippet parameter

packages/svelte/src/compiler/errors.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,15 @@ export function state_invalid_export(node) {
413413
e(node, "state_invalid_export", "Cannot export state from a module if it is reassigned. Either export a function returning the state value or only mutate the state value's properties");
414414
}
415415

416+
/**
417+
* Cannot export snippet from a `<script module>` if it references logic or expressions inside the component
418+
* @param {null | number | NodeLike} node
419+
* @returns {never}
420+
*/
421+
export function snippet_invalid_export(node) {
422+
e(node, "snippet_invalid_export", "Cannot export snippet from a `<script module>` if it references logic or expressions inside the component");
423+
}
424+
416425
/**
417426
* `%rune%(...)` can only be used as a variable declaration initializer or a class field
418427
* @param {null | number | NodeLike} node

packages/svelte/src/compiler/phases/2-analyze/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,8 @@ export function analyze_component(root, source, options) {
438438
: '',
439439
keyframes: []
440440
},
441-
source
441+
source,
442+
undefined_exports: new Map()
442443
};
443444

444445
if (!runes) {

packages/svelte/src/compiler/phases/2-analyze/visitors/ExportSpecifier.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ export function ExportSpecifier(node, context) {
2727
if (binding) binding.reassigned = binding.updated = true;
2828
}
2929
} else {
30-
validate_export(node, context.state.scope, local_name);
30+
const undefined_exports = context.state.analysis.undefined_exports;
31+
validate_export(node, context.state.scope, local_name, undefined_exports);
3132
}
3233
}
3334

@@ -36,10 +37,14 @@ export function ExportSpecifier(node, context) {
3637
* @param {Node} node
3738
* @param {Scope} scope
3839
* @param {string} name
40+
* @param {Map<string, Node>} undefined_exports
3941
*/
40-
function validate_export(node, scope, name) {
42+
function validate_export(node, scope, name, undefined_exports) {
4143
const binding = scope.get(name);
42-
if (!binding) return;
44+
if (!binding) {
45+
undefined_exports.set(name, node);
46+
return;
47+
}
4348

4449
if (binding.kind === 'derived') {
4550
e.derived_invalid_export(node);

packages/svelte/src/compiler/phases/2-analyze/visitors/SnippetBlock.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ export function SnippetBlock(node, context) {
2828
context.path.length === 1 &&
2929
context.path[0].type === 'Fragment' &&
3030
can_hoist_snippet(node, local_scope, context.state.scopes);
31+
const undefined_exports = context.state.analysis.undefined_exports;
32+
const name = node.expression.name;
33+
34+
if (!can_hoist && undefined_exports.has(name)) {
35+
e.snippet_invalid_export(/** @type {any} */ (undefined_exports.get(name)));
36+
}
3137

3238
node.metadata = {
3339
can_hoist

packages/svelte/src/compiler/phases/types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export interface ComponentAnalysis extends Analysis {
7373
keyframes: string[];
7474
};
7575
source: string;
76+
undefined_exports: Map<string, Node>;
7677
}
7778

7879
declare module 'estree' {

packages/svelte/types/index.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,6 +1229,9 @@ declare module 'svelte/compiler' {
12291229
expression: Identifier;
12301230
parameters: Pattern[];
12311231
body: Fragment;
1232+
metadata: {
1233+
can_hoist: boolean;
1234+
};
12321235
}
12331236

12341237
export interface Attribute extends BaseNode {

0 commit comments

Comments
 (0)