import { useState, useCallback, useEffect } from 'react'; import dynamic from 'next/dynamic'; export interface WidgetModule { id: string; name: string; version: string; component: ReturnType; } export const useDynamicWidgets = (): { widgets: WidgetModule[]; refreshWidgets: () => Promise; } => { const [widgets, setWidgets] = useState([]); const loadWidgets = useCallback(async () => { try { // Webpack 的 require.context 匹配 widgets 目录 const context = require.context('../widgets', true, /\/index\.tsx$/); console.log("[DEBUG] Matched files:", context.keys()); const modules = await Promise.all( context.keys().map(async (key) => { const folderName = key.split('/')[1]; // 动态导入元数据 console.log("[DEBUG] import files:", `../widgets/${folderName}/index.tsx`); const meta = await import(`../widgets/${folderName}/index.tsx`); // 创建动态组件(单独导入确保 Tree Shaking) const Component = dynamic( () => import(`../widgets/${folderName}/index.tsx`), { ssr: false } ); return { id: meta.id, name: meta.name, version: meta.version, component: Component }; }) ); console.log(modules); setWidgets(modules); } catch (error) { console.error('Failed to load widgets:', error); setWidgets([]); } }, []); // 初始化加载 useEffect(() => { loadWidgets(); }, [loadWidgets]); // 暴露刷新方法 const refreshWidgets = useCallback(async () => { await loadWidgets(); }, [loadWidgets]); return { widgets, refreshWidgets }; };