fix: index loading
This commit is contained in:
parent
ba7b264a97
commit
e262a83aac
|
|
@ -125,8 +125,8 @@ export const Sidebar: Component<SidebarProps> = (props) => {
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
onMount(() => {
|
onMount(async () => {
|
||||||
const toc = generateToc();
|
const toc = await generateToc();
|
||||||
setFileTree(toc.fileTree);
|
setFileTree(toc.fileTree);
|
||||||
setPathHeadings(toc.pathHeadings);
|
setPathHeadings(toc.pathHeadings);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@ import { buildFileTree, extractHeadings, extractSection, type TocNode, type File
|
||||||
export { TocNode, FileNode, extractHeadings, buildFileTree, extractSection };
|
export { TocNode, FileNode, extractHeadings, buildFileTree, extractSection };
|
||||||
|
|
||||||
let dataIndex: Record<string, string> | null = null;
|
let dataIndex: Record<string, string> | null = null;
|
||||||
let isDevIndexLoaded = false;
|
let indexLoadPromise: Promise<void> | null = null;
|
||||||
let isCliIndexLoaded = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从索引获取数据
|
* 从索引获取数据
|
||||||
|
|
@ -24,10 +23,54 @@ export function getIndexedPaths(): string[] {
|
||||||
return Object.keys(dataIndex);
|
return Object.keys(dataIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载索引(只加载一次)
|
||||||
|
*/
|
||||||
|
export function ensureIndexLoaded(): Promise<void> {
|
||||||
|
if (indexLoadPromise) return indexLoadPromise;
|
||||||
|
|
||||||
|
indexLoadPromise = (async () => {
|
||||||
|
// 尝试 CLI 环境:从 /__CONTENT_INDEX.json 加载
|
||||||
|
try {
|
||||||
|
const response = await fetch("/__CONTENT_INDEX.json");
|
||||||
|
if (response.ok) {
|
||||||
|
const index = await response.json();
|
||||||
|
dataIndex = { ...dataIndex, ...index };
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// CLI 索引不可用时尝试 dev 环境
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dev 环境:使用 import.meta.glob 加载
|
||||||
|
if (typeof import.meta !== "undefined" && import.meta.glob) {
|
||||||
|
try {
|
||||||
|
// @ts-ignore - 只加载 .md 文件
|
||||||
|
const modules = import.meta.glob("../../content/**/*.md", {
|
||||||
|
as: "raw",
|
||||||
|
eager: true,
|
||||||
|
});
|
||||||
|
const index: Record<string, string> = {};
|
||||||
|
for (const [path, content] of Object.entries(modules)) {
|
||||||
|
const normalizedPath = path.replace("/src/", "/");
|
||||||
|
index[normalizedPath] = content as string;
|
||||||
|
}
|
||||||
|
dataIndex = { ...dataIndex, ...index };
|
||||||
|
} catch (e) {
|
||||||
|
// glob 不可用时忽略
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
return indexLoadPromise;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成目录树(文件树 + 标题结构)
|
* 生成目录树(文件树 + 标题结构)
|
||||||
*/
|
*/
|
||||||
export function generateToc(): { fileTree: FileNode[]; pathHeadings: Record<string, TocNode[]> } {
|
export async function generateToc(): Promise<{ fileTree: FileNode[]; pathHeadings: Record<string, TocNode[]> }> {
|
||||||
|
await ensureIndexLoaded();
|
||||||
|
|
||||||
const paths = getIndexedPaths();
|
const paths = getIndexedPaths();
|
||||||
const fileTree = buildFileTree(paths);
|
const fileTree = buildFileTree(paths);
|
||||||
const pathHeadings: Record<string, TocNode[]> = {};
|
const pathHeadings: Record<string, TocNode[]> = {};
|
||||||
|
|
@ -42,63 +85,13 @@ export function generateToc(): { fileTree: FileNode[]; pathHeadings: Record<stri
|
||||||
return { fileTree, pathHeadings };
|
return { fileTree, pathHeadings };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 在 dev 环境加载 glob 索引
|
|
||||||
*/
|
|
||||||
async function loadDevIndex(): Promise<void> {
|
|
||||||
if (isDevIndexLoaded) return;
|
|
||||||
isDevIndexLoaded = true;
|
|
||||||
|
|
||||||
// @ts-ignore - import.meta.glob 在构建时会被处理
|
|
||||||
if (typeof import.meta !== "undefined" && import.meta.glob) {
|
|
||||||
try {
|
|
||||||
// @ts-ignore - 只加载 .csv 和 .md 文件
|
|
||||||
const modules = import.meta.glob("../../content/**/*.md", {
|
|
||||||
as: "raw",
|
|
||||||
eager: true,
|
|
||||||
});
|
|
||||||
const index: Record<string, string> = {};
|
|
||||||
for (const [path, content] of Object.entries(modules)) {
|
|
||||||
const normalizedPath = path.replace("/src/", "/");
|
|
||||||
index[normalizedPath] = content as string;
|
|
||||||
}
|
|
||||||
dataIndex = { ...dataIndex, ...index };
|
|
||||||
} catch (e) {
|
|
||||||
// glob 不可用时忽略
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 在 CLI 环境从 /__CONTENT_INDEX.json 加载索引
|
|
||||||
*/
|
|
||||||
async function loadCliIndex(): Promise<void> {
|
|
||||||
if (isCliIndexLoaded) return;
|
|
||||||
isCliIndexLoaded = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch("/__CONTENT_INDEX.json");
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Failed to fetch content index");
|
|
||||||
}
|
|
||||||
const index = await response.json();
|
|
||||||
dataIndex = { ...dataIndex, ...index };
|
|
||||||
} catch (e) {
|
|
||||||
// CLI 索引不可用时忽略(可能不在 CLI 环境)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异步加载数据
|
* 异步加载数据
|
||||||
* @param path 数据路径
|
* @param path 数据路径
|
||||||
* @returns 数据内容
|
* @returns 数据内容
|
||||||
*/
|
*/
|
||||||
export async function fetchData(path: string): Promise<string> {
|
export async function fetchData(path: string): Promise<string> {
|
||||||
// CLI 环境:先从 /__CONTENT_INDEX.json 加载索引
|
await ensureIndexLoaded();
|
||||||
await loadCliIndex();
|
|
||||||
|
|
||||||
// dev 环境:加载 glob 索引
|
|
||||||
await loadDevIndex();
|
|
||||||
|
|
||||||
// 首先尝试从索引获取
|
// 首先尝试从索引获取
|
||||||
const indexedData = getIndexedData(path);
|
const indexedData = getIndexedData(path);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue