refactor(doc-data): Use static imports for doc entries

This commit is contained in:
hyper 2026-06-30 18:54:34 +08:00
parent d72d4e7bde
commit a05b0f4291
2 changed files with 59 additions and 47 deletions

View File

@ -27,52 +27,59 @@ function getBody(raw: string): string {
return match ? match[1] : raw; return match ? match[1] : raw;
} }
/** Glob import all .md files in src/doc-entries/ */ function parseEntry(raw: string): DocEntry | null {
const modules = import.meta.webpackContext("./", { const fm = parseFrontmatter(raw);
recursive: false, if (!fm) return null;
regExp: /\.md$/, return {
}); tag: fm.tag as string,
icon: fm.icon as string,
/** Lazy-loaded doc entries, parsed on first access. */ title: fm.title as string,
let _entries: DocEntry[] | null = null; description: fm.description as string,
syntax: fm.syntax as string,
export function loadDocEntries(): DocEntry[] { props: (fm.props as DocEntry["props"]) ?? [],
if (_entries) return _entries; body: getBody(raw),
};
const entries: DocEntry[] = []; }
for (const key of modules.keys()) { // Static imports each .md file is asset/source so imports are strings.
const mod = modules(key); // Add a new import here when creating a new doc entry.
const raw = import mdDiceRaw from "../doc-entries/md-dice.md";
typeof mod === "string" import mdTableRaw from "../doc-entries/md-table.md";
? mod import mdLinkRaw from "../doc-entries/md-link.md";
: ((mod as { default?: string }).default ?? ""); import mdPinsRaw from "../doc-entries/md-pins.md";
if (!raw) continue; import mdFontRaw from "../doc-entries/md-font.md";
import mdBgRaw from "../doc-entries/md-bg.md";
const fm = parseFrontmatter(raw); import mdBorderRaw from "../doc-entries/md-border.md";
if (!fm) continue; import mdEmbedRaw from "../doc-entries/md-embed.md";
import mdDeckRaw from "../doc-entries/md-deck.md";
const body = getBody(raw); import mdYarnRaw from "../doc-entries/md-yarn-spinner.md";
import mdTokenRaw from "../doc-entries/md-token.md";
entries.push({ import mdTokenViewerRaw from "../doc-entries/md-token-viewer.md";
tag: fm.tag as string, import mdCommanderRaw from "../doc-entries/md-commander.md";
icon: fm.icon as string,
title: fm.title as string, const rawDocuments: string[] = [
description: fm.description as string, mdDiceRaw,
syntax: fm.syntax as string, mdTableRaw,
props: (fm.props as DocEntry["props"]) ?? [], mdLinkRaw,
body, mdPinsRaw,
}); mdFontRaw,
} mdBgRaw,
mdBorderRaw,
// Sort alphabetically by tag mdEmbedRaw,
entries.sort((a, b) => a.tag.localeCompare(b.tag)); mdDeckRaw,
_entries = entries; mdYarnRaw,
return entries; mdTokenRaw,
mdTokenViewerRaw,
mdCommanderRaw,
];
let _entries: DocEntry[] | null = null;
function loadDocEntries(): DocEntry[] {
if (_entries) return _entries;
_entries = rawDocuments.map(parseEntry).filter(Boolean) as DocEntry[];
_entries.sort((a, b) => a.tag.localeCompare(b.tag));
return _entries;
} }
/**
* Direct static array for the DocDialog sidebar uses webpackContext
* so all .md files in doc-entries/ are bundled automatically.
*/
export const docEntries = loadDocEntries(); export const docEntries = loadDocEntries();

7
src/global.d.ts vendored
View File

@ -11,6 +11,11 @@ interface ImportMeta {
options: { options: {
recursive?: boolean; recursive?: boolean;
regExp?: RegExp; regExp?: RegExp;
} },
): WebpackContext; ): WebpackContext;
} }
declare module "*.md" {
const content: string;
export default content;
}