微前端SDK@1.0
项目介绍
整个
SDK都是围绕sdk.app.user、sdk.app.menus进行设计的,旨在简化微前端应用的开发主应用
sdk.use(plugin, opts).mount('sdk')→ 微应用sdk.extend('sdk')→ 共享同一套状态与能力架构图
具体使用
主应用
创建
Vite项目1
npm create vite@latest
安装
@zxiaosi/sdk、react-router-dom@6、qiankun依赖1
npm install @zxiaosi/sdk react-router-dom@6 qiankun
在
src文件夹下创建sdk.config.ts文件,并进行SDK的配置1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import {
sdk,
SDKApiPlugin,
SDKAppPlugin,
SDKComponentsPlugin,
SDKConfigPlugin,
SDKI18nPlugin,
SDKRouterPlugin,
SDKStoragePlugin,
SDKStorePlugin,
} from "@zxiaosi/sdk";
import { loadMicroApp } from "qiankun";
sdk
.use(SDKApiPlugin)
.use(SDKAppPlugin, { loadMicroApp })
.use(SDKComponentsPlugin)
.use(SDKConfigPlugin)
.use(SDKI18nPlugin)
.use(SDKRouterPlugin)
.use(SDKStoragePlugin)
.use(SDKStorePlugin)
.mount("sdk");在
src/main.ts中引入sdk.config.ts文件1
2
3
4
5import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import "./sdk.config.ts";
createRoot(document.getElementById("root")!).render(<App />);运行项目
npm run dev,并在控制台输入sdk查看SDK是否初始化成功在
src/App.tsx中使用sdk1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97import { sdk } from "@zxiaosi/sdk";
import { useEffect, useState } from "react";
import {
Navigate,
RouterProvider,
createBrowserRouter,
useLocation,
useMatches,
useNavigate,
} from "react-router-dom";
const loader = (loading: boolean) => sdk.store.getState().setMicroAppLoading(loading);
const microApps = [
{
name: "subapp1",
container: "#sub-app",
entry: "http://localhost:5174",
loader: loader,
props: { sdk },
},
{
name: "subapp2",
container: "#sub-app",
entry: "http://localhost:5175",
loader: loader,
props: { sdk },
},
];
/** 记录路由信息 */
const WithRouter = ({ children }: any) => {
sdk.router.location = useLocation();
sdk.router.matches = useMatches();
sdk.router.navigate = useNavigate();
return children;
};
function App() {
const loginPath = sdk.config.loginPath;
const renderComponent = sdk.components.renderComponent;
const defaultRoutes = [
{ path: loginPath, element: renderComponent("Login") },
{ path: "*", element: <div>404</div> },
].map((_) => ({ ..._, element: <WithRouter>{_.element}</WithRouter> }));
const [routes, setRoutes] = useState(defaultRoutes);
const initData = () => {
sdk.app.user = { name: "zxiaosi" };
sdk.app.microApps = microApps;
sdk.app.menus = [
{ key: "Home", name: "Home", path: "/home", element: <div>Home</div> },
{
key: "Subapp1",
name: "Subapp1",
path: "/subapp1",
element: renderComponent("Microapp", { name: "subapp1", rootId: "sub-app" }),
},
{
key: "Subapp2",
name: "Subapp2",
path: "/subapp2",
element: renderComponent("Microapp", { name: "subapp2", rootId: "sub-app" }),
},
];
const allRoutes = [
...defaultRoutes,
{ path: "/", element: <Navigate to={"/home"} replace /> },
{
path: "/",
element: <WithRouter>{renderComponent("Layout")}</WithRouter>,
children: sdk.app.menus,
},
];
setRoutes(allRoutes);
};
useEffect(() => {
sdk.app.initData = initData;
const pathName = window.location.pathname;
if ([loginPath].includes(pathName)) return;
initData();
}, []);
return (
<RouterProvider router={createBrowserRouter(routes)} future={{ v7_startTransition: false }} />
);
}
export default App;
微应用
创建
Vite项目1
npm create vite@latest
安装
@zxiaosi/sdk、vite-plugin-qiankun-lite依赖1
2npm install @zxiaosi/sdk
npm install vite-plugin-qiankun-lite -d在
vite.config.ts中配置vite-plugin-qiankun-lite插件1
2
3
4
5
6
7
8
9
10import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import qiankun from "vite-plugin-qiankun-lite";
export default defineConfig({
plugins: [react(), qiankun({ name: "subapp", sandbox: !!process.env.VITE_SANDBOX })],
server: {
port: 5174,
},
});在
src/main.ts中进行SDK的继承1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38import { sdk } from "@zxiaosi/sdk";
import { createRoot, type Root } from "react-dom/client";
import App from "./App.tsx";
import { name } from "../package.json";
let root: Root;
const render = (props: any = {}) => {
const container = props?.container
? props.container.querySelector("#root")
: document.getElementById("root");
root = createRoot(container);
root.render(<App />);
};
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap() {
console.log(`${name} bootstrap`);
}
export async function mount(props: any) {
console.log(`${name} mount`, props);
sdk.extend(props?.sdk?.name); // 继承 sdk 功能
render(props);
}
export async function unmount(props: any) {
console.log(`${name} unmount`, props);
root.unmount();
}
export async function update(props: any) {
console.log(`${name} update`, props);
}
自定义插件
插件内容
name和install1
2
3
4
5
6
7
8
9
10
11
12
13import type { SDKPlugin } from "@zxiaosi/sdk";
/** 插件名称 */
const pluginName = "test";
const SDKTestPlugin: SDKPlugin<"test"> = {
name: pluginName,
install(sdk, options = {}) {
sdk[pluginName] = options;
},
};
export { SDKTestPlugin };插件类型
1
2
3
4
5
6
7
8
9
10// vite-env.d.ts
import "@zxiaosi/sdk";
declare module "@zxiaosi/sdk" {
interface SDKPlugins {
/** 自定义插件 **/
test: {};
}
}使用插件
1
sdk.use(SDKTestPlugin).mount("sdk");
注意事项
SDK 未初始化
SDK不能直接进行使用,否则会报SDK 未初始化错误可以在
组件中或者方法中中使用1
2
3
4
5
6const handle = () => { sdk.xxx };
const App = () => {
sdk.xxx
return <></>
}
React 多实例
微应用使用
sdk.components.renderComponent('xxx')时,会报React 多实例的错误,需要使用vite-plugin-externals插件将React等依赖排除在打包之外。更多详情在
主应用的index.html中使用cdn的方式去加载react和react-dom包1
2
3
4
5
6
7
8
9
10
11
12
<html lang="en">
<head>
<title>%VITE_APP_TITLE%</title>
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>在
主/微应用中使用vite-plugin-externals插件去排除react和react-dom包1
2
3
4
5
6
7
8
9
10
11
12
13
14import { viteExternalsPlugin } from "vite-plugin-externals";
export default defineConfig({
plugins: [
viteExternalsPlugin({
react: "React",
// 开发环境不排除 react-dom 依赖, 防止热更新失效
// 或者 浏览器安装 React Developer Tools 插件
"react-dom": "ReactDOM",
"react-dom/client": "ReactDOM",
}),
],
});
相关技术
Tsdown: 对
SDK进行打包Qiankun: 微前端框架
React: 前端框架
Vite: 前端构建工具
vite-plugin-qiankun-lite:
Vite-Qiankun插件









