Repository: tivac/modular-css (js)

Issue:
Preprocessor only looks for imports in the first <script> tag if multiple are present
Sveltekit components may have multiple <script> tags, and unless .mcss files are imported within the first tag, the preprocessor will fail to find the references and won't compile the associated styles:

Fails:
```
<script context="module">
	export const prerender = true;
</script>

<script>
	import Component from '$lib/Component.svelte';
	
        import css from "$lib/fooga/fooga.mcss";
</script>

<div class="{css.fooga}">Lorum Ipsum</div>
```

Works:
```
<script context="module">
	import css from "$lib/fooga/fooga.mcss";

	export const prerender = true;
</script>

<script>
	import Component from '$lib/Component.svelte';
</script>

<div class="{css.fooga}">Lorum Ipsum</div>
```

Pull request description:
feat(svelte): check every <script>
<!--- Provide a general summary of your changes in the Title above -->

## Description
At least until a matching import is found, still bail on the first one for optimization simplicity reasons.

## Motivation and Context
Fixes #818

## How Has This Been Tested?
Added a test

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [x] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [x] I have read the **CONTRIBUTING** document.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.


Patch:
diff --git a/packages/svelte/script.js b/packages/svelte/script.js
index 7f9e4810..e5e744ac 100644
--- a/packages/svelte/script.js
+++ b/packages/svelte/script.js
@@ -3,7 +3,7 @@
 const { init, parse } = require("es-module-lexer");
 const parseImports = require("parse-es6-imports");
 
-const scriptRegex = /<script[\S\s]*?>([\S\s]*?)<\/script>/im;
+const scriptRegex = /<script[\S\s]*?>(?<contents>[\S\s]*?)<\/script>/gim;
 
 // eslint-disable-next-line max-statements
 exports.extractImport = async ({
@@ -15,28 +15,30 @@ exports.extractImport = async ({
 }) => {
     await init;
 
-    const script = source.match(scriptRegex);
-    
-    if(!script) {
-        return false;
-    }
-
-    const [ , contents ] = script;
-    const [ imports ] = parse(contents);
+    const scripts = source.matchAll(scriptRegex);
     let href;
     let ident;
 
-    for(const { n : name, ss : start, se : end, d : dynamic } of imports) {
-        if(!filter(name) || dynamic > -1) {
-            continue;
+    for(const script of scripts) {
+        const { contents } = script.groups;
+        const [ imports ] = parse(contents);
+    
+        for(const { n : name, ss : start, se : end, d : dynamic } of imports) {
+            if(!filter(name) || dynamic > -1) {
+                continue;
+            }
+    
+            const [ details ] = parseImports(contents.substring(start, end));
+    
+            href = name;
+            ident = details.defaultImport;
+    
+            break;
         }
 
-        const [ details ] = parseImports(contents.substring(start, end));
-
-        href = name;
-        ident = details.defaultImport;
-
-        break;
+        if(href) {
+            break;
+        }
     }
 
     if(!href) {


Test patch:
diff --git a/packages/svelte/test/__snapshots__/svelte.test.js.snap b/packages/svelte/test/__snapshots__/svelte.test.js.snap
index 260c5ae1..0d8c635f 100644
--- a/packages/svelte/test/__snapshots__/svelte.test.js.snap
+++ b/packages/svelte/test/__snapshots__/svelte.test.js.snap
@@ -277,6 +277,48 @@ exports[`/svelte.js should extract CSS - <style> 2`] = `
 "
 `;
 
+exports[`/svelte.js should find imports in any <script> tag 1`] = `
+"<div class=\\"mc_flex mc_wrapper\\">
+    <h1 class=\\"mc_fooga mc_flex mc_hd\\">Head</h1>
+    <div class=\\"mc_fooga mc_wooga mc_bd\\">
+        <p class=\\"{bool ? \\"mc_text\\" : \\"mc_active\\" }\\">Text</p>
+    </div>
+</div>
+
+<script context=\\"module\\">
+	export const prerender = true;
+</script>
+
+<script>
+    import styles from \\"./external.css\\";
+
+    const bool = false;
+</script>
+"
+`;
+
+exports[`/svelte.js should find imports in any <script> tag 2`] = `
+"/* packages/svelte/test/specimens/simple.css */
+.mc_fooga {
+    color: red;
+}
+/* packages/svelte/test/specimens/dependencies.css */
+.mc_wooga {
+    background: blue;
+}
+/* packages/svelte/test/specimens/external.css */
+.mc_flex {
+    display: flex;
+}
+.mc_text {
+    color: #000;
+}
+.mc_active {
+    color: #F00;
+}
+"
+`;
+
 exports[`/svelte.js should handle errors: empty css file - <link> 1`] = `"[@modular-css/svelte] Unable to find .nope, .nopedynope, .alsonope in \\"./empty.css\\""`;
 
 exports[`/svelte.js should handle errors: empty css file - <link> 2`] = `
diff --git a/packages/svelte/test/specimens/script-multiple.svelte b/packages/svelte/test/specimens/script-multiple.svelte
new file mode 100644
index 00000000..f61c63a9
--- /dev/null
+++ b/packages/svelte/test/specimens/script-multiple.svelte
@@ -0,0 +1,16 @@
+<div class="{styles.wrapper}">
+    <h1 class="{styles.hd}">Head</h1>
+    <div class="{styles.bd}">
+        <p class="{bool ? styles.text : styles.active }">Text</p>
+    </div>
+</div>
+
+<script context="module">
+	export const prerender = true;
+</script>
+
+<script>
+    import styles from "./external.css";
+
+    const bool = false;
+</script>
diff --git a/packages/svelte/test/svelte.test.js b/packages/svelte/test/svelte.test.js
index f5b94ee7..4b97d672 100644
--- a/packages/svelte/test/svelte.test.js
+++ b/packages/svelte/test/svelte.test.js
@@ -512,4 +512,25 @@ describe("/svelte.js", () => {
 
         expect(output.css).toMatchSnapshot();
     });
+
+    it("should find imports in any <script> tag", async () => {
+        const filename = require.resolve("./specimens/script-multiple.svelte");
+        const { processor, preprocess } = plugin({
+            namer,
+        });
+
+        const processed = await svelte.preprocess(
+            fs.readFileSync(filename, "utf8"),
+            {
+                ...preprocess,
+                filename,
+            },
+        );
+
+        expect(processed.toString()).toMatchSnapshot();
+
+        const output = await processor.output();
+
+        expect(output.css).toMatchSnapshot();
+    });
 });