@seed-fe/mf-adapters 1.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +175 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +352 -0
- package/dist/index.d.ts +352 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 XiangHongAi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# @seed-fe/mf-adapters
|
|
2
|
+
|
|
3
|
+
React / Vue / 任意前端微应用在 Garfish / qiankun 等微前端宿主中的适配工具集。
|
|
4
|
+
|
|
5
|
+
> 本包不关心具体 UI 框架,只约定:微应用提供 `initRuntime`、`mountApp`、`startStandalone` 三个函数,适配层负责把它们接成各宿主需要的生命周期和宿主检测。
|
|
6
|
+
|
|
7
|
+
## 环境要求
|
|
8
|
+
|
|
9
|
+
- **运行环境**: 仅支持浏览器环境
|
|
10
|
+
- Garfish / qiankun 是纯浏览器运行时微前端框架
|
|
11
|
+
- 不支持 SSR / Node.js 环境(这些场景应使用独立 SSR 或 BFF 组合方案)
|
|
12
|
+
- 代码中直接访问 `window` 全局对象,不提供 SSR 兼容层
|
|
13
|
+
|
|
14
|
+
- **多实例支持**: 当前为单实例实现
|
|
15
|
+
- 适配层(Garfish / qiankun adapter)使用 `Map` 结构,从设计上支持多实例
|
|
16
|
+
- 微应用示例实现为单实例模式(全局唯一 root / standalone instance)
|
|
17
|
+
- 如需同一微应用多容器挂载,需微应用侧改为 `Map<container, root>` 实现
|
|
18
|
+
|
|
19
|
+
## 安装
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm add @seed-fe/mf-adapters
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**依赖说明**:
|
|
26
|
+
|
|
27
|
+
- `@seed-fe/logger` 会作为依赖自动安装
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 核心概念:basename
|
|
32
|
+
|
|
33
|
+
`basename` 是微应用的路由基础路径,用于配置路由库(如 React Router)。
|
|
34
|
+
|
|
35
|
+
### 特点
|
|
36
|
+
|
|
37
|
+
- **定义**: 微应用的路由基础路径
|
|
38
|
+
- **来源**: 宿主根据配置计算后通过 `app.basename` 传递
|
|
39
|
+
- **用途**: 配置微应用内部的路由库(如 `<BrowserRouter basename="/products" />`)
|
|
40
|
+
- **示例**: `"/products"`, `"/orders"`, `"/users"`
|
|
41
|
+
- **说明**: 宿主负责处理前后斜杠,微应用直接使用即可
|
|
42
|
+
|
|
43
|
+
### 使用示例
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// 宿主框架传递给微应用
|
|
47
|
+
renderApp({
|
|
48
|
+
container: document,
|
|
49
|
+
props: {
|
|
50
|
+
app: {
|
|
51
|
+
name: "product-app",
|
|
52
|
+
basename: "/products", // ← 路由基础路径
|
|
53
|
+
version: "1.0.0"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
// 微应用使用
|
|
59
|
+
function App({ app }: RuntimeProps) {
|
|
60
|
+
return (
|
|
61
|
+
<BrowserRouter basename={app?.basename}>
|
|
62
|
+
<Routes>
|
|
63
|
+
<Route path="/" element={<ProductList />} /> // 实际 URL: /products/
|
|
64
|
+
<Route path="/detail/:id" element={<ProductDetail />} /> // 实际 URL: /products/detail/123
|
|
65
|
+
</Routes>
|
|
66
|
+
</BrowserRouter>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
下面仅展示"在微应用中如何接入"的示例,分别对应当前使用的两个微前端库:
|
|
74
|
+
|
|
75
|
+
1. Garfish(容器现用)
|
|
76
|
+
2. qiankun(标准生命周期)
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 在微应用中统一接入(Garfish + qiankun)
|
|
81
|
+
|
|
82
|
+
推荐在微应用中创建一个统一的适配入口,例如:`src/mf-adapters/runtime.ts`。
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
// src/mf-adapters/runtime.ts
|
|
86
|
+
import { createMicroAppRuntime } from '@seed-fe/mf-adapters';
|
|
87
|
+
import type { InitRuntimeFn, RenderAppFn, StartStandaloneFn } from '@seed-fe/mf-adapters';
|
|
88
|
+
|
|
89
|
+
// 使用类型别名,获得完整类型提示
|
|
90
|
+
const initRuntime: InitRuntimeFn = async () => {
|
|
91
|
+
// 初始化权限、认证、i18n 等
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const renderApp: RenderAppFn = ({ container, props }) => {
|
|
95
|
+
const root = createRoot(container as HTMLElement);
|
|
96
|
+
root.render(<App {...props} />);
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
unmount() {
|
|
100
|
+
root.unmount();
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const startStandaloneApp: StartStandaloneFn = async (options) => {
|
|
106
|
+
await initRuntime();
|
|
107
|
+
return renderApp({
|
|
108
|
+
container: options?.container ?? document,
|
|
109
|
+
props: options?.props,
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// 创建运行时适配实例:内部完成 Garfish / qiankun 等宿主的适配与宿主检测
|
|
114
|
+
export const microAppRuntime = createMicroAppRuntime({
|
|
115
|
+
initRuntime,
|
|
116
|
+
mountApp: renderApp,
|
|
117
|
+
startStandalone: startStandaloneApp,
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
在应用入口中,仅需要引入这一文件即可触发宿主检测与独立模式回退:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
// src/mf-adapters/index.ts
|
|
125
|
+
import { microAppRuntime } from './runtime';
|
|
126
|
+
|
|
127
|
+
// 对于 qiankun 场景,按需导出生命周期(Garfish 无需额外导出)
|
|
128
|
+
export const { bootstrap, mount, unmount } = microAppRuntime.qiankun ?? {};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
然后在 `main.tsx` 入口中重导出生命周期:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
// src/main.tsx
|
|
135
|
+
export { bootstrap, mount, unmount } from '@/mf-adapters';
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**重要说明**:
|
|
139
|
+
|
|
140
|
+
- ✅ 必须使用 `export { ... } from '@/mf-adapters'` 导出生命周期函数
|
|
141
|
+
- ❌ 不能使用 `import '@/mf-adapters'`(副作用导入无法导出,qiankun 会报错 `lifecycleHook is not a function`)
|
|
142
|
+
- Garfish 会自动通过 `__GARFISH_EXPORTS__.provider` 获取 provider,无需手动导出
|
|
143
|
+
- qiankun 需要微应用入口模块导出 `bootstrap`/`mount`/`unmount` 函数
|
|
144
|
+
|
|
145
|
+
这样,微应用侧只需要维护一个接收 `initRuntime` / `mountApp` / `startStandalone` 的函数调用,其余 Garfish / qiankun 的具体适配逻辑都在 `@seed-fe/mf-adapters` 中统一实现。
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Garfish 宿主行为(容器现用)
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
// 内部逻辑(无需在微应用中手写):
|
|
153
|
+
// - 当 window.__GARFISH__ 为 true 且存在 __GARFISH_EXPORTS__ 时:
|
|
154
|
+
// - 自动创建 Garfish provider
|
|
155
|
+
// - 将 provider 赋值给 __GARFISH_EXPORTS__.provider
|
|
156
|
+
// - 宿主通过 Garfish 标准机制挂载微应用
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
- 适配层内部使用 `Map<Document, AppInstance>` 管理实例,支持同一应用在多个容器中挂载
|
|
160
|
+
- 微应用只需要确保 `initRuntime` 幂等、`renderApp` 返回的实例提供 `unmount()` 即可
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## qiankun 宿主行为(标准生命周期导出)
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
// 微应用侧只需在统一入口中导出生命周期:
|
|
168
|
+
// src/mf-adapters/index.ts
|
|
169
|
+
import { microAppRuntime } from './runtime';
|
|
170
|
+
|
|
171
|
+
export const { bootstrap, mount, unmount } = microAppRuntime.qiankun ?? {};
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
- 微应用侧暴露标准的 qiankun 生命周期
|
|
175
|
+
- 每个 `container` 对应一个 `AppInstance`,适配层内部同样用 Map 管理实例,方便宿主做多实例或保活
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var c=require('@seed-fe/logger');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var c__default=/*#__PURE__*/_interopDefault(c);var R=false;async function _(p){if(R)return;let{hosts:o,fallback:i}=p;for(let n of o)if(n.detect()){c__default.default.info(`[mf-runtime] detected micro-frontend host: ${n.name}`);try{await n.activate?.(),R=!0,c__default.default.info(`[mf-runtime] activated micro-frontend host: ${n.name}`);return}catch(s){c__default.default.error(`[mf-runtime] failed to activate ${n.name}, trying fallback`,s);}}R||(c__default.default.info("[mf-runtime] fallback to standalone mode"),await i());}function h(p){let{initRuntime:o,renderApp:i}=p,n=new Map;function s(){return {render(t){return o().then(()=>{let r=i({container:t.dom,props:{...t.props,app:t.props?.app}});n.set(t.dom,r),c__default.default.info(`[mf-runtime][garfish] rendered successfully: ${t.appName}`);}).catch(r=>{throw c__default.default.error(`[mf-runtime][garfish] render failed: ${t.appName}`,r),n.delete(t.dom),r})},destroy(t){try{let r=n.get(t.dom);r&&r.unmount(),n.delete(t.dom),c__default.default.info("[mf-runtime][garfish] destroy completed");}catch(r){c__default.default.error("[mf-runtime][garfish] destroy failed",r);}}}}return {provider:s}}function y(p){let{initRuntime:o,renderApp:i}=p,n=new Map;async function s(){try{await o(),c__default.default.info("[mf-runtime][qiankun] bootstrap completed");}catch(a){throw c__default.default.error("[mf-runtime][qiankun] bootstrap failed",a),a}}function t(a){try{let e=a.container??document,u=i({container:e,props:{...a,app:a.app}});n.set(e,u),c__default.default.info("[mf-runtime][qiankun] mount completed");}catch(e){throw c__default.default.error("[mf-runtime][qiankun] mount failed",e),e}}function r(a){try{let e=a?.container??document;n.get(e)?.unmount(),n.delete(e),c__default.default.info("[mf-runtime][qiankun] unmount completed");}catch(e){throw c__default.default.error("[mf-runtime][qiankun] unmount failed",e),e}}return {bootstrap:s,mount:t,unmount:r}}function M(p){let{initRuntime:o,mountApp:i,startStandalone:n,hosts:s,extraHosts:t}=p,r=s?.garfish??true,a=s?.qiankun??true,e=[];if(r){let{provider:d}=h({initRuntime:o,renderApp:m=>i({container:m.container,props:m.props})});if(typeof window<"u"&&window.__GARFISH__){let m=globalThis;m.__GARFISH_EXPORTS__||(m.__GARFISH_EXPORTS__={}),m.__GARFISH_EXPORTS__.provider=d;}e.push({name:"garfish",detect:()=>!!window.__GARFISH__,activate:()=>{typeof __GARFISH_EXPORTS__<"u"&&(__GARFISH_EXPORTS__.provider=d);}});}let u;if(a){let{bootstrap:d,mount:m,unmount:g}=y({initRuntime:o,renderApp:i});u={bootstrap:d,mount:m,unmount:g},e.push({name:"qiankun",detect:()=>!!window.__POWERED_BY_QIANKUN__,activate:()=>{c__default.default.info("[mf-adapter] qiankun");}});}return t?.length&&e.push(...t),_({hosts:e,fallback:()=>n()}),{startStandaloneApp:n,qiankun:u}}function T(p){let{initRuntime:o,renderApp:i}=p,n=null;return async function(t){return n||(await o(),n=i({container:t?.container??document,props:t?.props}),n)}}exports.createGarfishAdapter=h;exports.createMicroAppRuntime=M;exports.createQiankunAdapter=y;exports.createStandaloneStarter=T;exports.initMicroFrontendHosts=_;//# sourceMappingURL=index.cjs.map
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/hostManager.ts","../src/hosts/garfish.ts","../src/hosts/qiankun.ts","../src/core/setup.ts","../src/core/standalone.ts"],"names":["microFrontendResolved","initMicroFrontendHosts","options","hosts","fallback","host","logger","error","createGarfishAdapter","initRuntime","renderApp","instances","provider","params","instance","createQiankunAdapter","bootstrap","mount","props","container","unmount","createMicroAppRuntime","mountApp","startStandalone","extraHosts","garfishEnabled","qiankunEnabled","hostAdapters","garfishOptions","globalWithExports","qiankunRuntime","createStandaloneStarter","standaloneInstance","customOptions"],"mappings":"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","file":"index.cjs","sourcesContent":["import logger from '@seed-fe/logger';\nimport type { AppInstance } from '../types/base';\n\nexport interface HostAdapterConfig {\n name: string;\n /**\n * 返回 true 表示当前宿主命中\n */\n detect(): boolean;\n /**\n * 命中宿主后调用,用于注册生命周期或执行初始化逻辑\n */\n activate?(): void | Promise<void>;\n}\n\nexport interface HostManagerOptions {\n hosts: HostAdapterConfig[];\n /**\n * 当未检测到任何宿主标识时的回退逻辑,一般为 startStandaloneApp\n */\n fallback: () => Promise<AppInstance> | Promise<unknown>;\n}\n\nlet microFrontendResolved = false;\n\n/**\n * 根据宿主环境动态选择微前端框架,若未检测到宿主则回退为独立运行模式。\n */\nexport async function initMicroFrontendHosts(options: HostManagerOptions): Promise<void> {\n if (microFrontendResolved) {\n return;\n }\n\n const { hosts, fallback } = options;\n\n for (const host of hosts) {\n if (host.detect()) {\n logger.info(`[mf-runtime] detected micro-frontend host: ${host.name}`);\n\n try {\n await host.activate?.();\n microFrontendResolved = true;\n logger.info(`[mf-runtime] activated micro-frontend host: ${host.name}`);\n return;\n } catch (error) {\n logger.error(`[mf-runtime] failed to activate ${host.name}, trying fallback`, error);\n // 继续尝试下一个宿主或回退到独立模式\n }\n }\n }\n\n // 如果所有宿主激活失败或未检测到任何宿主,调用 fallback\n if (!microFrontendResolved) {\n logger.info('[mf-runtime] fallback to standalone mode');\n await fallback();\n }\n}\n","import logger from '@seed-fe/logger';\nimport type { AdapterOptions, AppInstance } from '../types/base';\nimport type { GarfishDestroyParams, GarfishRenderParams } from '../types/garfish';\n\n/**\n * 创建 Garfish 适配器:\n * - 提供 provider() 给 Garfish 宿主使用\n * - 内部通过 Map<Document, AppInstance> 管理实例,支持多容器挂载\n * - 不关心具体渲染实现细节(React/Vue/纯 DOM 等)\n */\nexport function createGarfishAdapter(options: AdapterOptions) {\n const { initRuntime, renderApp } = options;\n\n const instances = new Map<Document, AppInstance>();\n\n function provider() {\n return {\n render(params: GarfishRenderParams) {\n return initRuntime()\n .then(() => {\n const instance = renderApp({\n container: params.dom,\n props: {\n ...params.props,\n app: params.props?.app,\n },\n });\n instances.set(params.dom, instance);\n logger.info(`[mf-runtime][garfish] rendered successfully: ${params.appName}`);\n })\n .catch((error: Error) => {\n logger.error(`[mf-runtime][garfish] render failed: ${params.appName}`, error);\n // 清理可能的部分状态\n instances.delete(params.dom);\n // 重新抛出,让 Garfish 处理\n throw error;\n });\n },\n destroy(params: GarfishDestroyParams) {\n try {\n const instance = instances.get(params.dom);\n if (instance) {\n instance.unmount();\n }\n instances.delete(params.dom);\n logger.info('[mf-runtime][garfish] destroy completed');\n } catch (error) {\n // 仅记录错误,允许 Garfish 继续清理其他资源\n logger.error('[mf-runtime][garfish] destroy failed', error);\n }\n },\n };\n }\n\n return { provider };\n}\n","import logger from '@seed-fe/logger';\nimport type { AdapterOptions, AppInstance } from '../types/base';\nimport type { QiankunProps } from '../types/qiankun';\n\n/** @deprecated 使用 AdapterOptions 替代 */\nexport type QiankunAdapterOptions = AdapterOptions;\n\n/**\n * 创建 qiankun 适配器:\n * - 提供 bootstrap/mount/unmount 标准生命周期\n * - 内部通过 Map<container, AppInstance> 管理实例,支持多实例挂载\n * - 不关心具体渲染实现细节(React/Vue/纯 DOM 等)\n */\nexport function createQiankunAdapter(options: AdapterOptions) {\n const { initRuntime, renderApp } = options;\n\n const instances = new Map<Element | Document, AppInstance>();\n\n async function bootstrap() {\n try {\n await initRuntime();\n logger.info('[mf-runtime][qiankun] bootstrap completed');\n } catch (error) {\n logger.error('[mf-runtime][qiankun] bootstrap failed', error);\n throw error;\n }\n }\n\n function mount(props: QiankunProps) {\n try {\n const container = props.container ?? document;\n const instance = renderApp({\n container,\n props: {\n ...props,\n app: props.app,\n },\n });\n instances.set(container, instance);\n logger.info('[mf-runtime][qiankun] mount completed');\n } catch (error) {\n logger.error('[mf-runtime][qiankun] mount failed', error);\n throw error;\n }\n }\n\n function unmount(props?: QiankunProps) {\n try {\n const container = props?.container ?? document;\n const instance = instances.get(container);\n instance?.unmount();\n instances.delete(container);\n logger.info('[mf-runtime][qiankun] unmount completed');\n } catch (error) {\n logger.error('[mf-runtime][qiankun] unmount failed', error);\n throw error;\n }\n }\n\n return { bootstrap, mount, unmount };\n}\n","import logger from '@seed-fe/logger';\nimport { createGarfishAdapter } from '../hosts/garfish';\nimport { createQiankunAdapter } from '../hosts/qiankun';\nimport type { AppInstance, InitRuntimeFn, RenderAppFn, StartStandaloneFn } from '../types/base';\nimport type { GarfishExports } from '../types/garfish';\nimport type { QiankunProps } from '../types/qiankun';\nimport type { HostAdapterConfig } from './hostManager';\nimport { initMicroFrontendHosts } from './hostManager';\nimport type { StandaloneOptions } from './standalone';\n\nexport interface MicroAppRuntimeOptions {\n /**\n * 微应用运行时初始化逻辑,由应用侧实现。\n * 典型职责:权限、认证、i18n 等一次性初始化。\n */\n initRuntime: InitRuntimeFn;\n /**\n * 微应用渲染逻辑,由应用侧实现。\n * - 适配层只关心 container / props 约定\n * - 内部可以是 React / Vue / 纯 DOM 等任意实现\n */\n mountApp: RenderAppFn;\n /**\n * 独立运行模式入口,由应用侧实现。\n * - 一般通过 createStandaloneStarter(initRuntime, renderApp) 生成\n * - 适配层只在未检测到任何宿主时调用\n */\n startStandalone: StartStandaloneFn;\n /**\n * 内置宿主框架配置\n *\n * - 默认全部启用(garfish: true, qiankun: true)\n * - 设置为 false 可禁用特定框架\n * - 设置为 {} 等同于全部启用\n *\n * @example\n * ```ts\n * // 默认全部启用\n * createMicroAppRuntime({ initRuntime, mountApp, startStandalone });\n *\n * // 仅启用 garfish\n * createMicroAppRuntime({\n * initRuntime,\n * mountApp,\n * startStandalone,\n * hosts: { garfish: true, qiankun: false },\n * });\n *\n * // 禁用所有内置框架,仅使用 extraHosts\n * createMicroAppRuntime({\n * initRuntime,\n * mountApp,\n * startStandalone,\n * hosts: { garfish: false, qiankun: false },\n * extraHosts: [customHost],\n * });\n * ```\n */\n hosts?: {\n garfish?: boolean;\n qiankun?: boolean;\n };\n /**\n * 额外宿主配置,用于接入其他微前端库\n * - 适合其他团队维护的宿主,仅需在微应用中传入配置即可\n */\n extraHosts?: HostAdapterConfig[];\n}\n\nexport interface MicroAppRuntime {\n /**\n * 独立运行模式入口(直接透传应用侧实现)\n */\n startStandaloneApp: (options?: StandaloneOptions) => Promise<AppInstance>;\n /**\n * qiankun 生命周期适配结果\n * - 需要在微应用中按需导出:export const { bootstrap, mount, unmount } = runtime.qiankun ?? {};\n */\n qiankun?: {\n bootstrap: () => Promise<void>;\n mount: (props: QiankunProps) => void;\n unmount: (props?: QiankunProps) => void;\n };\n}\n\n/**\n * 创建微应用运行时适配:\n * - 接收应用侧的 initRuntime / mountApp / startStandalone\n * - 内部完成 Garfish / qiankun 等宿主的适配与检测\n * - 返回 qiankun 生命周期供微应用按需导出\n *\n * 微应用层只需要:\n * 1. 提供 initRuntime / mountApp / startStandalone\n * 2. 在入口处调用 createMicroAppRuntime(...)\n * 3. 若需要支持 qiankun,再将 runtime.qiankun 的三个生命周期导出\n */\nexport function createMicroAppRuntime(options: MicroAppRuntimeOptions): MicroAppRuntime {\n const { initRuntime, mountApp, startStandalone, hosts, extraHosts } = options;\n\n // 默认全部启用\n const garfishEnabled = hosts?.garfish ?? true;\n const qiankunEnabled = hosts?.qiankun ?? true;\n\n const hostAdapters: HostAdapterConfig[] = [];\n\n // Garfish:通过 __GARFISH__ / __GARFISH_EXPORTS__ 适配 provider\n if (garfishEnabled) {\n const { provider } = createGarfishAdapter({\n initRuntime,\n renderApp: (garfishOptions) =>\n mountApp({\n container: garfishOptions.container,\n props: garfishOptions.props,\n }),\n });\n\n // 宿主模式下:若检测到 Garfish 标识,则立即挂载 provider。\n // 兼容两种注入方式:\n // - 宿主预先创建 __GARFISH_EXPORTS__\n // - 子应用自行创建 __GARFISH_EXPORTS__\n if (typeof window !== 'undefined' && (window as Window & { __GARFISH__?: boolean }).__GARFISH__) {\n const globalWithExports = globalThis as typeof globalThis & { __GARFISH_EXPORTS__?: GarfishExports };\n if (!globalWithExports.__GARFISH_EXPORTS__) {\n globalWithExports.__GARFISH_EXPORTS__ = {} as GarfishExports;\n }\n globalWithExports.__GARFISH_EXPORTS__.provider = provider;\n }\n\n hostAdapters.push({\n name: 'garfish',\n detect: () => Boolean(window.__GARFISH__),\n activate: () => {\n if (typeof __GARFISH_EXPORTS__ !== 'undefined') {\n __GARFISH_EXPORTS__.provider = provider;\n }\n },\n });\n }\n\n // qiankun:返回标准生命周期,由微应用按需导出\n let qiankunRuntime: MicroAppRuntime['qiankun'];\n\n if (qiankunEnabled) {\n const { bootstrap, mount, unmount } = createQiankunAdapter({\n initRuntime,\n renderApp: mountApp,\n });\n\n qiankunRuntime = {\n bootstrap,\n mount,\n unmount,\n };\n\n // 将 qiankun 添加到 hosts 数组用于检测\n // 虽然 qiankun 不需要 activate(宿主会主动调用生命周期),\n // 但仍需要 detect 以防止错误地进入独立运行模式\n hostAdapters.push({\n name: 'qiankun',\n detect: () => Boolean(window.__POWERED_BY_QIANKUN__),\n activate: () => {\n logger.info(`[mf-adapter] qiankun`);\n // qiankun 宿主会主动调用生命周期,无需额外激活\n },\n });\n }\n\n if (extraHosts?.length) {\n hostAdapters.push(...extraHosts);\n }\n\n // 初始化宿主检测 + 独立运行回退\n void initMicroFrontendHosts({\n hosts: hostAdapters,\n fallback: () => startStandalone(),\n });\n\n return {\n startStandaloneApp: startStandalone,\n qiankun: qiankunRuntime,\n };\n}\n","import type { AppInstance, InitRuntimeFn, RenderAppFn, RuntimeProps } from '../types/base';\n\nexport interface StandaloneOptions {\n container?: Document;\n props?: RuntimeProps;\n}\n\nexport interface StandaloneStarterOptions {\n initRuntime: InitRuntimeFn;\n renderApp: RenderAppFn;\n}\n\n/**\n * 创建独立运行模式启动器:\n * - 统一处理非微前端宿主环境下的初始化逻辑\n * - 内部保证单例实例,避免重复挂载\n */\nexport function createStandaloneStarter(options: StandaloneStarterOptions) {\n const { initRuntime, renderApp } = options;\n\n let standaloneInstance: AppInstance | null = null;\n\n return async function startStandaloneApp(customOptions?: StandaloneOptions): Promise<AppInstance> {\n if (standaloneInstance) {\n return standaloneInstance;\n }\n\n await initRuntime();\n\n standaloneInstance = renderApp({\n container: customOptions?.container ?? document,\n props: customOptions?.props,\n });\n\n return standaloneInstance;\n };\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 主应用传递给微应用的配置约定:
|
|
3
|
+
* - 与容器工程的 ProjectConfig.microapps[] 结构保持兼容
|
|
4
|
+
* - 但不直接依赖容器工程的类型定义,避免跨工程路径耦合
|
|
5
|
+
*/
|
|
6
|
+
interface MicroAppConfig {
|
|
7
|
+
/** 微应用唯一标识(如 "product-app") */
|
|
8
|
+
name?: string;
|
|
9
|
+
/**
|
|
10
|
+
* 微应用的路由基础路径
|
|
11
|
+
*
|
|
12
|
+
* - **来源**: 由主应用根据配置计算后传递(如从 pathname 计算得到)
|
|
13
|
+
* - **用途**: 配置路由库(如 React Router 的 `<BrowserRouter basename="/products" />`)
|
|
14
|
+
* - **示例**: `"/products"`, `"/orders"`, `"/users"`
|
|
15
|
+
* - **说明**: 主应用负责处理前后斜杠,微应用直接使用即可
|
|
16
|
+
*/
|
|
17
|
+
basename: string;
|
|
18
|
+
/** 微应用版本号 */
|
|
19
|
+
version?: string;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 微应用运行时初始化参数
|
|
24
|
+
*
|
|
25
|
+
* 说明:
|
|
26
|
+
* - 仅作为适配层与微应用之间的契约类型
|
|
27
|
+
* - 不关心具体实现细节(权限 / 认证 / i18n 等)
|
|
28
|
+
* - 支持宿主透传扩展字段
|
|
29
|
+
*/
|
|
30
|
+
interface RuntimeProps {
|
|
31
|
+
/**
|
|
32
|
+
* 主应用传递的微应用配置信息
|
|
33
|
+
*
|
|
34
|
+
* - **来源**: 主应用根据配置构建并传递
|
|
35
|
+
* - **内容**: 包含 basename(必需), name, version 等配置
|
|
36
|
+
*/
|
|
37
|
+
app?: MicroAppConfig;
|
|
38
|
+
/**
|
|
39
|
+
* 宿主扩展字段
|
|
40
|
+
*
|
|
41
|
+
* 允许宿主透传专有字段,避免类型冲突
|
|
42
|
+
*/
|
|
43
|
+
[key: string]: unknown;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 微应用实例:用于统一卸载逻辑
|
|
47
|
+
*
|
|
48
|
+
* 由微应用自行决定实例内部结构,这里只约定必须提供 unmount 方法。
|
|
49
|
+
*/
|
|
50
|
+
interface AppInstance {
|
|
51
|
+
unmount(): void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 微应用运行时初始化函数类型
|
|
55
|
+
*
|
|
56
|
+
* 职责:权限、认证、i18n 等一次性初始化
|
|
57
|
+
* 约定:必须是幂等的(可被多次调用)
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* import type { InitRuntimeFn } from '@seed-fe/mf-adapters';
|
|
62
|
+
*
|
|
63
|
+
* export const initRuntime: InitRuntimeFn = async () => {
|
|
64
|
+
* // 初始化权限、认证、i18n 等
|
|
65
|
+
* };
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
type InitRuntimeFn = () => Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* 微应用渲染函数类型
|
|
71
|
+
*
|
|
72
|
+
* 不关心具体框架(React / Vue / 纯 DOM),仅约定返回包含 unmount() 的实例
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* import type { RenderAppFn } from '@seed-fe/mf-adapters';
|
|
77
|
+
*
|
|
78
|
+
* export const renderApp: RenderAppFn = ({ container, props }) => {
|
|
79
|
+
* const root = createRoot(container as HTMLElement);
|
|
80
|
+
* root.render(<App {...props} />);
|
|
81
|
+
*
|
|
82
|
+
* return {
|
|
83
|
+
* unmount() {
|
|
84
|
+
* root.unmount();
|
|
85
|
+
* }
|
|
86
|
+
* };
|
|
87
|
+
* };
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
type RenderAppFn = (options: {
|
|
91
|
+
container: Element | Document;
|
|
92
|
+
props?: RuntimeProps;
|
|
93
|
+
}) => AppInstance;
|
|
94
|
+
/**
|
|
95
|
+
* 独立运行模式启动函数类型
|
|
96
|
+
*
|
|
97
|
+
* 用于非微前端宿主环境下的独立运行
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* import type { StartStandaloneFn } from '@seed-fe/mf-adapters';
|
|
102
|
+
*
|
|
103
|
+
* export const startStandalone: StartStandaloneFn = async (options) => {
|
|
104
|
+
* await initRuntime();
|
|
105
|
+
* return renderApp({
|
|
106
|
+
* container: options?.container ?? document,
|
|
107
|
+
* props: options?.props,
|
|
108
|
+
* });
|
|
109
|
+
* };
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
type StartStandaloneFn = (options?: {
|
|
113
|
+
container?: Document;
|
|
114
|
+
props?: RuntimeProps;
|
|
115
|
+
}) => Promise<AppInstance>;
|
|
116
|
+
/**
|
|
117
|
+
* 宿主适配器选项契约
|
|
118
|
+
*
|
|
119
|
+
* - 适用于所有微前端宿主(Garfish / qiankun / 未来扩展)
|
|
120
|
+
* - 定义了微应用侧必须实现的两个核心函数
|
|
121
|
+
*/
|
|
122
|
+
interface AdapterOptions {
|
|
123
|
+
/**
|
|
124
|
+
* 微应用运行时初始化逻辑
|
|
125
|
+
*
|
|
126
|
+
* - 职责:权限、认证、i18n 等一次性初始化
|
|
127
|
+
* - 约定:必须是幂等的(可被多次调用)
|
|
128
|
+
*/
|
|
129
|
+
initRuntime: InitRuntimeFn;
|
|
130
|
+
/**
|
|
131
|
+
* 微应用渲染函数
|
|
132
|
+
*
|
|
133
|
+
* - 不关心具体框架(React / Vue / 纯 DOM)
|
|
134
|
+
* - 仅约定返回包含 unmount() 的实例
|
|
135
|
+
*/
|
|
136
|
+
renderApp: RenderAppFn;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
interface HostAdapterConfig {
|
|
140
|
+
name: string;
|
|
141
|
+
/**
|
|
142
|
+
* 返回 true 表示当前宿主命中
|
|
143
|
+
*/
|
|
144
|
+
detect(): boolean;
|
|
145
|
+
/**
|
|
146
|
+
* 命中宿主后调用,用于注册生命周期或执行初始化逻辑
|
|
147
|
+
*/
|
|
148
|
+
activate?(): void | Promise<void>;
|
|
149
|
+
}
|
|
150
|
+
interface HostManagerOptions {
|
|
151
|
+
hosts: HostAdapterConfig[];
|
|
152
|
+
/**
|
|
153
|
+
* 当未检测到任何宿主标识时的回退逻辑,一般为 startStandaloneApp
|
|
154
|
+
*/
|
|
155
|
+
fallback: () => Promise<AppInstance> | Promise<unknown>;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* 根据宿主环境动态选择微前端框架,若未检测到宿主则回退为独立运行模式。
|
|
159
|
+
*/
|
|
160
|
+
declare function initMicroFrontendHosts(options: HostManagerOptions): Promise<void>;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* qiankun 相关类型声明与全局接口扩展。
|
|
164
|
+
*
|
|
165
|
+
* 注意:
|
|
166
|
+
* - 此处只声明类型,不做任何运行时代码
|
|
167
|
+
* - 运行时适配逻辑在 hosts/qiankun.ts 中实现
|
|
168
|
+
*/
|
|
169
|
+
|
|
170
|
+
declare global {
|
|
171
|
+
interface Window {
|
|
172
|
+
__POWERED_BY_QIANKUN__?: boolean;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/** qiankun 生命周期 props */
|
|
176
|
+
interface QiankunProps extends RuntimeProps {
|
|
177
|
+
container?: Element;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
interface StandaloneOptions {
|
|
181
|
+
container?: Document;
|
|
182
|
+
props?: RuntimeProps;
|
|
183
|
+
}
|
|
184
|
+
interface StandaloneStarterOptions {
|
|
185
|
+
initRuntime: InitRuntimeFn;
|
|
186
|
+
renderApp: RenderAppFn;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* 创建独立运行模式启动器:
|
|
190
|
+
* - 统一处理非微前端宿主环境下的初始化逻辑
|
|
191
|
+
* - 内部保证单例实例,避免重复挂载
|
|
192
|
+
*/
|
|
193
|
+
declare function createStandaloneStarter(options: StandaloneStarterOptions): (customOptions?: StandaloneOptions) => Promise<AppInstance>;
|
|
194
|
+
|
|
195
|
+
interface MicroAppRuntimeOptions {
|
|
196
|
+
/**
|
|
197
|
+
* 微应用运行时初始化逻辑,由应用侧实现。
|
|
198
|
+
* 典型职责:权限、认证、i18n 等一次性初始化。
|
|
199
|
+
*/
|
|
200
|
+
initRuntime: InitRuntimeFn;
|
|
201
|
+
/**
|
|
202
|
+
* 微应用渲染逻辑,由应用侧实现。
|
|
203
|
+
* - 适配层只关心 container / props 约定
|
|
204
|
+
* - 内部可以是 React / Vue / 纯 DOM 等任意实现
|
|
205
|
+
*/
|
|
206
|
+
mountApp: RenderAppFn;
|
|
207
|
+
/**
|
|
208
|
+
* 独立运行模式入口,由应用侧实现。
|
|
209
|
+
* - 一般通过 createStandaloneStarter(initRuntime, renderApp) 生成
|
|
210
|
+
* - 适配层只在未检测到任何宿主时调用
|
|
211
|
+
*/
|
|
212
|
+
startStandalone: StartStandaloneFn;
|
|
213
|
+
/**
|
|
214
|
+
* 内置宿主框架配置
|
|
215
|
+
*
|
|
216
|
+
* - 默认全部启用(garfish: true, qiankun: true)
|
|
217
|
+
* - 设置为 false 可禁用特定框架
|
|
218
|
+
* - 设置为 {} 等同于全部启用
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```ts
|
|
222
|
+
* // 默认全部启用
|
|
223
|
+
* createMicroAppRuntime({ initRuntime, mountApp, startStandalone });
|
|
224
|
+
*
|
|
225
|
+
* // 仅启用 garfish
|
|
226
|
+
* createMicroAppRuntime({
|
|
227
|
+
* initRuntime,
|
|
228
|
+
* mountApp,
|
|
229
|
+
* startStandalone,
|
|
230
|
+
* hosts: { garfish: true, qiankun: false },
|
|
231
|
+
* });
|
|
232
|
+
*
|
|
233
|
+
* // 禁用所有内置框架,仅使用 extraHosts
|
|
234
|
+
* createMicroAppRuntime({
|
|
235
|
+
* initRuntime,
|
|
236
|
+
* mountApp,
|
|
237
|
+
* startStandalone,
|
|
238
|
+
* hosts: { garfish: false, qiankun: false },
|
|
239
|
+
* extraHosts: [customHost],
|
|
240
|
+
* });
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
hosts?: {
|
|
244
|
+
garfish?: boolean;
|
|
245
|
+
qiankun?: boolean;
|
|
246
|
+
};
|
|
247
|
+
/**
|
|
248
|
+
* 额外宿主配置,用于接入其他微前端库
|
|
249
|
+
* - 适合其他团队维护的宿主,仅需在微应用中传入配置即可
|
|
250
|
+
*/
|
|
251
|
+
extraHosts?: HostAdapterConfig[];
|
|
252
|
+
}
|
|
253
|
+
interface MicroAppRuntime {
|
|
254
|
+
/**
|
|
255
|
+
* 独立运行模式入口(直接透传应用侧实现)
|
|
256
|
+
*/
|
|
257
|
+
startStandaloneApp: (options?: StandaloneOptions) => Promise<AppInstance>;
|
|
258
|
+
/**
|
|
259
|
+
* qiankun 生命周期适配结果
|
|
260
|
+
* - 需要在微应用中按需导出:export const { bootstrap, mount, unmount } = runtime.qiankun ?? {};
|
|
261
|
+
*/
|
|
262
|
+
qiankun?: {
|
|
263
|
+
bootstrap: () => Promise<void>;
|
|
264
|
+
mount: (props: QiankunProps) => void;
|
|
265
|
+
unmount: (props?: QiankunProps) => void;
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* 创建微应用运行时适配:
|
|
270
|
+
* - 接收应用侧的 initRuntime / mountApp / startStandalone
|
|
271
|
+
* - 内部完成 Garfish / qiankun 等宿主的适配与检测
|
|
272
|
+
* - 返回 qiankun 生命周期供微应用按需导出
|
|
273
|
+
*
|
|
274
|
+
* 微应用层只需要:
|
|
275
|
+
* 1. 提供 initRuntime / mountApp / startStandalone
|
|
276
|
+
* 2. 在入口处调用 createMicroAppRuntime(...)
|
|
277
|
+
* 3. 若需要支持 qiankun,再将 runtime.qiankun 的三个生命周期导出
|
|
278
|
+
*/
|
|
279
|
+
declare function createMicroAppRuntime(options: MicroAppRuntimeOptions): MicroAppRuntime;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Garfish 相关类型声明与全局接口扩展。
|
|
283
|
+
*
|
|
284
|
+
* 注意:
|
|
285
|
+
* - 此处只声明类型,不做任何运行时代码
|
|
286
|
+
* - 运行时适配逻辑在 hosts/garfish.ts 中实现
|
|
287
|
+
*/
|
|
288
|
+
|
|
289
|
+
declare global {
|
|
290
|
+
interface Window {
|
|
291
|
+
/** Garfish 在 window 上注入的宿主标识 */
|
|
292
|
+
__GARFISH__?: boolean;
|
|
293
|
+
}
|
|
294
|
+
/** Garfish 在运行时注入的全局导出对象 */
|
|
295
|
+
var __GARFISH_EXPORTS__: GarfishExports;
|
|
296
|
+
}
|
|
297
|
+
/** Garfish render 钩子参数 */
|
|
298
|
+
interface GarfishRenderParams {
|
|
299
|
+
appName: string;
|
|
300
|
+
dom: Document;
|
|
301
|
+
basename?: string;
|
|
302
|
+
appRenderInfo: GarfishAppRenderInfo;
|
|
303
|
+
props?: RuntimeProps;
|
|
304
|
+
}
|
|
305
|
+
/** Garfish destroy 钩子参数 */
|
|
306
|
+
interface GarfishDestroyParams {
|
|
307
|
+
appName: string;
|
|
308
|
+
dom: Document;
|
|
309
|
+
appRenderInfo: GarfishAppRenderInfo;
|
|
310
|
+
props?: RuntimeProps;
|
|
311
|
+
}
|
|
312
|
+
/** Garfish 应用渲染信息 */
|
|
313
|
+
interface GarfishAppRenderInfo {
|
|
314
|
+
isMount?: boolean;
|
|
315
|
+
isUnmount?: boolean;
|
|
316
|
+
}
|
|
317
|
+
/** Garfish 导出对象接口 */
|
|
318
|
+
interface GarfishExports {
|
|
319
|
+
provider: () => {
|
|
320
|
+
render: (params: GarfishRenderParams) => void;
|
|
321
|
+
destroy: (params: GarfishDestroyParams) => void;
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* 创建 Garfish 适配器:
|
|
327
|
+
* - 提供 provider() 给 Garfish 宿主使用
|
|
328
|
+
* - 内部通过 Map<Document, AppInstance> 管理实例,支持多容器挂载
|
|
329
|
+
* - 不关心具体渲染实现细节(React/Vue/纯 DOM 等)
|
|
330
|
+
*/
|
|
331
|
+
declare function createGarfishAdapter(options: AdapterOptions): {
|
|
332
|
+
provider: () => {
|
|
333
|
+
render(params: GarfishRenderParams): Promise<void>;
|
|
334
|
+
destroy(params: GarfishDestroyParams): void;
|
|
335
|
+
};
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
/** @deprecated 使用 AdapterOptions 替代 */
|
|
339
|
+
type QiankunAdapterOptions = AdapterOptions;
|
|
340
|
+
/**
|
|
341
|
+
* 创建 qiankun 适配器:
|
|
342
|
+
* - 提供 bootstrap/mount/unmount 标准生命周期
|
|
343
|
+
* - 内部通过 Map<container, AppInstance> 管理实例,支持多实例挂载
|
|
344
|
+
* - 不关心具体渲染实现细节(React/Vue/纯 DOM 等)
|
|
345
|
+
*/
|
|
346
|
+
declare function createQiankunAdapter(options: AdapterOptions): {
|
|
347
|
+
bootstrap: () => Promise<void>;
|
|
348
|
+
mount: (props: QiankunProps) => void;
|
|
349
|
+
unmount: (props?: QiankunProps) => void;
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
export { type AdapterOptions, type AppInstance, type GarfishAppRenderInfo, type GarfishDestroyParams, type GarfishExports, type GarfishRenderParams, type HostAdapterConfig, type HostManagerOptions, type InitRuntimeFn, type MicroAppConfig, type MicroAppRuntime, type MicroAppRuntimeOptions, type QiankunAdapterOptions, type QiankunProps, type RenderAppFn, type RuntimeProps, type StandaloneOptions, type StandaloneStarterOptions, type StartStandaloneFn, createGarfishAdapter, createMicroAppRuntime, createQiankunAdapter, createStandaloneStarter, initMicroFrontendHosts };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 主应用传递给微应用的配置约定:
|
|
3
|
+
* - 与容器工程的 ProjectConfig.microapps[] 结构保持兼容
|
|
4
|
+
* - 但不直接依赖容器工程的类型定义,避免跨工程路径耦合
|
|
5
|
+
*/
|
|
6
|
+
interface MicroAppConfig {
|
|
7
|
+
/** 微应用唯一标识(如 "product-app") */
|
|
8
|
+
name?: string;
|
|
9
|
+
/**
|
|
10
|
+
* 微应用的路由基础路径
|
|
11
|
+
*
|
|
12
|
+
* - **来源**: 由主应用根据配置计算后传递(如从 pathname 计算得到)
|
|
13
|
+
* - **用途**: 配置路由库(如 React Router 的 `<BrowserRouter basename="/products" />`)
|
|
14
|
+
* - **示例**: `"/products"`, `"/orders"`, `"/users"`
|
|
15
|
+
* - **说明**: 主应用负责处理前后斜杠,微应用直接使用即可
|
|
16
|
+
*/
|
|
17
|
+
basename: string;
|
|
18
|
+
/** 微应用版本号 */
|
|
19
|
+
version?: string;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 微应用运行时初始化参数
|
|
24
|
+
*
|
|
25
|
+
* 说明:
|
|
26
|
+
* - 仅作为适配层与微应用之间的契约类型
|
|
27
|
+
* - 不关心具体实现细节(权限 / 认证 / i18n 等)
|
|
28
|
+
* - 支持宿主透传扩展字段
|
|
29
|
+
*/
|
|
30
|
+
interface RuntimeProps {
|
|
31
|
+
/**
|
|
32
|
+
* 主应用传递的微应用配置信息
|
|
33
|
+
*
|
|
34
|
+
* - **来源**: 主应用根据配置构建并传递
|
|
35
|
+
* - **内容**: 包含 basename(必需), name, version 等配置
|
|
36
|
+
*/
|
|
37
|
+
app?: MicroAppConfig;
|
|
38
|
+
/**
|
|
39
|
+
* 宿主扩展字段
|
|
40
|
+
*
|
|
41
|
+
* 允许宿主透传专有字段,避免类型冲突
|
|
42
|
+
*/
|
|
43
|
+
[key: string]: unknown;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 微应用实例:用于统一卸载逻辑
|
|
47
|
+
*
|
|
48
|
+
* 由微应用自行决定实例内部结构,这里只约定必须提供 unmount 方法。
|
|
49
|
+
*/
|
|
50
|
+
interface AppInstance {
|
|
51
|
+
unmount(): void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 微应用运行时初始化函数类型
|
|
55
|
+
*
|
|
56
|
+
* 职责:权限、认证、i18n 等一次性初始化
|
|
57
|
+
* 约定:必须是幂等的(可被多次调用)
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* import type { InitRuntimeFn } from '@seed-fe/mf-adapters';
|
|
62
|
+
*
|
|
63
|
+
* export const initRuntime: InitRuntimeFn = async () => {
|
|
64
|
+
* // 初始化权限、认证、i18n 等
|
|
65
|
+
* };
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
type InitRuntimeFn = () => Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* 微应用渲染函数类型
|
|
71
|
+
*
|
|
72
|
+
* 不关心具体框架(React / Vue / 纯 DOM),仅约定返回包含 unmount() 的实例
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* import type { RenderAppFn } from '@seed-fe/mf-adapters';
|
|
77
|
+
*
|
|
78
|
+
* export const renderApp: RenderAppFn = ({ container, props }) => {
|
|
79
|
+
* const root = createRoot(container as HTMLElement);
|
|
80
|
+
* root.render(<App {...props} />);
|
|
81
|
+
*
|
|
82
|
+
* return {
|
|
83
|
+
* unmount() {
|
|
84
|
+
* root.unmount();
|
|
85
|
+
* }
|
|
86
|
+
* };
|
|
87
|
+
* };
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
type RenderAppFn = (options: {
|
|
91
|
+
container: Element | Document;
|
|
92
|
+
props?: RuntimeProps;
|
|
93
|
+
}) => AppInstance;
|
|
94
|
+
/**
|
|
95
|
+
* 独立运行模式启动函数类型
|
|
96
|
+
*
|
|
97
|
+
* 用于非微前端宿主环境下的独立运行
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* import type { StartStandaloneFn } from '@seed-fe/mf-adapters';
|
|
102
|
+
*
|
|
103
|
+
* export const startStandalone: StartStandaloneFn = async (options) => {
|
|
104
|
+
* await initRuntime();
|
|
105
|
+
* return renderApp({
|
|
106
|
+
* container: options?.container ?? document,
|
|
107
|
+
* props: options?.props,
|
|
108
|
+
* });
|
|
109
|
+
* };
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
type StartStandaloneFn = (options?: {
|
|
113
|
+
container?: Document;
|
|
114
|
+
props?: RuntimeProps;
|
|
115
|
+
}) => Promise<AppInstance>;
|
|
116
|
+
/**
|
|
117
|
+
* 宿主适配器选项契约
|
|
118
|
+
*
|
|
119
|
+
* - 适用于所有微前端宿主(Garfish / qiankun / 未来扩展)
|
|
120
|
+
* - 定义了微应用侧必须实现的两个核心函数
|
|
121
|
+
*/
|
|
122
|
+
interface AdapterOptions {
|
|
123
|
+
/**
|
|
124
|
+
* 微应用运行时初始化逻辑
|
|
125
|
+
*
|
|
126
|
+
* - 职责:权限、认证、i18n 等一次性初始化
|
|
127
|
+
* - 约定:必须是幂等的(可被多次调用)
|
|
128
|
+
*/
|
|
129
|
+
initRuntime: InitRuntimeFn;
|
|
130
|
+
/**
|
|
131
|
+
* 微应用渲染函数
|
|
132
|
+
*
|
|
133
|
+
* - 不关心具体框架(React / Vue / 纯 DOM)
|
|
134
|
+
* - 仅约定返回包含 unmount() 的实例
|
|
135
|
+
*/
|
|
136
|
+
renderApp: RenderAppFn;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
interface HostAdapterConfig {
|
|
140
|
+
name: string;
|
|
141
|
+
/**
|
|
142
|
+
* 返回 true 表示当前宿主命中
|
|
143
|
+
*/
|
|
144
|
+
detect(): boolean;
|
|
145
|
+
/**
|
|
146
|
+
* 命中宿主后调用,用于注册生命周期或执行初始化逻辑
|
|
147
|
+
*/
|
|
148
|
+
activate?(): void | Promise<void>;
|
|
149
|
+
}
|
|
150
|
+
interface HostManagerOptions {
|
|
151
|
+
hosts: HostAdapterConfig[];
|
|
152
|
+
/**
|
|
153
|
+
* 当未检测到任何宿主标识时的回退逻辑,一般为 startStandaloneApp
|
|
154
|
+
*/
|
|
155
|
+
fallback: () => Promise<AppInstance> | Promise<unknown>;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* 根据宿主环境动态选择微前端框架,若未检测到宿主则回退为独立运行模式。
|
|
159
|
+
*/
|
|
160
|
+
declare function initMicroFrontendHosts(options: HostManagerOptions): Promise<void>;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* qiankun 相关类型声明与全局接口扩展。
|
|
164
|
+
*
|
|
165
|
+
* 注意:
|
|
166
|
+
* - 此处只声明类型,不做任何运行时代码
|
|
167
|
+
* - 运行时适配逻辑在 hosts/qiankun.ts 中实现
|
|
168
|
+
*/
|
|
169
|
+
|
|
170
|
+
declare global {
|
|
171
|
+
interface Window {
|
|
172
|
+
__POWERED_BY_QIANKUN__?: boolean;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/** qiankun 生命周期 props */
|
|
176
|
+
interface QiankunProps extends RuntimeProps {
|
|
177
|
+
container?: Element;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
interface StandaloneOptions {
|
|
181
|
+
container?: Document;
|
|
182
|
+
props?: RuntimeProps;
|
|
183
|
+
}
|
|
184
|
+
interface StandaloneStarterOptions {
|
|
185
|
+
initRuntime: InitRuntimeFn;
|
|
186
|
+
renderApp: RenderAppFn;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* 创建独立运行模式启动器:
|
|
190
|
+
* - 统一处理非微前端宿主环境下的初始化逻辑
|
|
191
|
+
* - 内部保证单例实例,避免重复挂载
|
|
192
|
+
*/
|
|
193
|
+
declare function createStandaloneStarter(options: StandaloneStarterOptions): (customOptions?: StandaloneOptions) => Promise<AppInstance>;
|
|
194
|
+
|
|
195
|
+
interface MicroAppRuntimeOptions {
|
|
196
|
+
/**
|
|
197
|
+
* 微应用运行时初始化逻辑,由应用侧实现。
|
|
198
|
+
* 典型职责:权限、认证、i18n 等一次性初始化。
|
|
199
|
+
*/
|
|
200
|
+
initRuntime: InitRuntimeFn;
|
|
201
|
+
/**
|
|
202
|
+
* 微应用渲染逻辑,由应用侧实现。
|
|
203
|
+
* - 适配层只关心 container / props 约定
|
|
204
|
+
* - 内部可以是 React / Vue / 纯 DOM 等任意实现
|
|
205
|
+
*/
|
|
206
|
+
mountApp: RenderAppFn;
|
|
207
|
+
/**
|
|
208
|
+
* 独立运行模式入口,由应用侧实现。
|
|
209
|
+
* - 一般通过 createStandaloneStarter(initRuntime, renderApp) 生成
|
|
210
|
+
* - 适配层只在未检测到任何宿主时调用
|
|
211
|
+
*/
|
|
212
|
+
startStandalone: StartStandaloneFn;
|
|
213
|
+
/**
|
|
214
|
+
* 内置宿主框架配置
|
|
215
|
+
*
|
|
216
|
+
* - 默认全部启用(garfish: true, qiankun: true)
|
|
217
|
+
* - 设置为 false 可禁用特定框架
|
|
218
|
+
* - 设置为 {} 等同于全部启用
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```ts
|
|
222
|
+
* // 默认全部启用
|
|
223
|
+
* createMicroAppRuntime({ initRuntime, mountApp, startStandalone });
|
|
224
|
+
*
|
|
225
|
+
* // 仅启用 garfish
|
|
226
|
+
* createMicroAppRuntime({
|
|
227
|
+
* initRuntime,
|
|
228
|
+
* mountApp,
|
|
229
|
+
* startStandalone,
|
|
230
|
+
* hosts: { garfish: true, qiankun: false },
|
|
231
|
+
* });
|
|
232
|
+
*
|
|
233
|
+
* // 禁用所有内置框架,仅使用 extraHosts
|
|
234
|
+
* createMicroAppRuntime({
|
|
235
|
+
* initRuntime,
|
|
236
|
+
* mountApp,
|
|
237
|
+
* startStandalone,
|
|
238
|
+
* hosts: { garfish: false, qiankun: false },
|
|
239
|
+
* extraHosts: [customHost],
|
|
240
|
+
* });
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
hosts?: {
|
|
244
|
+
garfish?: boolean;
|
|
245
|
+
qiankun?: boolean;
|
|
246
|
+
};
|
|
247
|
+
/**
|
|
248
|
+
* 额外宿主配置,用于接入其他微前端库
|
|
249
|
+
* - 适合其他团队维护的宿主,仅需在微应用中传入配置即可
|
|
250
|
+
*/
|
|
251
|
+
extraHosts?: HostAdapterConfig[];
|
|
252
|
+
}
|
|
253
|
+
interface MicroAppRuntime {
|
|
254
|
+
/**
|
|
255
|
+
* 独立运行模式入口(直接透传应用侧实现)
|
|
256
|
+
*/
|
|
257
|
+
startStandaloneApp: (options?: StandaloneOptions) => Promise<AppInstance>;
|
|
258
|
+
/**
|
|
259
|
+
* qiankun 生命周期适配结果
|
|
260
|
+
* - 需要在微应用中按需导出:export const { bootstrap, mount, unmount } = runtime.qiankun ?? {};
|
|
261
|
+
*/
|
|
262
|
+
qiankun?: {
|
|
263
|
+
bootstrap: () => Promise<void>;
|
|
264
|
+
mount: (props: QiankunProps) => void;
|
|
265
|
+
unmount: (props?: QiankunProps) => void;
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* 创建微应用运行时适配:
|
|
270
|
+
* - 接收应用侧的 initRuntime / mountApp / startStandalone
|
|
271
|
+
* - 内部完成 Garfish / qiankun 等宿主的适配与检测
|
|
272
|
+
* - 返回 qiankun 生命周期供微应用按需导出
|
|
273
|
+
*
|
|
274
|
+
* 微应用层只需要:
|
|
275
|
+
* 1. 提供 initRuntime / mountApp / startStandalone
|
|
276
|
+
* 2. 在入口处调用 createMicroAppRuntime(...)
|
|
277
|
+
* 3. 若需要支持 qiankun,再将 runtime.qiankun 的三个生命周期导出
|
|
278
|
+
*/
|
|
279
|
+
declare function createMicroAppRuntime(options: MicroAppRuntimeOptions): MicroAppRuntime;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Garfish 相关类型声明与全局接口扩展。
|
|
283
|
+
*
|
|
284
|
+
* 注意:
|
|
285
|
+
* - 此处只声明类型,不做任何运行时代码
|
|
286
|
+
* - 运行时适配逻辑在 hosts/garfish.ts 中实现
|
|
287
|
+
*/
|
|
288
|
+
|
|
289
|
+
declare global {
|
|
290
|
+
interface Window {
|
|
291
|
+
/** Garfish 在 window 上注入的宿主标识 */
|
|
292
|
+
__GARFISH__?: boolean;
|
|
293
|
+
}
|
|
294
|
+
/** Garfish 在运行时注入的全局导出对象 */
|
|
295
|
+
var __GARFISH_EXPORTS__: GarfishExports;
|
|
296
|
+
}
|
|
297
|
+
/** Garfish render 钩子参数 */
|
|
298
|
+
interface GarfishRenderParams {
|
|
299
|
+
appName: string;
|
|
300
|
+
dom: Document;
|
|
301
|
+
basename?: string;
|
|
302
|
+
appRenderInfo: GarfishAppRenderInfo;
|
|
303
|
+
props?: RuntimeProps;
|
|
304
|
+
}
|
|
305
|
+
/** Garfish destroy 钩子参数 */
|
|
306
|
+
interface GarfishDestroyParams {
|
|
307
|
+
appName: string;
|
|
308
|
+
dom: Document;
|
|
309
|
+
appRenderInfo: GarfishAppRenderInfo;
|
|
310
|
+
props?: RuntimeProps;
|
|
311
|
+
}
|
|
312
|
+
/** Garfish 应用渲染信息 */
|
|
313
|
+
interface GarfishAppRenderInfo {
|
|
314
|
+
isMount?: boolean;
|
|
315
|
+
isUnmount?: boolean;
|
|
316
|
+
}
|
|
317
|
+
/** Garfish 导出对象接口 */
|
|
318
|
+
interface GarfishExports {
|
|
319
|
+
provider: () => {
|
|
320
|
+
render: (params: GarfishRenderParams) => void;
|
|
321
|
+
destroy: (params: GarfishDestroyParams) => void;
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* 创建 Garfish 适配器:
|
|
327
|
+
* - 提供 provider() 给 Garfish 宿主使用
|
|
328
|
+
* - 内部通过 Map<Document, AppInstance> 管理实例,支持多容器挂载
|
|
329
|
+
* - 不关心具体渲染实现细节(React/Vue/纯 DOM 等)
|
|
330
|
+
*/
|
|
331
|
+
declare function createGarfishAdapter(options: AdapterOptions): {
|
|
332
|
+
provider: () => {
|
|
333
|
+
render(params: GarfishRenderParams): Promise<void>;
|
|
334
|
+
destroy(params: GarfishDestroyParams): void;
|
|
335
|
+
};
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
/** @deprecated 使用 AdapterOptions 替代 */
|
|
339
|
+
type QiankunAdapterOptions = AdapterOptions;
|
|
340
|
+
/**
|
|
341
|
+
* 创建 qiankun 适配器:
|
|
342
|
+
* - 提供 bootstrap/mount/unmount 标准生命周期
|
|
343
|
+
* - 内部通过 Map<container, AppInstance> 管理实例,支持多实例挂载
|
|
344
|
+
* - 不关心具体渲染实现细节(React/Vue/纯 DOM 等)
|
|
345
|
+
*/
|
|
346
|
+
declare function createQiankunAdapter(options: AdapterOptions): {
|
|
347
|
+
bootstrap: () => Promise<void>;
|
|
348
|
+
mount: (props: QiankunProps) => void;
|
|
349
|
+
unmount: (props?: QiankunProps) => void;
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
export { type AdapterOptions, type AppInstance, type GarfishAppRenderInfo, type GarfishDestroyParams, type GarfishExports, type GarfishRenderParams, type HostAdapterConfig, type HostManagerOptions, type InitRuntimeFn, type MicroAppConfig, type MicroAppRuntime, type MicroAppRuntimeOptions, type QiankunAdapterOptions, type QiankunProps, type RenderAppFn, type RuntimeProps, type StandaloneOptions, type StandaloneStarterOptions, type StartStandaloneFn, createGarfishAdapter, createMicroAppRuntime, createQiankunAdapter, createStandaloneStarter, initMicroFrontendHosts };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import u from'@seed-fe/logger';var _=false;async function h(p){if(_)return;let{hosts:o,fallback:i}=p;for(let n of o)if(n.detect()){u.info(`[mf-runtime] detected micro-frontend host: ${n.name}`);try{await n.activate?.(),_=!0,u.info(`[mf-runtime] activated micro-frontend host: ${n.name}`);return}catch(s){u.error(`[mf-runtime] failed to activate ${n.name}, trying fallback`,s);}}_||(u.info("[mf-runtime] fallback to standalone mode"),await i());}function y(p){let{initRuntime:o,renderApp:i}=p,n=new Map;function s(){return {render(t){return o().then(()=>{let r=i({container:t.dom,props:{...t.props,app:t.props?.app}});n.set(t.dom,r),u.info(`[mf-runtime][garfish] rendered successfully: ${t.appName}`);}).catch(r=>{throw u.error(`[mf-runtime][garfish] render failed: ${t.appName}`,r),n.delete(t.dom),r})},destroy(t){try{let r=n.get(t.dom);r&&r.unmount(),n.delete(t.dom),u.info("[mf-runtime][garfish] destroy completed");}catch(r){u.error("[mf-runtime][garfish] destroy failed",r);}}}}return {provider:s}}function g(p){let{initRuntime:o,renderApp:i}=p,n=new Map;async function s(){try{await o(),u.info("[mf-runtime][qiankun] bootstrap completed");}catch(a){throw u.error("[mf-runtime][qiankun] bootstrap failed",a),a}}function t(a){try{let e=a.container??document,d=i({container:e,props:{...a,app:a.app}});n.set(e,d),u.info("[mf-runtime][qiankun] mount completed");}catch(e){throw u.error("[mf-runtime][qiankun] mount failed",e),e}}function r(a){try{let e=a?.container??document;n.get(e)?.unmount(),n.delete(e),u.info("[mf-runtime][qiankun] unmount completed");}catch(e){throw u.error("[mf-runtime][qiankun] unmount failed",e),e}}return {bootstrap:s,mount:t,unmount:r}}function D(p){let{initRuntime:o,mountApp:i,startStandalone:n,hosts:s,extraHosts:t}=p,r=s?.garfish??true,a=s?.qiankun??true,e=[];if(r){let{provider:l}=y({initRuntime:o,renderApp:m=>i({container:m.container,props:m.props})});if(typeof window<"u"&&window.__GARFISH__){let m=globalThis;m.__GARFISH_EXPORTS__||(m.__GARFISH_EXPORTS__={}),m.__GARFISH_EXPORTS__.provider=l;}e.push({name:"garfish",detect:()=>!!window.__GARFISH__,activate:()=>{typeof __GARFISH_EXPORTS__<"u"&&(__GARFISH_EXPORTS__.provider=l);}});}let d;if(a){let{bootstrap:l,mount:m,unmount:P}=g({initRuntime:o,renderApp:i});d={bootstrap:l,mount:m,unmount:P},e.push({name:"qiankun",detect:()=>!!window.__POWERED_BY_QIANKUN__,activate:()=>{u.info("[mf-adapter] qiankun");}});}return t?.length&&e.push(...t),h({hosts:e,fallback:()=>n()}),{startStandaloneApp:n,qiankun:d}}function N(p){let{initRuntime:o,renderApp:i}=p,n=null;return async function(t){return n||(await o(),n=i({container:t?.container??document,props:t?.props}),n)}}export{y as createGarfishAdapter,D as createMicroAppRuntime,g as createQiankunAdapter,N as createStandaloneStarter,h as initMicroFrontendHosts};//# sourceMappingURL=index.js.map
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/hostManager.ts","../src/hosts/garfish.ts","../src/hosts/qiankun.ts","../src/core/setup.ts","../src/core/standalone.ts"],"names":["microFrontendResolved","initMicroFrontendHosts","options","hosts","fallback","host","logger","error","createGarfishAdapter","initRuntime","renderApp","instances","provider","params","instance","createQiankunAdapter","bootstrap","mount","props","container","unmount","createMicroAppRuntime","mountApp","startStandalone","extraHosts","garfishEnabled","qiankunEnabled","hostAdapters","garfishOptions","globalWithExports","qiankunRuntime","createStandaloneStarter","standaloneInstance","customOptions"],"mappings":"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","file":"index.js","sourcesContent":["import logger from '@seed-fe/logger';\nimport type { AppInstance } from '../types/base';\n\nexport interface HostAdapterConfig {\n name: string;\n /**\n * 返回 true 表示当前宿主命中\n */\n detect(): boolean;\n /**\n * 命中宿主后调用,用于注册生命周期或执行初始化逻辑\n */\n activate?(): void | Promise<void>;\n}\n\nexport interface HostManagerOptions {\n hosts: HostAdapterConfig[];\n /**\n * 当未检测到任何宿主标识时的回退逻辑,一般为 startStandaloneApp\n */\n fallback: () => Promise<AppInstance> | Promise<unknown>;\n}\n\nlet microFrontendResolved = false;\n\n/**\n * 根据宿主环境动态选择微前端框架,若未检测到宿主则回退为独立运行模式。\n */\nexport async function initMicroFrontendHosts(options: HostManagerOptions): Promise<void> {\n if (microFrontendResolved) {\n return;\n }\n\n const { hosts, fallback } = options;\n\n for (const host of hosts) {\n if (host.detect()) {\n logger.info(`[mf-runtime] detected micro-frontend host: ${host.name}`);\n\n try {\n await host.activate?.();\n microFrontendResolved = true;\n logger.info(`[mf-runtime] activated micro-frontend host: ${host.name}`);\n return;\n } catch (error) {\n logger.error(`[mf-runtime] failed to activate ${host.name}, trying fallback`, error);\n // 继续尝试下一个宿主或回退到独立模式\n }\n }\n }\n\n // 如果所有宿主激活失败或未检测到任何宿主,调用 fallback\n if (!microFrontendResolved) {\n logger.info('[mf-runtime] fallback to standalone mode');\n await fallback();\n }\n}\n","import logger from '@seed-fe/logger';\nimport type { AdapterOptions, AppInstance } from '../types/base';\nimport type { GarfishDestroyParams, GarfishRenderParams } from '../types/garfish';\n\n/**\n * 创建 Garfish 适配器:\n * - 提供 provider() 给 Garfish 宿主使用\n * - 内部通过 Map<Document, AppInstance> 管理实例,支持多容器挂载\n * - 不关心具体渲染实现细节(React/Vue/纯 DOM 等)\n */\nexport function createGarfishAdapter(options: AdapterOptions) {\n const { initRuntime, renderApp } = options;\n\n const instances = new Map<Document, AppInstance>();\n\n function provider() {\n return {\n render(params: GarfishRenderParams) {\n return initRuntime()\n .then(() => {\n const instance = renderApp({\n container: params.dom,\n props: {\n ...params.props,\n app: params.props?.app,\n },\n });\n instances.set(params.dom, instance);\n logger.info(`[mf-runtime][garfish] rendered successfully: ${params.appName}`);\n })\n .catch((error: Error) => {\n logger.error(`[mf-runtime][garfish] render failed: ${params.appName}`, error);\n // 清理可能的部分状态\n instances.delete(params.dom);\n // 重新抛出,让 Garfish 处理\n throw error;\n });\n },\n destroy(params: GarfishDestroyParams) {\n try {\n const instance = instances.get(params.dom);\n if (instance) {\n instance.unmount();\n }\n instances.delete(params.dom);\n logger.info('[mf-runtime][garfish] destroy completed');\n } catch (error) {\n // 仅记录错误,允许 Garfish 继续清理其他资源\n logger.error('[mf-runtime][garfish] destroy failed', error);\n }\n },\n };\n }\n\n return { provider };\n}\n","import logger from '@seed-fe/logger';\nimport type { AdapterOptions, AppInstance } from '../types/base';\nimport type { QiankunProps } from '../types/qiankun';\n\n/** @deprecated 使用 AdapterOptions 替代 */\nexport type QiankunAdapterOptions = AdapterOptions;\n\n/**\n * 创建 qiankun 适配器:\n * - 提供 bootstrap/mount/unmount 标准生命周期\n * - 内部通过 Map<container, AppInstance> 管理实例,支持多实例挂载\n * - 不关心具体渲染实现细节(React/Vue/纯 DOM 等)\n */\nexport function createQiankunAdapter(options: AdapterOptions) {\n const { initRuntime, renderApp } = options;\n\n const instances = new Map<Element | Document, AppInstance>();\n\n async function bootstrap() {\n try {\n await initRuntime();\n logger.info('[mf-runtime][qiankun] bootstrap completed');\n } catch (error) {\n logger.error('[mf-runtime][qiankun] bootstrap failed', error);\n throw error;\n }\n }\n\n function mount(props: QiankunProps) {\n try {\n const container = props.container ?? document;\n const instance = renderApp({\n container,\n props: {\n ...props,\n app: props.app,\n },\n });\n instances.set(container, instance);\n logger.info('[mf-runtime][qiankun] mount completed');\n } catch (error) {\n logger.error('[mf-runtime][qiankun] mount failed', error);\n throw error;\n }\n }\n\n function unmount(props?: QiankunProps) {\n try {\n const container = props?.container ?? document;\n const instance = instances.get(container);\n instance?.unmount();\n instances.delete(container);\n logger.info('[mf-runtime][qiankun] unmount completed');\n } catch (error) {\n logger.error('[mf-runtime][qiankun] unmount failed', error);\n throw error;\n }\n }\n\n return { bootstrap, mount, unmount };\n}\n","import logger from '@seed-fe/logger';\nimport { createGarfishAdapter } from '../hosts/garfish';\nimport { createQiankunAdapter } from '../hosts/qiankun';\nimport type { AppInstance, InitRuntimeFn, RenderAppFn, StartStandaloneFn } from '../types/base';\nimport type { GarfishExports } from '../types/garfish';\nimport type { QiankunProps } from '../types/qiankun';\nimport type { HostAdapterConfig } from './hostManager';\nimport { initMicroFrontendHosts } from './hostManager';\nimport type { StandaloneOptions } from './standalone';\n\nexport interface MicroAppRuntimeOptions {\n /**\n * 微应用运行时初始化逻辑,由应用侧实现。\n * 典型职责:权限、认证、i18n 等一次性初始化。\n */\n initRuntime: InitRuntimeFn;\n /**\n * 微应用渲染逻辑,由应用侧实现。\n * - 适配层只关心 container / props 约定\n * - 内部可以是 React / Vue / 纯 DOM 等任意实现\n */\n mountApp: RenderAppFn;\n /**\n * 独立运行模式入口,由应用侧实现。\n * - 一般通过 createStandaloneStarter(initRuntime, renderApp) 生成\n * - 适配层只在未检测到任何宿主时调用\n */\n startStandalone: StartStandaloneFn;\n /**\n * 内置宿主框架配置\n *\n * - 默认全部启用(garfish: true, qiankun: true)\n * - 设置为 false 可禁用特定框架\n * - 设置为 {} 等同于全部启用\n *\n * @example\n * ```ts\n * // 默认全部启用\n * createMicroAppRuntime({ initRuntime, mountApp, startStandalone });\n *\n * // 仅启用 garfish\n * createMicroAppRuntime({\n * initRuntime,\n * mountApp,\n * startStandalone,\n * hosts: { garfish: true, qiankun: false },\n * });\n *\n * // 禁用所有内置框架,仅使用 extraHosts\n * createMicroAppRuntime({\n * initRuntime,\n * mountApp,\n * startStandalone,\n * hosts: { garfish: false, qiankun: false },\n * extraHosts: [customHost],\n * });\n * ```\n */\n hosts?: {\n garfish?: boolean;\n qiankun?: boolean;\n };\n /**\n * 额外宿主配置,用于接入其他微前端库\n * - 适合其他团队维护的宿主,仅需在微应用中传入配置即可\n */\n extraHosts?: HostAdapterConfig[];\n}\n\nexport interface MicroAppRuntime {\n /**\n * 独立运行模式入口(直接透传应用侧实现)\n */\n startStandaloneApp: (options?: StandaloneOptions) => Promise<AppInstance>;\n /**\n * qiankun 生命周期适配结果\n * - 需要在微应用中按需导出:export const { bootstrap, mount, unmount } = runtime.qiankun ?? {};\n */\n qiankun?: {\n bootstrap: () => Promise<void>;\n mount: (props: QiankunProps) => void;\n unmount: (props?: QiankunProps) => void;\n };\n}\n\n/**\n * 创建微应用运行时适配:\n * - 接收应用侧的 initRuntime / mountApp / startStandalone\n * - 内部完成 Garfish / qiankun 等宿主的适配与检测\n * - 返回 qiankun 生命周期供微应用按需导出\n *\n * 微应用层只需要:\n * 1. 提供 initRuntime / mountApp / startStandalone\n * 2. 在入口处调用 createMicroAppRuntime(...)\n * 3. 若需要支持 qiankun,再将 runtime.qiankun 的三个生命周期导出\n */\nexport function createMicroAppRuntime(options: MicroAppRuntimeOptions): MicroAppRuntime {\n const { initRuntime, mountApp, startStandalone, hosts, extraHosts } = options;\n\n // 默认全部启用\n const garfishEnabled = hosts?.garfish ?? true;\n const qiankunEnabled = hosts?.qiankun ?? true;\n\n const hostAdapters: HostAdapterConfig[] = [];\n\n // Garfish:通过 __GARFISH__ / __GARFISH_EXPORTS__ 适配 provider\n if (garfishEnabled) {\n const { provider } = createGarfishAdapter({\n initRuntime,\n renderApp: (garfishOptions) =>\n mountApp({\n container: garfishOptions.container,\n props: garfishOptions.props,\n }),\n });\n\n // 宿主模式下:若检测到 Garfish 标识,则立即挂载 provider。\n // 兼容两种注入方式:\n // - 宿主预先创建 __GARFISH_EXPORTS__\n // - 子应用自行创建 __GARFISH_EXPORTS__\n if (typeof window !== 'undefined' && (window as Window & { __GARFISH__?: boolean }).__GARFISH__) {\n const globalWithExports = globalThis as typeof globalThis & { __GARFISH_EXPORTS__?: GarfishExports };\n if (!globalWithExports.__GARFISH_EXPORTS__) {\n globalWithExports.__GARFISH_EXPORTS__ = {} as GarfishExports;\n }\n globalWithExports.__GARFISH_EXPORTS__.provider = provider;\n }\n\n hostAdapters.push({\n name: 'garfish',\n detect: () => Boolean(window.__GARFISH__),\n activate: () => {\n if (typeof __GARFISH_EXPORTS__ !== 'undefined') {\n __GARFISH_EXPORTS__.provider = provider;\n }\n },\n });\n }\n\n // qiankun:返回标准生命周期,由微应用按需导出\n let qiankunRuntime: MicroAppRuntime['qiankun'];\n\n if (qiankunEnabled) {\n const { bootstrap, mount, unmount } = createQiankunAdapter({\n initRuntime,\n renderApp: mountApp,\n });\n\n qiankunRuntime = {\n bootstrap,\n mount,\n unmount,\n };\n\n // 将 qiankun 添加到 hosts 数组用于检测\n // 虽然 qiankun 不需要 activate(宿主会主动调用生命周期),\n // 但仍需要 detect 以防止错误地进入独立运行模式\n hostAdapters.push({\n name: 'qiankun',\n detect: () => Boolean(window.__POWERED_BY_QIANKUN__),\n activate: () => {\n logger.info(`[mf-adapter] qiankun`);\n // qiankun 宿主会主动调用生命周期,无需额外激活\n },\n });\n }\n\n if (extraHosts?.length) {\n hostAdapters.push(...extraHosts);\n }\n\n // 初始化宿主检测 + 独立运行回退\n void initMicroFrontendHosts({\n hosts: hostAdapters,\n fallback: () => startStandalone(),\n });\n\n return {\n startStandaloneApp: startStandalone,\n qiankun: qiankunRuntime,\n };\n}\n","import type { AppInstance, InitRuntimeFn, RenderAppFn, RuntimeProps } from '../types/base';\n\nexport interface StandaloneOptions {\n container?: Document;\n props?: RuntimeProps;\n}\n\nexport interface StandaloneStarterOptions {\n initRuntime: InitRuntimeFn;\n renderApp: RenderAppFn;\n}\n\n/**\n * 创建独立运行模式启动器:\n * - 统一处理非微前端宿主环境下的初始化逻辑\n * - 内部保证单例实例,避免重复挂载\n */\nexport function createStandaloneStarter(options: StandaloneStarterOptions) {\n const { initRuntime, renderApp } = options;\n\n let standaloneInstance: AppInstance | null = null;\n\n return async function startStandaloneApp(customOptions?: StandaloneOptions): Promise<AppInstance> {\n if (standaloneInstance) {\n return standaloneInstance;\n }\n\n await initRuntime();\n\n standaloneInstance = renderApp({\n container: customOptions?.container ?? document,\n props: customOptions?.props,\n });\n\n return standaloneInstance;\n };\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@seed-fe/mf-adapters",
|
|
3
|
+
"version": "1.0.0-alpha.1",
|
|
4
|
+
"description": "微前端适配工具库,支持 React/Vue/任意框架在 Garfish/qiankun 等宿主中运行",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public",
|
|
11
|
+
"provenance": false
|
|
12
|
+
},
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"require": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md",
|
|
23
|
+
"LICENSE"
|
|
24
|
+
],
|
|
25
|
+
"keywords": [
|
|
26
|
+
"micro-frontend",
|
|
27
|
+
"microfrontend",
|
|
28
|
+
"garfish",
|
|
29
|
+
"qiankun",
|
|
30
|
+
"react",
|
|
31
|
+
"runtime"
|
|
32
|
+
],
|
|
33
|
+
"author": "xianghongai",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/xianghongai/seed-fe-mf-adapters.git"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/xianghongai/seed-fe-mf-adapters/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/xianghongai/seed-fe-mf-adapters#readme",
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@seed-fe/logger": "^1.0.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@biomejs/biome": "2.3.10",
|
|
48
|
+
"jsdom": "^27.4.0",
|
|
49
|
+
"npm-check-updates": "^19.1.2",
|
|
50
|
+
"tsup": "^8.5.1",
|
|
51
|
+
"typescript": "^5.9.3",
|
|
52
|
+
"vitest": "^1.6.1"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"dev": "tsup --watch",
|
|
56
|
+
"build": "tsup",
|
|
57
|
+
"typecheck": "tsc --noEmit",
|
|
58
|
+
"check": "pnpm typecheck && biome check --write",
|
|
59
|
+
"format": "biome format --write",
|
|
60
|
+
"lint": "biome check --write",
|
|
61
|
+
"test": "vitest run",
|
|
62
|
+
"test:watch": "vitest",
|
|
63
|
+
"test:coverage": "vitest run --coverage"
|
|
64
|
+
}
|
|
65
|
+
}
|