diff --git a/packages/md/src/plugin.ts b/packages/md/src/plugin.ts
index 84b74ee8a..30699d528 100644
--- a/packages/md/src/plugin.ts
+++ b/packages/md/src/plugin.ts
@@ -1,5 +1,5 @@
import { createHash } from 'node:crypto';
-import { existsSync, readFileSync, readdirSync } from 'node:fs';
+import { existsSync, readFileSync } from 'node:fs';
import { dirname, join, relative, resolve } from 'pathslash';
import { glob } from 'tinyglobby';
import { normalizePath, type Plugin, type ResolvedConfig, type ViteDevServer } from 'vite';
@@ -57,32 +57,22 @@ function mdRouteName(file: string, env: 'dev' | 'prod' | null): string {
return name.endsWith('/index') ? name.slice(0, -'/index'.length) : name;
}
-function hasMdFilesWithScript(dir: string): boolean {
- try {
- for (const entry of readdirSync(dir, { withFileTypes: true, recursive: true })) {
- if (entry.isFile() && entry.name.endsWith('.md')) {
- const fullPath = join(entry.parentPath, entry.name);
- const content = readFileSync(fullPath, 'utf-8');
- if (/^
+
+# Script
+
+unset
+`,
+ 'pages/mixed.md': `
+
+# Mixed
+
+unset
+
+
+`,
+ },
+ });
+ let server: PreviewServer | undefined;
+ let browser: Browser | undefined;
+ try {
+ const manifest = JSON.parse(
+ readFileSync(join(build.root, 'dist/client/.vite/manifest.json'), 'utf8'),
+ );
+ expect(manifest).toHaveProperty(['virtual:void-md-client']);
+ // A page without client code still ships no JavaScript.
+ expect(build.page('about.html').html).not.toContain('\n\n# Hello\n',
- );
- writeFileSync(join(root, 'src', 'pages', 'posts', 'Counter.island.tsx'), 'export default {};');
-
- const plugin = createPlugin();
- const config = getHookHandler(plugin.config) as (
+ for (const [file, content] of Object.entries(pages)) {
+ writeFileSync(join(root, 'src', 'pages', file), content);
+ }
+ const config = getHookHandler(createPlugin().config) as (
config: { root: string },
env: { command: 'build' },
- ) => unknown;
+ ) => Promise;
+ return config({ root }, { command: 'build' });
+ }
- expect(config({ root }, { command: 'build' })).toEqual({
+ const CLIENT_CODE = '\n\n# Hello\n';
+ const ISLAND_IMPORT = 'import Counter from "./Counter.tsx" with { island: "load" };';
+
+ it.each([
+ ['a page', { 'posts/hello.md': CLIENT_CODE }],
+ ['a build-only page', { 'stats.prod.md': CLIENT_CODE }],
+ [
+ 'a page that also imports an island',
+ {
+ 'mixed.md': `\n\n\n`,
+ },
+ ],
+ ])('adds the markdown client entry for client code on %s', async (_name, pages) => {
+ expect(await buildConfigFor(pages)).toEqual({
environments: {
client: {
build: {
@@ -147,4 +158,27 @@ describe('voidMarkdown sourceDir support', () => {
},
});
});
+
+ it.each([
+ ['pages without a script', { 'hello.md': '# Hello\n' }],
+ [
+ 'a script with only island imports',
+ { 'hello.md': `\n\n\n` },
+ ],
+ [
+ 'a script tag in a code block',
+ { 'hello.md': '# Hello\n\n```html\n\n```\n' },
+ ],
+ ['client code on a dev-only page', { 'debug.dev.md': CLIENT_CODE, 'hello.md': '# Hello\n' }],
+ [
+ 'island files next to pages without client code',
+ {
+ 'hello.md': `\n\n\n`,
+ 'Counter.island.tsx': 'export default {};',
+ '_x.island.txt': '',
+ },
+ ],
+ ])('does not add the markdown client entry for %s', async (_name, pages) => {
+ expect(await buildConfigFor(pages)).toBeUndefined();
+ });
});