Skip to content

Commit 0c341bd

Browse files
authored
fix: Move hoisted snippet to right after import (#2753)
#2653
1 parent b887cbe commit 0c341bd

File tree

8 files changed

+60
-12
lines changed

8 files changed

+60
-12
lines changed

packages/svelte2tsx/src/svelte2tsx/index.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { processInstanceScriptContent } from './processInstanceScriptContent';
1010
import { createModuleAst, ModuleAst, processModuleScriptTag } from './processModuleScriptTag';
1111
import path from 'path';
1212
import { parse, VERSION } from 'svelte/compiler';
13+
import { getTopLevelImports } from './utils/tsAst';
1314

1415
function processSvelteTemplate(
1516
str: MagicString,
@@ -170,6 +171,20 @@ export function svelte2tsx(
170171
}
171172

172173
if (moduleScriptTag || scriptTag) {
174+
let snippetHoistTargetForModule = 0;
175+
if (rootSnippets.length) {
176+
if (scriptTag) {
177+
snippetHoistTargetForModule = scriptTag.start + 1; // +1 because imports are also moved at that position, and we want to move interfaces after imports
178+
} else {
179+
const imports = getTopLevelImports(moduleAst.tsAst);
180+
const lastImport = imports[imports.length - 1];
181+
snippetHoistTargetForModule = lastImport
182+
? lastImport.end + moduleAst.astOffset
183+
: moduleAst.astOffset;
184+
str.appendLeft(snippetHoistTargetForModule, '\n');
185+
}
186+
}
187+
173188
for (const [start, end, globals] of rootSnippets) {
174189
const hoist_to_module =
175190
moduleScriptTag &&
@@ -179,13 +194,7 @@ export function svelte2tsx(
179194
));
180195

181196
if (hoist_to_module) {
182-
str.move(
183-
start,
184-
end,
185-
scriptTag
186-
? scriptTag.start + 1 // +1 because imports are also moved at that position, and we want to move interfaces after imports
187-
: instanceScriptTarget
188-
);
197+
str.move(start, end, snippetHoistTargetForModule);
189198
} else if (scriptTag) {
190199
str.move(start, end, renderFunctionStart);
191200
}

packages/svelte2tsx/src/svelte2tsx/nodes/handleImportDeclaration.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import MagicString from 'magic-string';
22
import ts from 'typescript';
3-
import { moveNode } from '../utils/tsAst';
3+
import { getTopLevelImports, moveNode } from '../utils/tsAst';
44

55
/**
66
* move imports to top of script so they appear outside our render function
@@ -25,7 +25,7 @@ export function handleFirstInstanceImport(
2525
hasModuleScript: boolean,
2626
str: MagicString
2727
) {
28-
const imports = tsAst.statements.filter(ts.isImportDeclaration).sort((a, b) => a.end - b.end);
28+
const imports = getTopLevelImports(tsAst);
2929
const firstImport = imports[0];
3030
if (!firstImport) {
3131
return;

packages/svelte2tsx/src/svelte2tsx/utils/tsAst.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,7 @@ function isNewGroup(sourceFile: ts.SourceFile, topLevelImportDecl: ts.Node, scan
273273

274274
return false;
275275
}
276+
277+
export function getTopLevelImports(sourceFile: ts.SourceFile): ts.ImportDeclaration[] {
278+
return sourceFile.statements.filter(ts.isImportDeclaration).sort((a, b) => a.end - b.end);
279+
}

packages/svelte2tsx/test/svelte2tsx/samples/snippet-module-hoist-3.v5/expectedv2.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
///<reference types="svelte" />
22
;
3-
let foo = true;
4-
; const hoistable1/*Ωignore_positionΩ*/ = ()/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
3+
const hoistable1/*Ωignore_positionΩ*/ = ()/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
54
{ svelteHTML.createElement("div", {}); }
65
};return __sveltets_2_any(0)}; const hoistable2/*Ωignore_positionΩ*/ = ()/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {
76
{ svelteHTML.createElement("div", {});foo; }
8-
};return __sveltets_2_any(0)};;function $$render() {
7+
};return __sveltets_2_any(0)};
8+
let foo = true;
9+
;;function $$render() {
910
async () => {
1011

1112

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
///<reference types="svelte" />
2+
;
3+
import {} from 'svelte'
4+
const foo/*Ωignore_positionΩ*/ = ()/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {};return __sveltets_2_any(0)};
5+
;;function $$render() {
6+
async () => {
7+
8+
};
9+
return { props: /** @type {Record<string, never>} */ ({}), exports: {}, bindings: "", slots: {}, events: {} }}
10+
const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event($$render())));
11+
/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType<typeof Input__SvelteComponent_>;
12+
/*Ωignore_endΩ*/export default Input__SvelteComponent_;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script module>
2+
import {} from 'svelte'
3+
</script>
4+
5+
{#snippet foo()}{/snippet}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
///<reference types="svelte" />
2+
;
3+
const _foo/*Ωignore_positionΩ*/ = ()/*Ωignore_startΩ*/: ReturnType<import('svelte').Snippet>/*Ωignore_endΩ*/ => { async ()/*Ωignore_positionΩ*/ => {};return __sveltets_2_any(0)};
4+
export const foo = _foo;
5+
;;function $$render() {
6+
async () => {
7+
8+
};
9+
return { props: /** @type {Record<string, never>} */ ({}), exports: {}, bindings: "", slots: {}, events: {} }}
10+
const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event($$render())));
11+
/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType<typeof Input__SvelteComponent_>;
12+
/*Ωignore_endΩ*/export default Input__SvelteComponent_;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script module>
2+
export const foo = _foo;
3+
</script>
4+
5+
{#snippet _foo()}{/snippet}

0 commit comments

Comments
 (0)