This commit is contained in:
2025-03-21 22:40:00 +08:00
parent 7a4578c16d
commit 6e921e82fb
12 changed files with 146 additions and 19 deletions

View File

@@ -0,0 +1,68 @@
import { useState, useCallback, useEffect } from 'react';
import dynamic from 'next/dynamic';
export interface WidgetModule {
id: string;
name: string;
version: string;
component: ReturnType<typeof dynamic>;
}
export const useDynamicWidgets = (): {
widgets: WidgetModule[];
refreshWidgets: () => Promise<void>;
} => {
const [widgets, setWidgets] = useState<WidgetModule[]>([]);
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 };
};