@hhfenpm/micro-app 1.0.0 → 1.0.2
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/dist/index.esm.js +84 -99
- package/dist/index.js +84 -99
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 微前端通信桥接
|
|
3
|
-
* 支持父子应用之间的方法调用和通信
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
1
|
const BRIDGE$1 = {
|
|
7
2
|
INVOKE: 'bridge-invoke',
|
|
8
3
|
CALLBACK: 'bridge-callback',
|
|
@@ -24,27 +19,15 @@ const safeClone = value => {
|
|
|
24
19
|
}
|
|
25
20
|
};
|
|
26
21
|
|
|
27
|
-
/**
|
|
28
|
-
* 初始化通信桥接
|
|
29
|
-
* @param {Object} options - 配置选项
|
|
30
|
-
* @param {boolean} options.isParent - 是否为父应用,默认 false
|
|
31
|
-
* @param {Object} options.vm - Vue 实例(可选)
|
|
32
|
-
* @param {string} options.iframeSelector - iframe 选择器,默认 '#microApp'
|
|
33
|
-
* @param {Object} options.handlers - 处理器对象(父应用需要提供)
|
|
34
|
-
* @returns {void}
|
|
35
|
-
*/
|
|
36
22
|
const initBridge = ({
|
|
37
23
|
isParent = false,
|
|
38
24
|
vm,
|
|
39
25
|
iframeSelector = '#microApp',
|
|
40
26
|
handlers = {},
|
|
41
27
|
} = {}) => {
|
|
42
|
-
// 父应用使用传入的 handlers,子应用为空对象
|
|
43
28
|
const finalHandlers = isParent ? handlers : Object.create(null);
|
|
44
|
-
|
|
45
29
|
const pending = Object.create(null);
|
|
46
30
|
|
|
47
|
-
// 子应用:创建 $base 代理对象,用于调用父应用方法
|
|
48
31
|
if (!isParent && vm) {
|
|
49
32
|
vm.$base = new Proxy(
|
|
50
33
|
{},
|
|
@@ -76,7 +59,6 @@ const initBridge = ({
|
|
|
76
59
|
vm.$baseReady = true;
|
|
77
60
|
}
|
|
78
61
|
|
|
79
|
-
// 处理来自子应用的调用请求(父应用)
|
|
80
62
|
const handleInvoke = e => {
|
|
81
63
|
const { action, params, callbackId } = e.data || {};
|
|
82
64
|
if (!action || !callbackId) return
|
|
@@ -107,7 +89,6 @@ const initBridge = ({
|
|
|
107
89
|
}
|
|
108
90
|
};
|
|
109
91
|
|
|
110
|
-
// 处理来自父应用的响应(子应用)
|
|
111
92
|
const handleCallback = e => {
|
|
112
93
|
const { callbackId, result } = e.data || {};
|
|
113
94
|
if (!callbackId || !pending[callbackId]) return
|
|
@@ -116,7 +97,6 @@ const initBridge = ({
|
|
|
116
97
|
delete pending[callbackId];
|
|
117
98
|
};
|
|
118
99
|
|
|
119
|
-
// 监听消息
|
|
120
100
|
window.addEventListener('message', e => {
|
|
121
101
|
if (e.origin !== window.location.origin) return
|
|
122
102
|
|
|
@@ -126,18 +106,88 @@ const initBridge = ({
|
|
|
126
106
|
});
|
|
127
107
|
};
|
|
128
108
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
109
|
+
var uiHandler = vm => ({
|
|
110
|
+
$message: (...args) => vm.$message(...args),
|
|
111
|
+
$success: msg => vm.$message.success(msg),
|
|
112
|
+
$warning: msg => vm.$message.warning(msg),
|
|
113
|
+
$error: msg => vm.$message.error(msg),
|
|
114
|
+
$notify: options => vm.$notify(options),
|
|
115
|
+
$confirm: (...args) =>
|
|
116
|
+
vm
|
|
117
|
+
.$confirm(...args)
|
|
118
|
+
.then(() => true)
|
|
119
|
+
.catch(() => false),
|
|
120
|
+
$alert: (...args) =>
|
|
121
|
+
vm
|
|
122
|
+
.$alert(...args)
|
|
123
|
+
.then(() => true)
|
|
124
|
+
.catch(() => false),
|
|
125
|
+
$prompt: (...args) =>
|
|
126
|
+
vm
|
|
127
|
+
.$prompt(...args)
|
|
128
|
+
.then(res => res.value)
|
|
129
|
+
.catch(() => null),
|
|
130
|
+
$loading: options => {
|
|
131
|
+
const loading = vm.$loading(options);
|
|
132
|
+
return () => loading.close()
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const noop = () => console.warn('[bridge] electron 不可用');
|
|
137
|
+
|
|
138
|
+
const KEYS = [
|
|
139
|
+
'renderer_listen',
|
|
140
|
+
'web_send',
|
|
141
|
+
'web_send_path',
|
|
142
|
+
'show',
|
|
143
|
+
'hide',
|
|
144
|
+
'quit',
|
|
145
|
+
'showAlertDialog',
|
|
146
|
+
'closeAlertDialog',
|
|
147
|
+
'closeAlertDialogAndJump',
|
|
148
|
+
'set_bounds',
|
|
149
|
+
'get_bounds',
|
|
150
|
+
'workarea',
|
|
151
|
+
'center',
|
|
152
|
+
'maximize',
|
|
153
|
+
'unmaximize',
|
|
154
|
+
'is_maximized',
|
|
155
|
+
'minimize',
|
|
156
|
+
'open_top',
|
|
157
|
+
'close_top',
|
|
158
|
+
'update',
|
|
159
|
+
'collapse',
|
|
160
|
+
'unfold',
|
|
161
|
+
'unfoldMax',
|
|
162
|
+
'get_version',
|
|
163
|
+
];
|
|
164
|
+
|
|
165
|
+
function createCs(electron = {}) {
|
|
166
|
+
const base = Object.fromEntries(
|
|
167
|
+
KEYS.map(k => [k, typeof electron[k] === 'function' ? electron[k] : noop])
|
|
168
|
+
);
|
|
169
|
+
return {
|
|
170
|
+
...electron,
|
|
171
|
+
...base,
|
|
172
|
+
is_app:
|
|
173
|
+
typeof electron.is_app === 'function'
|
|
174
|
+
? electron.is_app()
|
|
175
|
+
: !!electron.is_app,
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function createRegisterHandlers(getElectron) {
|
|
180
|
+
let electron = {};
|
|
181
|
+
try {
|
|
182
|
+
if (typeof getElectron === 'function') electron = getElectron();
|
|
183
|
+
} catch {}
|
|
184
|
+
|
|
185
|
+
return vm => ({
|
|
186
|
+
ui: uiHandler(vm),
|
|
187
|
+
cs: createCs(electron),
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
|
|
141
191
|
function createMicroAppCore({
|
|
142
192
|
modelMap,
|
|
143
193
|
enabledModules,
|
|
@@ -148,10 +198,6 @@ function createMicroAppCore({
|
|
|
148
198
|
|
|
149
199
|
const MAP = modelMap();
|
|
150
200
|
|
|
151
|
-
/**
|
|
152
|
-
* 获取启用的模块列表
|
|
153
|
-
* @returns {Array<string>|null}
|
|
154
|
-
*/
|
|
155
201
|
const getEnabledModules = () => {
|
|
156
202
|
if (Array.isArray(enabledModules)) {
|
|
157
203
|
return enabledModules
|
|
@@ -159,18 +205,12 @@ function createMicroAppCore({
|
|
|
159
205
|
if (typeof enabledModules === 'function') {
|
|
160
206
|
return enabledModules()
|
|
161
207
|
}
|
|
162
|
-
// 默认从 window.GLOBAL_CONFIG.microApp 获取
|
|
163
208
|
if (typeof window !== 'undefined' && window.GLOBAL_CONFIG) {
|
|
164
209
|
return window.GLOBAL_CONFIG.microApp || null
|
|
165
210
|
}
|
|
166
211
|
return null
|
|
167
212
|
};
|
|
168
213
|
|
|
169
|
-
/**
|
|
170
|
-
* 根据路径获取对应的微前端模块名
|
|
171
|
-
* @param {string} path - 路由路径
|
|
172
|
-
* @returns {string|null} 模块名,如果不在任何模块中则返回 null
|
|
173
|
-
*/
|
|
174
214
|
const microAppModule = path => {
|
|
175
215
|
const value = path.split('?')[0];
|
|
176
216
|
const key = Object.keys(MAP).find(key => MAP[key].includes(value));
|
|
@@ -178,22 +218,12 @@ function createMicroAppCore({
|
|
|
178
218
|
return DATA?.includes(key) ? key : null
|
|
179
219
|
};
|
|
180
220
|
|
|
181
|
-
/**
|
|
182
|
-
* 生成微前端应用的完整 URL
|
|
183
|
-
* @param {string} path - 路由路径
|
|
184
|
-
* @returns {string} 完整的 URL
|
|
185
|
-
*/
|
|
186
221
|
const microAppSrc = path => {
|
|
187
222
|
const module = microAppModule(path);
|
|
188
223
|
const base = window.location.href.split('#')[0];
|
|
189
224
|
return `${base}${module ? `${module}/` : ''}#${path}`
|
|
190
225
|
};
|
|
191
226
|
|
|
192
|
-
/**
|
|
193
|
-
* 检测微前端模块是否已部署
|
|
194
|
-
* @param {string} module - 模块名
|
|
195
|
-
* @returns {Promise<boolean>} 是否已部署
|
|
196
|
-
*/
|
|
197
227
|
const microAppDeployed = async module => {
|
|
198
228
|
try {
|
|
199
229
|
const result = await fetch(`/${module}`, {
|
|
@@ -213,23 +243,6 @@ function createMicroAppCore({
|
|
|
213
243
|
}
|
|
214
244
|
}
|
|
215
245
|
|
|
216
|
-
/**
|
|
217
|
-
* 创建默认的微前端核心功能实例
|
|
218
|
-
* 使用 window.GLOBAL_CONFIG.microApp 作为配置源
|
|
219
|
-
* @param {Function} modelMap - 模块路由映射函数
|
|
220
|
-
* @returns {Object} 核心功能对象
|
|
221
|
-
*/
|
|
222
|
-
function createDefaultMicroAppCore(modelMap) {
|
|
223
|
-
return createMicroAppCore({
|
|
224
|
-
modelMap,
|
|
225
|
-
})
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Vuex 状态同步插件
|
|
230
|
-
* 用于在父子应用之间同步 Vuex store 状态
|
|
231
|
-
*/
|
|
232
|
-
|
|
233
246
|
const MESSAGE = {
|
|
234
247
|
SYNC_FROM_CHILD: 'sync-base-from-child',
|
|
235
248
|
SYNC_FROM_PARENT: 'sync-base-from-parent',
|
|
@@ -283,13 +296,6 @@ const syncRouteFromChild = fullPath => {
|
|
|
283
296
|
}
|
|
284
297
|
};
|
|
285
298
|
|
|
286
|
-
/**
|
|
287
|
-
* 创建状态同步插件
|
|
288
|
-
* @param {Object} options - 配置选项
|
|
289
|
-
* @param {boolean} options.isParent - 是否为父应用,默认 false
|
|
290
|
-
* @param {string} options.iframeSelector - iframe 选择器,默认 '#microApp'
|
|
291
|
-
* @returns {Function} Vuex 插件函数
|
|
292
|
-
*/
|
|
293
299
|
function baseSyncPlugin({
|
|
294
300
|
isParent = false,
|
|
295
301
|
iframeSelector = '#microApp',
|
|
@@ -297,7 +303,6 @@ function baseSyncPlugin({
|
|
|
297
303
|
return store => {
|
|
298
304
|
let latestBaseState = store.state.base;
|
|
299
305
|
|
|
300
|
-
// 监听 base 状态变化,自动同步
|
|
301
306
|
store.watch(
|
|
302
307
|
state => state.base,
|
|
303
308
|
newBase => {
|
|
@@ -317,7 +322,6 @@ function baseSyncPlugin({
|
|
|
317
322
|
{ deep: true }
|
|
318
323
|
);
|
|
319
324
|
|
|
320
|
-
// 附加路由同步功能(子应用使用)
|
|
321
325
|
store.attachRouterSync = router => {
|
|
322
326
|
if (!router || isParent) return
|
|
323
327
|
router.afterEach(to => {
|
|
@@ -337,7 +341,6 @@ function baseSyncPlugin({
|
|
|
337
341
|
});
|
|
338
342
|
};
|
|
339
343
|
|
|
340
|
-
// 调用微前端生命周期(父应用使用)
|
|
341
344
|
store.callMicroAppLifeCycle = (type, payload) => {
|
|
342
345
|
if (!isParent) return
|
|
343
346
|
if (!isLifeCycleMessage(type)) return
|
|
@@ -348,30 +351,25 @@ function baseSyncPlugin({
|
|
|
348
351
|
});
|
|
349
352
|
};
|
|
350
353
|
|
|
351
|
-
// 处理消息
|
|
352
354
|
const handleMessage = event => {
|
|
353
355
|
if (event.origin !== window.location.origin) return
|
|
354
356
|
const { type, payload, fullPath } = event.data || {};
|
|
355
357
|
|
|
356
|
-
// 子应用处理生命周期消息
|
|
357
358
|
if (!isParent && isLifeCycleMessage(type)) {
|
|
358
359
|
window.__MICRO_APP_LIFECYCLE__?.[type]?.(payload);
|
|
359
360
|
return
|
|
360
361
|
}
|
|
361
362
|
|
|
362
|
-
// 父应用处理来自子应用的状态同步
|
|
363
363
|
if (isParent && type === MESSAGE.SYNC_FROM_CHILD) {
|
|
364
364
|
store.commit('base/SYNC_STATE', payload);
|
|
365
365
|
return
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
-
// 子应用处理来自父应用的状态同步
|
|
369
368
|
if (!isParent && type === MESSAGE.SYNC_FROM_PARENT) {
|
|
370
369
|
store.commit('base/SYNC_STATE', payload);
|
|
371
370
|
return
|
|
372
371
|
}
|
|
373
372
|
|
|
374
|
-
// 父应用响应子应用的状态请求
|
|
375
373
|
if (isParent && type === MESSAGE.REQUEST_FROM_CHILD) {
|
|
376
374
|
postToChild(iframeSelector, {
|
|
377
375
|
type: MESSAGE.SYNC_FROM_PARENT,
|
|
@@ -380,13 +378,11 @@ function baseSyncPlugin({
|
|
|
380
378
|
return
|
|
381
379
|
}
|
|
382
380
|
|
|
383
|
-
// 父应用处理子应用的路由变化
|
|
384
381
|
if (isParent && type === MESSAGE.CHILD_ROUTE_CHANGE) {
|
|
385
382
|
syncRouteFromChild(fullPath);
|
|
386
383
|
return
|
|
387
384
|
}
|
|
388
385
|
|
|
389
|
-
// 父应用转发其他消息到父窗口
|
|
390
386
|
if (isParent && !isInternalMessage(type) && !isBridgeMessage(type)) {
|
|
391
387
|
window.parent?.postMessage(event.data || {}, '*');
|
|
392
388
|
}
|
|
@@ -394,23 +390,12 @@ function baseSyncPlugin({
|
|
|
394
390
|
|
|
395
391
|
window.addEventListener('message', handleMessage);
|
|
396
392
|
|
|
397
|
-
// 子应用初始化时请求父应用状态
|
|
398
393
|
if (!isParent && window.parent) {
|
|
399
394
|
postToParent({ type: MESSAGE.REQUEST_FROM_CHILD });
|
|
400
395
|
}
|
|
401
396
|
}
|
|
402
397
|
}
|
|
403
398
|
|
|
404
|
-
|
|
405
|
-
* @hhfenpm/micro-app
|
|
406
|
-
* 微前端通信桥接和状态同步工具
|
|
407
|
-
*/
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
var index = {
|
|
411
|
-
initBridge,
|
|
412
|
-
createDefaultMicroAppCore,
|
|
413
|
-
baseSyncPlugin,
|
|
414
|
-
};
|
|
399
|
+
var index = { initBridge, baseSyncPlugin };
|
|
415
400
|
|
|
416
|
-
export { baseSyncPlugin,
|
|
401
|
+
export { baseSyncPlugin, createMicroAppCore, createRegisterHandlers, index as default, initBridge };
|
package/dist/index.js
CHANGED
|
@@ -2,11 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* 微前端通信桥接
|
|
7
|
-
* 支持父子应用之间的方法调用和通信
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
5
|
const BRIDGE$1 = {
|
|
11
6
|
INVOKE: 'bridge-invoke',
|
|
12
7
|
CALLBACK: 'bridge-callback',
|
|
@@ -28,27 +23,15 @@ const safeClone = value => {
|
|
|
28
23
|
}
|
|
29
24
|
};
|
|
30
25
|
|
|
31
|
-
/**
|
|
32
|
-
* 初始化通信桥接
|
|
33
|
-
* @param {Object} options - 配置选项
|
|
34
|
-
* @param {boolean} options.isParent - 是否为父应用,默认 false
|
|
35
|
-
* @param {Object} options.vm - Vue 实例(可选)
|
|
36
|
-
* @param {string} options.iframeSelector - iframe 选择器,默认 '#microApp'
|
|
37
|
-
* @param {Object} options.handlers - 处理器对象(父应用需要提供)
|
|
38
|
-
* @returns {void}
|
|
39
|
-
*/
|
|
40
26
|
const initBridge = ({
|
|
41
27
|
isParent = false,
|
|
42
28
|
vm,
|
|
43
29
|
iframeSelector = '#microApp',
|
|
44
30
|
handlers = {},
|
|
45
31
|
} = {}) => {
|
|
46
|
-
// 父应用使用传入的 handlers,子应用为空对象
|
|
47
32
|
const finalHandlers = isParent ? handlers : Object.create(null);
|
|
48
|
-
|
|
49
33
|
const pending = Object.create(null);
|
|
50
34
|
|
|
51
|
-
// 子应用:创建 $base 代理对象,用于调用父应用方法
|
|
52
35
|
if (!isParent && vm) {
|
|
53
36
|
vm.$base = new Proxy(
|
|
54
37
|
{},
|
|
@@ -80,7 +63,6 @@ const initBridge = ({
|
|
|
80
63
|
vm.$baseReady = true;
|
|
81
64
|
}
|
|
82
65
|
|
|
83
|
-
// 处理来自子应用的调用请求(父应用)
|
|
84
66
|
const handleInvoke = e => {
|
|
85
67
|
const { action, params, callbackId } = e.data || {};
|
|
86
68
|
if (!action || !callbackId) return
|
|
@@ -111,7 +93,6 @@ const initBridge = ({
|
|
|
111
93
|
}
|
|
112
94
|
};
|
|
113
95
|
|
|
114
|
-
// 处理来自父应用的响应(子应用)
|
|
115
96
|
const handleCallback = e => {
|
|
116
97
|
const { callbackId, result } = e.data || {};
|
|
117
98
|
if (!callbackId || !pending[callbackId]) return
|
|
@@ -120,7 +101,6 @@ const initBridge = ({
|
|
|
120
101
|
delete pending[callbackId];
|
|
121
102
|
};
|
|
122
103
|
|
|
123
|
-
// 监听消息
|
|
124
104
|
window.addEventListener('message', e => {
|
|
125
105
|
if (e.origin !== window.location.origin) return
|
|
126
106
|
|
|
@@ -130,18 +110,88 @@ const initBridge = ({
|
|
|
130
110
|
});
|
|
131
111
|
};
|
|
132
112
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
113
|
+
var uiHandler = vm => ({
|
|
114
|
+
$message: (...args) => vm.$message(...args),
|
|
115
|
+
$success: msg => vm.$message.success(msg),
|
|
116
|
+
$warning: msg => vm.$message.warning(msg),
|
|
117
|
+
$error: msg => vm.$message.error(msg),
|
|
118
|
+
$notify: options => vm.$notify(options),
|
|
119
|
+
$confirm: (...args) =>
|
|
120
|
+
vm
|
|
121
|
+
.$confirm(...args)
|
|
122
|
+
.then(() => true)
|
|
123
|
+
.catch(() => false),
|
|
124
|
+
$alert: (...args) =>
|
|
125
|
+
vm
|
|
126
|
+
.$alert(...args)
|
|
127
|
+
.then(() => true)
|
|
128
|
+
.catch(() => false),
|
|
129
|
+
$prompt: (...args) =>
|
|
130
|
+
vm
|
|
131
|
+
.$prompt(...args)
|
|
132
|
+
.then(res => res.value)
|
|
133
|
+
.catch(() => null),
|
|
134
|
+
$loading: options => {
|
|
135
|
+
const loading = vm.$loading(options);
|
|
136
|
+
return () => loading.close()
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const noop = () => console.warn('[bridge] electron 不可用');
|
|
141
|
+
|
|
142
|
+
const KEYS = [
|
|
143
|
+
'renderer_listen',
|
|
144
|
+
'web_send',
|
|
145
|
+
'web_send_path',
|
|
146
|
+
'show',
|
|
147
|
+
'hide',
|
|
148
|
+
'quit',
|
|
149
|
+
'showAlertDialog',
|
|
150
|
+
'closeAlertDialog',
|
|
151
|
+
'closeAlertDialogAndJump',
|
|
152
|
+
'set_bounds',
|
|
153
|
+
'get_bounds',
|
|
154
|
+
'workarea',
|
|
155
|
+
'center',
|
|
156
|
+
'maximize',
|
|
157
|
+
'unmaximize',
|
|
158
|
+
'is_maximized',
|
|
159
|
+
'minimize',
|
|
160
|
+
'open_top',
|
|
161
|
+
'close_top',
|
|
162
|
+
'update',
|
|
163
|
+
'collapse',
|
|
164
|
+
'unfold',
|
|
165
|
+
'unfoldMax',
|
|
166
|
+
'get_version',
|
|
167
|
+
];
|
|
168
|
+
|
|
169
|
+
function createCs(electron = {}) {
|
|
170
|
+
const base = Object.fromEntries(
|
|
171
|
+
KEYS.map(k => [k, typeof electron[k] === 'function' ? electron[k] : noop])
|
|
172
|
+
);
|
|
173
|
+
return {
|
|
174
|
+
...electron,
|
|
175
|
+
...base,
|
|
176
|
+
is_app:
|
|
177
|
+
typeof electron.is_app === 'function'
|
|
178
|
+
? electron.is_app()
|
|
179
|
+
: !!electron.is_app,
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function createRegisterHandlers(getElectron) {
|
|
184
|
+
let electron = {};
|
|
185
|
+
try {
|
|
186
|
+
if (typeof getElectron === 'function') electron = getElectron();
|
|
187
|
+
} catch {}
|
|
188
|
+
|
|
189
|
+
return vm => ({
|
|
190
|
+
ui: uiHandler(vm),
|
|
191
|
+
cs: createCs(electron),
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
|
|
145
195
|
function createMicroAppCore({
|
|
146
196
|
modelMap,
|
|
147
197
|
enabledModules,
|
|
@@ -152,10 +202,6 @@ function createMicroAppCore({
|
|
|
152
202
|
|
|
153
203
|
const MAP = modelMap();
|
|
154
204
|
|
|
155
|
-
/**
|
|
156
|
-
* 获取启用的模块列表
|
|
157
|
-
* @returns {Array<string>|null}
|
|
158
|
-
*/
|
|
159
205
|
const getEnabledModules = () => {
|
|
160
206
|
if (Array.isArray(enabledModules)) {
|
|
161
207
|
return enabledModules
|
|
@@ -163,18 +209,12 @@ function createMicroAppCore({
|
|
|
163
209
|
if (typeof enabledModules === 'function') {
|
|
164
210
|
return enabledModules()
|
|
165
211
|
}
|
|
166
|
-
// 默认从 window.GLOBAL_CONFIG.microApp 获取
|
|
167
212
|
if (typeof window !== 'undefined' && window.GLOBAL_CONFIG) {
|
|
168
213
|
return window.GLOBAL_CONFIG.microApp || null
|
|
169
214
|
}
|
|
170
215
|
return null
|
|
171
216
|
};
|
|
172
217
|
|
|
173
|
-
/**
|
|
174
|
-
* 根据路径获取对应的微前端模块名
|
|
175
|
-
* @param {string} path - 路由路径
|
|
176
|
-
* @returns {string|null} 模块名,如果不在任何模块中则返回 null
|
|
177
|
-
*/
|
|
178
218
|
const microAppModule = path => {
|
|
179
219
|
const value = path.split('?')[0];
|
|
180
220
|
const key = Object.keys(MAP).find(key => MAP[key].includes(value));
|
|
@@ -182,22 +222,12 @@ function createMicroAppCore({
|
|
|
182
222
|
return DATA?.includes(key) ? key : null
|
|
183
223
|
};
|
|
184
224
|
|
|
185
|
-
/**
|
|
186
|
-
* 生成微前端应用的完整 URL
|
|
187
|
-
* @param {string} path - 路由路径
|
|
188
|
-
* @returns {string} 完整的 URL
|
|
189
|
-
*/
|
|
190
225
|
const microAppSrc = path => {
|
|
191
226
|
const module = microAppModule(path);
|
|
192
227
|
const base = window.location.href.split('#')[0];
|
|
193
228
|
return `${base}${module ? `${module}/` : ''}#${path}`
|
|
194
229
|
};
|
|
195
230
|
|
|
196
|
-
/**
|
|
197
|
-
* 检测微前端模块是否已部署
|
|
198
|
-
* @param {string} module - 模块名
|
|
199
|
-
* @returns {Promise<boolean>} 是否已部署
|
|
200
|
-
*/
|
|
201
231
|
const microAppDeployed = async module => {
|
|
202
232
|
try {
|
|
203
233
|
const result = await fetch(`/${module}`, {
|
|
@@ -217,23 +247,6 @@ function createMicroAppCore({
|
|
|
217
247
|
}
|
|
218
248
|
}
|
|
219
249
|
|
|
220
|
-
/**
|
|
221
|
-
* 创建默认的微前端核心功能实例
|
|
222
|
-
* 使用 window.GLOBAL_CONFIG.microApp 作为配置源
|
|
223
|
-
* @param {Function} modelMap - 模块路由映射函数
|
|
224
|
-
* @returns {Object} 核心功能对象
|
|
225
|
-
*/
|
|
226
|
-
function createDefaultMicroAppCore(modelMap) {
|
|
227
|
-
return createMicroAppCore({
|
|
228
|
-
modelMap,
|
|
229
|
-
})
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Vuex 状态同步插件
|
|
234
|
-
* 用于在父子应用之间同步 Vuex store 状态
|
|
235
|
-
*/
|
|
236
|
-
|
|
237
250
|
const MESSAGE = {
|
|
238
251
|
SYNC_FROM_CHILD: 'sync-base-from-child',
|
|
239
252
|
SYNC_FROM_PARENT: 'sync-base-from-parent',
|
|
@@ -287,13 +300,6 @@ const syncRouteFromChild = fullPath => {
|
|
|
287
300
|
}
|
|
288
301
|
};
|
|
289
302
|
|
|
290
|
-
/**
|
|
291
|
-
* 创建状态同步插件
|
|
292
|
-
* @param {Object} options - 配置选项
|
|
293
|
-
* @param {boolean} options.isParent - 是否为父应用,默认 false
|
|
294
|
-
* @param {string} options.iframeSelector - iframe 选择器,默认 '#microApp'
|
|
295
|
-
* @returns {Function} Vuex 插件函数
|
|
296
|
-
*/
|
|
297
303
|
function baseSyncPlugin({
|
|
298
304
|
isParent = false,
|
|
299
305
|
iframeSelector = '#microApp',
|
|
@@ -301,7 +307,6 @@ function baseSyncPlugin({
|
|
|
301
307
|
return store => {
|
|
302
308
|
let latestBaseState = store.state.base;
|
|
303
309
|
|
|
304
|
-
// 监听 base 状态变化,自动同步
|
|
305
310
|
store.watch(
|
|
306
311
|
state => state.base,
|
|
307
312
|
newBase => {
|
|
@@ -321,7 +326,6 @@ function baseSyncPlugin({
|
|
|
321
326
|
{ deep: true }
|
|
322
327
|
);
|
|
323
328
|
|
|
324
|
-
// 附加路由同步功能(子应用使用)
|
|
325
329
|
store.attachRouterSync = router => {
|
|
326
330
|
if (!router || isParent) return
|
|
327
331
|
router.afterEach(to => {
|
|
@@ -341,7 +345,6 @@ function baseSyncPlugin({
|
|
|
341
345
|
});
|
|
342
346
|
};
|
|
343
347
|
|
|
344
|
-
// 调用微前端生命周期(父应用使用)
|
|
345
348
|
store.callMicroAppLifeCycle = (type, payload) => {
|
|
346
349
|
if (!isParent) return
|
|
347
350
|
if (!isLifeCycleMessage(type)) return
|
|
@@ -352,30 +355,25 @@ function baseSyncPlugin({
|
|
|
352
355
|
});
|
|
353
356
|
};
|
|
354
357
|
|
|
355
|
-
// 处理消息
|
|
356
358
|
const handleMessage = event => {
|
|
357
359
|
if (event.origin !== window.location.origin) return
|
|
358
360
|
const { type, payload, fullPath } = event.data || {};
|
|
359
361
|
|
|
360
|
-
// 子应用处理生命周期消息
|
|
361
362
|
if (!isParent && isLifeCycleMessage(type)) {
|
|
362
363
|
window.__MICRO_APP_LIFECYCLE__?.[type]?.(payload);
|
|
363
364
|
return
|
|
364
365
|
}
|
|
365
366
|
|
|
366
|
-
// 父应用处理来自子应用的状态同步
|
|
367
367
|
if (isParent && type === MESSAGE.SYNC_FROM_CHILD) {
|
|
368
368
|
store.commit('base/SYNC_STATE', payload);
|
|
369
369
|
return
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
-
// 子应用处理来自父应用的状态同步
|
|
373
372
|
if (!isParent && type === MESSAGE.SYNC_FROM_PARENT) {
|
|
374
373
|
store.commit('base/SYNC_STATE', payload);
|
|
375
374
|
return
|
|
376
375
|
}
|
|
377
376
|
|
|
378
|
-
// 父应用响应子应用的状态请求
|
|
379
377
|
if (isParent && type === MESSAGE.REQUEST_FROM_CHILD) {
|
|
380
378
|
postToChild(iframeSelector, {
|
|
381
379
|
type: MESSAGE.SYNC_FROM_PARENT,
|
|
@@ -384,13 +382,11 @@ function baseSyncPlugin({
|
|
|
384
382
|
return
|
|
385
383
|
}
|
|
386
384
|
|
|
387
|
-
// 父应用处理子应用的路由变化
|
|
388
385
|
if (isParent && type === MESSAGE.CHILD_ROUTE_CHANGE) {
|
|
389
386
|
syncRouteFromChild(fullPath);
|
|
390
387
|
return
|
|
391
388
|
}
|
|
392
389
|
|
|
393
|
-
// 父应用转发其他消息到父窗口
|
|
394
390
|
if (isParent && !isInternalMessage(type) && !isBridgeMessage(type)) {
|
|
395
391
|
window.parent?.postMessage(event.data || {}, '*');
|
|
396
392
|
}
|
|
@@ -398,27 +394,16 @@ function baseSyncPlugin({
|
|
|
398
394
|
|
|
399
395
|
window.addEventListener('message', handleMessage);
|
|
400
396
|
|
|
401
|
-
// 子应用初始化时请求父应用状态
|
|
402
397
|
if (!isParent && window.parent) {
|
|
403
398
|
postToParent({ type: MESSAGE.REQUEST_FROM_CHILD });
|
|
404
399
|
}
|
|
405
400
|
}
|
|
406
401
|
}
|
|
407
402
|
|
|
408
|
-
|
|
409
|
-
* @hhfenpm/micro-app
|
|
410
|
-
* 微前端通信桥接和状态同步工具
|
|
411
|
-
*/
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
var index = {
|
|
415
|
-
initBridge,
|
|
416
|
-
createDefaultMicroAppCore,
|
|
417
|
-
baseSyncPlugin,
|
|
418
|
-
};
|
|
403
|
+
var index = { initBridge, baseSyncPlugin };
|
|
419
404
|
|
|
420
405
|
exports.baseSyncPlugin = baseSyncPlugin;
|
|
421
|
-
exports.createDefaultMicroAppCore = createDefaultMicroAppCore;
|
|
422
406
|
exports.createMicroAppCore = createMicroAppCore;
|
|
407
|
+
exports.createRegisterHandlers = createRegisterHandlers;
|
|
423
408
|
exports.default = index;
|
|
424
409
|
exports.initBridge = initBridge;
|