
本文介绍如何在 Vite 构建的 React 应用中,将一个 Material UI 表格组件(如 YourTableComponent)抽离为轻量、自包含、可跨域嵌入的独立 Widget,通过 iframe 集成到当前应用或其他任意网页中。
本文介绍如何在 vite 构建的 react 应用中,将一个 material ui 表格组件(如 `yourtablecomponent`)抽离为轻量、自包含、可跨域嵌入的独立 widget,通过 iframe 集成到当前应用或其他任意网页中。
要将 React 应用中的单个组件(例如一个 Material UI 数据表格)转化为可复用的 Widget,并非必须打包整个应用——关键在于构建一个隔离、自启动、无上下文依赖的轻量入口页面。以下是完整实现路径:
✅ 步骤一:创建自包含的 Widget 组件
确保该组件不依赖 App 的全局状态(如 Redux store、Context Provider 或路由参数)。所有数据应通过 props 传入,或在组件内部通过独立 API 请求获取:
// src/widgets/WidgetTable.tsx
import React, { useEffect, useState } from 'react';
import { DataGrid, GridColDef } from '@mui/x-data-grid';
const WidgetTable = () => {
const [rows, setRows] = useState<any>([]);
const columns: GridColDef[] = [
{ field: 'id', headerName: 'ID', width: 90 },
{ field: 'name', headerName: 'Name', width: 150 },
];
useEffect(() => {
// 示例:独立请求,避免使用全局 axios 实例或 store
fetch('/api/widget-data')
.then(res => res.json())
.then(data => setRows(data));
}, []);
return (
<div style="{{" height: width:>
<h3 style="{{" margin: fontsize:>? Analytics Widget</h3>
<datagrid rows="{rows}" columns="{columns}" disableselectiononclick></datagrid>
</div>
);
};
export default WidgetTable;</any>
⚠️ 注意:移除对
BrowserRouter、AppProvider等父级 Context 的依赖;若需主题一致性,可手动引入 MUIcreateTheme并用ThemeProvider包裹。
✅ 步骤二:新建专用 Widget 页面(入口路由)
在 src/pages/WidgetPage.tsx 中仅渲染该组件,不挂载任何主应用布局、导航或样式污染:
// src/pages/WidgetPage.tsx
import WidgetTable from '../widgets/WidgetTable';
export default function WidgetPage() {
return (
<div style="{{" margin: padding: fontfamily: sans-serif>
<widgettable></widgettable>
</div>
);
}
并在 src/main.tsx 中为该页面添加独立路由(推荐使用 Vite 的 @vitejs/plugin-react-swc + 原生 HTML 入口,而非复杂路由系统):
// src/main-widget.tsx —— 专用于 widget 构建的入口文件
import React from 'react';
import ReactDOM from 'react-dom/client';
import WidgetPage from './pages/WidgetPage';
ReactDOM.createRoot(document.getElementById('root')!).render(
<react.strictmode><widgetpage></widgetpage></react.strictmode>
);
✅ 步骤三:配置 Vite 构建为独立微应用
修改 vite.config.ts,新增 widget 构建目标(与主应用分离):
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
build: {
rollupOptions: {
external: ['react', 'react-dom'], // 排除 React 运行时,减小包体积
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM',
},
},
},
lib: {
entry: 'src/main-widget.tsx',
name: 'WidgetBundle',
formats: ['umd'],
fileName: (format) => `widget.${format}.js`,
},
outDir: 'dist/widget',
},
});
运行 vite build --config vite.config.ts 后,dist/widget/ 下将生成 widget.umd.js 和配套 HTML(可手动补全最小 index.html),但更推荐直接使用 路由托管方式(见下一步)。
Orderly React SDK 钩子使用参考指南,包括 useOrderEntry、usePositionStream、useOrderbookStream、useCollateral 等。
✅ 步骤四:启用独立路由并嵌入 iframe
在 vite.config.ts 中配置开发/生产环境下的路由代理或静态路由支持(Vite 默认支持):
// vite.config.ts(补充)
export default defineConfig({
// ...其他配置
server: {
port: 3000,
},
// 使 /widget 路由指向 WidgetPage
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
});
然后在 src/router.ts(若使用 react-router)或直接在 main.tsx 中添加路由规则(推荐使用 @tanstack/react-router 或简易条件渲染),但最简单可靠的方式是:
✅ 在 src/App.tsx 中添加一条路由:
<route path="/widget" element="{<WidgetPage"></route>} />
构建部署后,即可通过以下方式嵌入任意网站:
<iframe title="Analytics Widget" src="https://your-domain.com/widget" width="100%" height="420" frameborder="0" sandbox="allow-scripts allow-same-origin" loading="lazy"></iframe>
? 安全提示:务必在服务端设置
Content-Security-Policy与X-Frame-Options: ALLOW-FROM ...(或使用frame-ancestors)以控制合法嵌入来源;生产环境建议启用sandbox属性限制脚本权限。
✅ 总结
将单个 React 组件转为 Widget 的核心原则是:解耦、轻量、自治。无需改造整站架构,只需:
- 创建无副作用的纯组件;
- 提供最小化 HTML/JS 入口;
- 通过路由隔离暴露独立 URL;
- 用 iframe 安全嵌入。
这种方式兼容 Next.js、Remix、甚至非 React 项目,真正实现「一次开发,多端复用」。










