fix(mdx): correct dynamic index generation for lazy entries (#3116)

* fix: correct mdx dynamic index generation

* fix: avoid unused dynamic path import
This commit is contained in:
eliasfaltin
2026-03-16 21:21:34 +08:00
committed by GitHub
parent 94b6eb5639
commit 31441492e7
8 changed files with 101 additions and 13 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'fumadocs-mdx': patch
---
Fix dynamic index generation so generated `dynamic.ts` imports `node:path` and passes lazy entries to `create.doc()` / `create.docs()` as arrays.
+14 -10
View File
@@ -234,13 +234,6 @@ async function generateDynamicIndexFile(ctx: FileGenContext) {
environment,
outDir,
};
codegen.lines.push(
`import { dynamic } from 'fumadocs-mdx/runtime/dynamic';`,
`import * as Config from '${codegen.formatImportPath(configPath)}';`,
'',
`const create = await dynamic<typeof Config, ${tc}>(Config, ${JSON.stringify(partialOptions)}, ${JSON.stringify(serverOptions)});`,
);
async function generateCollectionObjectEntry(
collection: DocCollectionItem,
absolutePath: string,
@@ -295,14 +288,14 @@ async function generateDynamicIndexFile(ctx: FileGenContext) {
case 'docs': {
const metaGlob = await generateMetaCollectionGlob(ctx, parent.meta, true);
return `await create.docs("${parent.name}", "${getBase(parent)}", ${metaGlob}, ${entries.join(', ')})`;
return `await create.docs("${parent.name}", "${getBase(parent)}", ${metaGlob}, [${entries.join(', ')}])`;
}
case 'doc':
return `await create.doc("${collection.name}", "${getBase(collection)}", ${entries.join(', ')})`;
return `await create.doc("${collection.name}", "${getBase(collection)}", [${entries.join(', ')}])`;
}
}
await codegen.pushAsync(
const objects = await Promise.all(
core.getCollections().map(async (collection) => {
const obj = await generateCollectionObject(collection);
if (!obj) return;
@@ -310,6 +303,17 @@ async function generateDynamicIndexFile(ctx: FileGenContext) {
return `\nexport const ${collection.name} = ${obj};`;
}),
);
const hasDynamicCollection = objects.some(Boolean);
codegen.lines.push(
`import { dynamic } from 'fumadocs-mdx/runtime/dynamic';`,
...(hasDynamicCollection ? [`import path from 'node:path';`] : []),
`import * as Config from '${codegen.formatImportPath(configPath)}';`,
'',
`const create = await dynamic<typeof Config, ${tc}>(Config, ${JSON.stringify(partialOptions)}, ${JSON.stringify(serverOptions)});`,
);
codegen.lines.push(...objects.filter((obj): obj is string => obj !== undefined));
}
async function generateBrowserIndexFile(ctx: FileGenContext) {
@@ -0,0 +1,5 @@
---
title: Folder Test
---
## Folder Test
@@ -0,0 +1,5 @@
---
title: Hello World
---
# Hello World
@@ -0,0 +1 @@
{}
+39
View File
@@ -0,0 +1,39 @@
```ts title="server.ts"
// @ts-nocheck
import { server } from 'fumadocs-mdx/runtime/server';
import type * as Config from './config';
const create = server<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
}
}>({"doc":{"passthroughs":["extractedReferences"]}});
```
```ts title="dynamic.ts"
// @ts-nocheck
import { default as __fd_glob_0 } from "./generate-index-docs/meta.json?collection=docs"
import { dynamic } from 'fumadocs-mdx/runtime/dynamic';
import path from 'node:path';
import * as Config from './config';
const create = await dynamic<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
}
}>(Config, {"configPath":"packages/mdx/test/fixtures/config.ts","environment":"test","outDir":"packages/mdx/test/fixtures"}, {"doc":{"passthroughs":["extractedReferences"]}});
export const docs = await create.docs("docs", "packages/mdx/test/fixtures/generate-index-docs", {"meta.json": __fd_glob_0, }, [{ absolutePath: path.resolve("packages/mdx/test/fixtures/generate-index-docs/index.mdx"), info: {"fullPath":"packages/mdx/test/fixtures/generate-index-docs/index.mdx","path":"index.mdx"}, data: {"title":"Hello World"}, hash: "ff5bb77e7944dd47e09718d8190c76b3" }, { absolutePath: path.resolve("packages/mdx/test/fixtures/generate-index-docs/folder/test.mdx"), info: {"fullPath":"packages/mdx/test/fixtures/generate-index-docs/folder/test.mdx","path":"folder/test.mdx"}, data: {"title":"Folder Test"}, hash: "f003f596f68747454370ba42599464fc" }]);
```
```ts title="browser.ts"
// @ts-nocheck
import { browser } from 'fumadocs-mdx/runtime/browser';
import type * as Config from './config';
const create = browser<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
}
}>();
const browserCollections = {
};
export default browserCollections;
```
+3 -2
View File
@@ -18,6 +18,7 @@ const create = server<typeof Config, import("fumadocs-mdx/runtime/types").Intern
```ts title="dynamic.ts"
// @ts-nocheck
import { dynamic } from 'fumadocs-mdx/runtime/dynamic';
import path from 'node:path';
import * as Config from './config';
const create = await dynamic<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
@@ -31,9 +32,9 @@ const create = await dynamic<typeof Config, import("fumadocs-mdx/runtime/types")
}
}>(Config, {"configPath":"packages/mdx/test/fixtures/config.ts","environment":"test","outDir":"packages/mdx/test/fixtures"}, {"doc":{"passthroughs":["extractedReferences"]}});
export const docs = await create.doc("docs", "packages/mdx/test/fixtures/generate-index", { absolutePath: path.resolve("packages/mdx/test/fixtures/generate-index/index.mdx"), info: {"fullPath":"packages/mdx/test/fixtures/generate-index/index.mdx","path":"index.mdx"}, data: {}, hash: "b12f02f44f5ed3318104c095c455e5ee" }, { absolutePath: path.resolve("packages/mdx/test/fixtures/generate-index/folder/test.mdx"), info: {"fullPath":"packages/mdx/test/fixtures/generate-index/folder/test.mdx","path":"folder/test.mdx"}, data: {}, hash: "d41d8cd98f00b204e9800998ecf8427e" });
export const docs = await create.doc("docs", "packages/mdx/test/fixtures/generate-index", [{ absolutePath: path.resolve("packages/mdx/test/fixtures/generate-index/index.mdx"), info: {"fullPath":"packages/mdx/test/fixtures/generate-index/index.mdx","path":"index.mdx"}, data: {}, hash: "b12f02f44f5ed3318104c095c455e5ee" }, { absolutePath: path.resolve("packages/mdx/test/fixtures/generate-index/folder/test.mdx"), info: {"fullPath":"packages/mdx/test/fixtures/generate-index/folder/test.mdx","path":"folder/test.mdx"}, data: {}, hash: "d41d8cd98f00b204e9800998ecf8427e" }]);
export const blogs = await create.doc("blogs", "packages/mdx/test/fixtures/generate-index", { absolutePath: path.resolve("packages/mdx/test/fixtures/generate-index/index.mdx"), info: {"fullPath":"packages/mdx/test/fixtures/generate-index/index.mdx","path":"index.mdx"}, data: {}, hash: "b12f02f44f5ed3318104c095c455e5ee" }, { absolutePath: path.resolve("packages/mdx/test/fixtures/generate-index/folder/test.mdx"), info: {"fullPath":"packages/mdx/test/fixtures/generate-index/folder/test.mdx","path":"folder/test.mdx"}, data: {}, hash: "d41d8cd98f00b204e9800998ecf8427e" });
export const blogs = await create.doc("blogs", "packages/mdx/test/fixtures/generate-index", [{ absolutePath: path.resolve("packages/mdx/test/fixtures/generate-index/index.mdx"), info: {"fullPath":"packages/mdx/test/fixtures/generate-index/index.mdx","path":"index.mdx"}, data: {}, hash: "b12f02f44f5ed3318104c095c455e5ee" }, { absolutePath: path.resolve("packages/mdx/test/fixtures/generate-index/folder/test.mdx"), info: {"fullPath":"packages/mdx/test/fixtures/generate-index/folder/test.mdx","path":"folder/test.mdx"}, data: {}, hash: "d41d8cd98f00b204e9800998ecf8427e" }]);
```
```ts title="browser.ts"
+29 -1
View File
@@ -3,7 +3,7 @@ import * as path from 'node:path';
import { expect, test } from 'vitest';
import { z } from 'zod';
import { ValidationError } from '@/utils/validation';
import { defineCollections, defineConfig } from '@/config';
import { defineCollections, defineConfig, defineDocs } from '@/config';
import { fumaMatter } from '@/utils/fuma-matter';
import { buildConfig } from '@/config/build';
import { createCore } from '@/core';
@@ -114,6 +114,17 @@ const cases: {
}),
},
},
{
name: 'dynamic-docs',
config: {
docs: defineDocs({
dir: path.join(baseDir, './fixtures/generate-index-docs'),
docs: {
dynamic: true,
},
}),
},
},
{
name: 'workspace',
config: {
@@ -163,6 +174,23 @@ for (const { name, config } of cases) {
.map((entry) => `\`\`\`ts title="${entry.path}"\n${entry.content}\n\`\`\``)
.join('\n\n');
if (name === 'dynamic') {
expect(markdown).toContain(`import path from 'node:path';`);
expect(markdown).toContain(
'create.doc("docs", "packages/mdx/test/fixtures/generate-index", [',
);
expect(markdown).toContain(
'create.doc("blogs", "packages/mdx/test/fixtures/generate-index", [',
);
}
if (name === 'dynamic-docs') {
expect(markdown).toContain(`import path from 'node:path';`);
expect(markdown).toMatch(
/create\.docs\("docs", "packages\/mdx\/test\/fixtures\/generate-index-docs", [\s\S]+, \[/,
);
}
await expect(markdown).toMatchFileSnapshot(`./fixtures/index-${name}.output.md`);
});
}