@@ -16,32 +16,46 @@ impl<'a> SveltePartialLoader<'a> {
1616 }
1717
1818 pub fn parse ( self ) -> Vec < JavaScriptSource < ' a > > {
19- self . parse_script ( ) . map_or_else ( Vec :: new , |source| vec ! [ source ] )
19+ self . parse_scripts ( )
2020 }
2121
22- fn parse_script ( & self ) -> Option < JavaScriptSource < ' a > > {
22+ /// Each *.svelte file can contain at most
23+ /// * one `<script>` block
24+ /// * one `<script context="module">` or `<script module>` block
25+ /// <https://github.com/sveltejs/svelte.dev/blob/ba7ad256f786aa5bc67eac3a58608f3f50b59e91/apps/svelte.dev/content/tutorial/02-advanced-svelte/08-script-module/02-module-exports/index.md>
26+ fn parse_scripts ( & self ) -> Vec < JavaScriptSource < ' a > > {
27+ let mut pointer = 0 ;
28+ let Some ( result1) = self . parse_script ( & mut pointer) else {
29+ return vec ! [ ] ;
30+ } ;
31+ let Some ( result2) = self . parse_script ( & mut pointer) else {
32+ return vec ! [ result1] ;
33+ } ;
34+ vec ! [ result1, result2]
35+ }
36+
37+ fn parse_script ( & self , pointer : & mut usize ) -> Option < JavaScriptSource < ' a > > {
2338 let script_start_finder = Finder :: new ( SCRIPT_START ) ;
2439 let script_end_finder = Finder :: new ( SCRIPT_END ) ;
2540
26- let mut pointer = 0 ;
27-
2841 // find opening "<script"
29- let offset = script_start_finder. find ( & self . source_text . as_bytes ( ) [ pointer..] ) ?;
30- pointer += offset + SCRIPT_START . len ( ) ;
42+ let offset = script_start_finder. find ( & self . source_text . as_bytes ( ) [ * pointer..] ) ?;
43+ * pointer += offset + SCRIPT_START . len ( ) ;
3144
3245 // find closing ">"
33- let offset = find_script_closing_angle ( self . source_text , pointer) ?;
46+ let offset = find_script_closing_angle ( self . source_text , * pointer) ?;
3447
3548 // get lang="ts" attribute
36- let content = & self . source_text [ pointer..pointer + offset] ;
49+ let content = & self . source_text [ * pointer..* pointer + offset] ;
3750 let is_ts = content. contains ( "ts" ) ;
3851
39- pointer += offset + 1 ;
40- let js_start = pointer;
52+ * pointer += offset + 1 ;
53+ let js_start = * pointer;
4154
4255 // find "</script>"
43- let offset = script_end_finder. find ( & self . source_text . as_bytes ( ) [ pointer..] ) ?;
44- let js_end = pointer + offset;
56+ let offset = script_end_finder. find ( & self . source_text . as_bytes ( ) [ * pointer..] ) ?;
57+ let js_end = * pointer + offset;
58+ * pointer += offset + SCRIPT_END . len ( ) ;
4559
4660 let source_text = & self . source_text [ js_start..js_end] ;
4761 let source_type = SourceType :: mjs ( ) . with_typescript ( is_ts) ;
@@ -86,4 +100,25 @@ mod test {
86100 let result = parse_svelte ( source_text) ;
87101 assert_eq ! ( result. source_text. trim( ) , r#"console.log("hi");"# ) ;
88102 }
103+
104+ #[ test]
105+ fn test_parse_svelte_with_module_script ( ) {
106+ let source_text = r#"
107+ <script module>
108+ export async function load() { /* some loading logic */ }
109+ </script>
110+ <script>
111+ console.log("hi");
112+ </script>
113+ <h1>Hello World</h1>
114+ "# ;
115+
116+ let sources = SveltePartialLoader :: new ( source_text) . parse ( ) ;
117+ assert_eq ! ( sources. len( ) , 2 ) ;
118+ assert_eq ! (
119+ sources[ 0 ] . source_text. trim( ) ,
120+ "export async function load() { /* some loading logic */ }"
121+ ) ;
122+ assert_eq ! ( sources[ 1 ] . source_text. trim( ) , r#"console.log("hi");"# ) ;
123+ }
89124}
0 commit comments