From 86aef7ab8752b330822ce867182cf31ac2124151 Mon Sep 17 00:00:00 2001 From: Yunfei He Date: Thu, 18 Jun 2026 21:09:14 +0800 Subject: [PATCH] fix(md): tolerate trailing comma in markdown island imports The island-import regexes in the markdown compiler did not allow a trailing comma in the import attributes (`with { island: "load", }`) and only matched component names of the form \w+. A markdown page using either form silently fell through to the non-island branch: the component rendered as static markup with no client hydration, and the un-stripped import leaked into the client bundle as an orphan import. The same island-import fix already landed for all four adapter plugins and void/pages/islands-plugin.ts (commit 3307e6fc), but the parallel markdown parser (shared by every adapter for .md pages) was missed. Mirror it here: allow an optional trailing comma and a $/_-leading component name in both the extraction and line-strip regexes. --- packages/md/src/extract-script.ts | 4 +-- packages/md/test/unit/extract-script.test.ts | 29 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/packages/md/src/extract-script.ts b/packages/md/src/extract-script.ts index 19e9ffd5a..a31c9d5e0 100644 --- a/packages/md/src/extract-script.ts +++ b/packages/md/src/extract-script.ts @@ -1,8 +1,8 @@ const SCRIPT_RE = /^]*>([\s\S]*?)<\/script>\s*\n?/; const ISLAND_IMPORT_RE = - /import\s+(\w+)\s+from\s+("[^"]+"|'[^']+')\s+with\s*\{\s*island\s*:\s*("[^"]+"|'[^']+')\s*\}/g; + /import\s+([$_A-Za-z][$_\w]*)\s+from\s+("[^"]+"|'[^']+')\s+with\s*\{\s*island\s*:\s*("[^"]+"|'[^']+')\s*,?\s*\}/g; const ISLAND_IMPORT_LINE_RE = - /^[ \t]*import\s+\w+\s+from\s+(?:"[^"]+"|'[^']+')\s+with\s*\{\s*island\s*:\s*(?:"[^"]+"|'[^']+')\s*\}\s*;?\s*$/gm; + /^[ \t]*import\s+[$_A-Za-z][$_\w]*\s+from\s+(?:"[^"]+"|'[^']+')\s+with\s*\{\s*island\s*:\s*(?:"[^"]+"|'[^']+')\s*,?\s*\}\s*;?\s*$/gm; export type IslandImport = { name: string; diff --git a/packages/md/test/unit/extract-script.test.ts b/packages/md/test/unit/extract-script.test.ts index fc233d685..667df4ac7 100644 --- a/packages/md/test/unit/extract-script.test.ts +++ b/packages/md/test/unit/extract-script.test.ts @@ -133,4 +133,33 @@ const count = ref(0) const result = extractScript(source); expect(result.clientCode).toBe(`import { ref } from "vue"\n\nconst count = ref(0)`); }); + + it('extracts island imports with a trailing comma in the attributes', () => { + const source = ` + +# Hello`; + const result = extractScript(source); + expect(result.islandImports).toHaveLength(1); + expect(result.islandImports[0]).toEqual({ + name: 'Counter', + specifier: './Counter.vue', + strategy: 'load', + }); + // the island import line is stripped from client code (not leaked as an orphan import) + expect(result.clientCode).toBeNull(); + }); + + it('extracts island imports whose component name starts with $ or _', () => { + const source = ` + +# Hello`; + const result = extractScript(source); + expect(result.islandImports).toHaveLength(1); + expect(result.islandImports[0].name).toBe('$Counter'); + expect(result.clientCode).toBeNull(); + }); });