let dataIndex: Record | null = null; let isDevIndexLoaded = false; let isCliIndexLoaded = false; /** * 设置全局数据索引(CLI 环境使用) */ export function setDataIndex(index: Record) { dataIndex = index; } /** * 从索引获取数据 */ function getIndexedData(path: string): string | null { if (dataIndex && dataIndex[path]) { return dataIndex[path]; } return null; } /** * 在 dev 环境加载 glob 索引 */ async function loadDevIndex(): Promise { 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/**/*.{csv,md}', { as: 'raw', eager: true }); const index: Record = {}; 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 { 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 数据路径 * @returns 数据内容 */ export async function fetchData(path: string): Promise { // CLI 环境:先从 /__CONTENT_INDEX.json 加载索引 await loadCliIndex(); // dev 环境:加载 glob 索引 await loadDevIndex(); // 首先尝试从索引获取 const indexedData = getIndexedData(path); if (indexedData) { return indexedData; } // 索引不存在时,使用 fetch 加载 try { const response = await fetch(path); if (!response.ok) { throw new Error(`Failed to fetch: ${path}`); } return await response.text(); } catch (error) { console.error('fetchData error:', error); throw error; } }