@umijs/plugins 4.0.0-beta.9 → 4.0.0-rc.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.
Files changed (58) hide show
  1. package/README.md +4 -1
  2. package/dist/access.js +73 -1
  3. package/dist/{sass.d.ts → analytics.d.ts} +0 -0
  4. package/dist/analytics.js +67 -0
  5. package/dist/antd.js +89 -145
  6. package/dist/dva.d.ts +3 -0
  7. package/dist/dva.js +168 -4
  8. package/dist/initial-state.js +112 -1
  9. package/dist/layout.js +479 -1
  10. package/dist/locale.d.ts +1 -0
  11. package/dist/locale.js +199 -1
  12. package/dist/model.js +112 -1
  13. package/dist/moment2dayjs.d.ts +3 -0
  14. package/dist/moment2dayjs.js +96 -0
  15. package/dist/qiankun/constants.d.ts +5 -0
  16. package/dist/qiankun/constants.js +8 -0
  17. package/dist/qiankun/master.d.ts +6 -0
  18. package/dist/qiankun/master.js +114 -0
  19. package/dist/qiankun/slave.d.ts +3 -0
  20. package/dist/qiankun/slave.js +141 -0
  21. package/dist/qiankun.js +15 -1
  22. package/dist/request.js +300 -1
  23. package/dist/tailwindcss.d.ts +3 -0
  24. package/dist/tailwindcss.js +38 -0
  25. package/dist/unocss.d.ts +3 -0
  26. package/dist/unocss.js +57 -0
  27. package/dist/utils/astUtils.d.ts +3 -0
  28. package/dist/utils/astUtils.js +34 -0
  29. package/dist/utils/localeUtils.d.ts +33 -0
  30. package/dist/utils/localeUtils.js +135 -0
  31. package/dist/utils/modelUtils.d.ts +35 -0
  32. package/dist/utils/modelUtils.js +145 -0
  33. package/dist/utils/resolveProjectDep.d.ts +5 -0
  34. package/dist/utils/resolveProjectDep.js +15 -0
  35. package/dist/utils/withTmpPath.d.ts +6 -0
  36. package/dist/utils/withTmpPath.js +11 -0
  37. package/libs/dva.ts +10 -0
  38. package/libs/locale/SelectLang.tpl +478 -0
  39. package/libs/locale/locale.tpl +82 -0
  40. package/libs/locale/localeExports.tpl +271 -0
  41. package/libs/locale/runtime.tpl +33 -0
  42. package/libs/model.tsx +140 -0
  43. package/libs/qiankun/master/AntdErrorBoundary.tsx +34 -0
  44. package/libs/qiankun/master/AntdLoader.tsx +15 -0
  45. package/libs/qiankun/master/ErrorBoundary.tsx +7 -0
  46. package/libs/qiankun/master/MicroApp.tsx +262 -0
  47. package/libs/qiankun/master/MicroAppWithMemoHistory.tsx +43 -0
  48. package/libs/qiankun/master/common.ts +133 -0
  49. package/libs/qiankun/master/constants.ts +7 -0
  50. package/libs/qiankun/master/getMicroAppRouteComponent.tsx.tpl +45 -0
  51. package/libs/qiankun/master/masterRuntimePlugin.tsx +130 -0
  52. package/libs/qiankun/master/types.ts +44 -0
  53. package/libs/qiankun/slave/connectMaster.tsx +15 -0
  54. package/libs/qiankun/slave/lifecycles.ts +149 -0
  55. package/libs/qiankun/slave/qiankunModel.ts +19 -0
  56. package/libs/qiankun/slave/slaveRuntimePlugin.ts +21 -0
  57. package/package.json +21 -5
  58. package/dist/sass.js +0 -5
@@ -0,0 +1,262 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable */
3
+ __USE_MODEL__;
4
+ import concat from 'lodash/concat';
5
+ import mergeWith from 'lodash/mergeWith';
6
+ import noop from 'lodash/noop';
7
+ import {
8
+ FrameworkConfiguration,
9
+ loadMicroApp,
10
+ MicroApp as MicroAppType,
11
+ prefetchApps,
12
+ } from 'qiankun';
13
+ import React, {
14
+ forwardRef,
15
+ Ref,
16
+ useEffect,
17
+ useImperativeHandle,
18
+ useRef,
19
+ useState,
20
+ } from 'react';
21
+ import { ErrorBoundary } from './ErrorBoundary';
22
+ import { getMasterOptions } from './masterOptions';
23
+ import MicroAppLoader from './MicroAppLoader';
24
+ import { MasterOptions } from './types';
25
+
26
+ const qiankunStateForSlaveModelNamespace = '@@qiankunStateForSlave';
27
+
28
+ type HashHistory = {
29
+ type?: 'hash';
30
+ } & any;
31
+
32
+ type BrowserHistory = {
33
+ type?: 'browser';
34
+ } & any;
35
+
36
+ type MemoryHistory = {
37
+ type?: 'memory';
38
+ } & any;
39
+
40
+ export type Props = {
41
+ name: string;
42
+ settings?: FrameworkConfiguration;
43
+ base?: string;
44
+ history?:
45
+ | 'hash'
46
+ | 'browser'
47
+ | 'memory'
48
+ | HashHistory
49
+ | BrowserHistory
50
+ | MemoryHistory;
51
+ getMatchedBase?: () => string;
52
+ loader?: (loading: boolean) => React.ReactNode;
53
+ errorBoundary?: (error: any) => React.ReactNode;
54
+ onHistoryInit?: (history: any) => void;
55
+ autoSetLoading?: boolean;
56
+ autoCaptureError?: boolean;
57
+ // 仅开启 loader 时需要
58
+ wrapperClassName?: string;
59
+ className?: string;
60
+ } & Record<string, any>;
61
+
62
+ function unmountMicroApp(microApp?: MicroAppType) {
63
+ if (microApp) {
64
+ microApp.mountPromise.then(() => microApp.unmount());
65
+ }
66
+ }
67
+
68
+ let noneMounted = true;
69
+
70
+ export const MicroApp = forwardRef(
71
+ (componentProps: Props, componentRef: Ref<MicroAppType>) => {
72
+ const {
73
+ masterHistoryType,
74
+ apps = [],
75
+ lifeCycles: globalLifeCycles,
76
+ prefetch = true,
77
+ ...globalSettings
78
+ } = getMasterOptions() as MasterOptions;
79
+
80
+ const {
81
+ name,
82
+ settings: settingsFromProps = {},
83
+ loader,
84
+ errorBoundary,
85
+ lifeCycles,
86
+ wrapperClassName,
87
+ className,
88
+ ...propsFromParams
89
+ } = componentProps;
90
+
91
+ const [loading, setLoading] = useState(true);
92
+ const [error, setError] = useState<any>(null);
93
+ // 未配置自定义 errorBoundary 且开启了 autoCaptureError 场景下,使用插件默认的 errorBoundary,否则使用自定义 errorBoundary
94
+ const microAppErrorBoundary =
95
+ errorBoundary ||
96
+ (propsFromParams.autoCaptureError
97
+ ? (e) => <ErrorBoundary error={e} />
98
+ : null);
99
+
100
+ // 配置了 errorBoundary 才改 error 状态,否则直接往上抛异常
101
+ const setComponentError = (error: any) => {
102
+ if (microAppErrorBoundary) {
103
+ setError(error);
104
+ // error log 出来,不要吞
105
+ if (error) {
106
+ console.error(error);
107
+ }
108
+ } else if (error) {
109
+ throw error;
110
+ }
111
+ };
112
+
113
+ const containerRef = useRef<HTMLDivElement>();
114
+ const microAppRef = useRef<MicroAppType>();
115
+ const updatingPromise = useRef<Promise<any>>();
116
+ const updatingTimestamp = useRef(Date.now());
117
+
118
+ useImperativeHandle(componentRef, () => microAppRef.current);
119
+
120
+ const appConfig = apps.find((app: any) => app.name === name);
121
+ useEffect(() => {
122
+ if (!appConfig) {
123
+ setComponentError(
124
+ new Error(
125
+ `[@umijs/plugin-qiankun]: Can not find the configuration of ${name} app!`,
126
+ ),
127
+ );
128
+ }
129
+ return noop;
130
+ }, []);
131
+
132
+ // 约定使用 src/app.ts/useQiankunStateForSlave 中的数据作为主应用透传给微应用的 props,优先级高于 propsFromConfig
133
+ const stateForSlave = (useModel || noop)(
134
+ qiankunStateForSlaveModelNamespace,
135
+ );
136
+ const { entry, props: propsFromConfig = {} } = appConfig || {};
137
+
138
+ useEffect(() => {
139
+ setComponentError(null);
140
+ setLoading(true);
141
+ const configuration = {
142
+ globalContext: window,
143
+ ...globalSettings,
144
+ ...settingsFromProps,
145
+ };
146
+ microAppRef.current = loadMicroApp(
147
+ {
148
+ name,
149
+ entry,
150
+ container: containerRef.current!,
151
+ props: {
152
+ ...propsFromConfig,
153
+ ...stateForSlave,
154
+ ...propsFromParams,
155
+ setLoading,
156
+ },
157
+ },
158
+ configuration,
159
+ mergeWith({}, globalLifeCycles, lifeCycles, (v1, v2) =>
160
+ concat(v1 ?? [], v2 ?? []),
161
+ ),
162
+ );
163
+
164
+ // 当配置了 prefetch true 时,在第一个应用 mount 完成之后,再去预加载其他应用
165
+ if (prefetch && prefetch !== 'all' && noneMounted) {
166
+ microAppRef.current?.mountPromise.then(() => {
167
+ if (noneMounted) {
168
+ if (Array.isArray(prefetch)) {
169
+ const specialPrefetchApps = apps.filter(
170
+ (app) => app.name !== name && prefetch.indexOf(app.name) !== -1,
171
+ );
172
+ prefetchApps(specialPrefetchApps, configuration);
173
+ } else {
174
+ const otherNotMountedApps = apps.filter(
175
+ (app) => app.name !== name,
176
+ );
177
+ prefetchApps(otherNotMountedApps, configuration);
178
+ }
179
+ noneMounted = false;
180
+ }
181
+ });
182
+ }
183
+
184
+ (['loadPromise', 'bootstrapPromise', 'mountPromise'] as const).forEach(
185
+ (key) => {
186
+ const promise = microAppRef.current?.[key];
187
+ promise.catch((e) => {
188
+ setComponentError(e);
189
+ setLoading(false);
190
+ });
191
+ },
192
+ );
193
+
194
+ return () => unmountMicroApp(microAppRef.current);
195
+ }, [name]);
196
+
197
+ useEffect(() => {
198
+ const microApp = microAppRef.current;
199
+ if (microApp) {
200
+ if (!updatingPromise.current) {
201
+ // 初始化 updatingPromise 为 microApp.mountPromise,从而确保后续更新是在应用 mount 完成之后
202
+ updatingPromise.current = microApp.mountPromise;
203
+ } else {
204
+ // 确保 microApp.update 调用是跟组件状态变更顺序一致的,且后一个微应用更新必须等待前一个更新完成
205
+ updatingPromise.current = updatingPromise.current.then(() => {
206
+ const canUpdate = (microApp?: MicroAppType) =>
207
+ microApp?.update && microApp.getStatus() === 'MOUNTED';
208
+ if (canUpdate(microApp)) {
209
+ const props = {
210
+ ...propsFromConfig,
211
+ ...stateForSlave,
212
+ ...propsFromParams,
213
+ setLoading,
214
+ };
215
+
216
+ if (process.env.NODE_ENV === 'development') {
217
+ if (Date.now() - updatingTimestamp.current < 200) {
218
+ console.warn(
219
+ `[@umijs/plugin-qiankun] It seems like microApp ${name} is updating too many times in a short time(200ms), you may need to do some optimization to avoid the unnecessary re-rendering.`,
220
+ );
221
+ }
222
+
223
+ console.info(
224
+ `[@umijs/plugin-qiankun] MicroApp ${name} is updating with props: `,
225
+ props,
226
+ );
227
+ updatingTimestamp.current = Date.now();
228
+ }
229
+
230
+ // 返回 microApp.update 形成链式调用
231
+ // @ts-ignore
232
+ return microApp.update(props);
233
+ }
234
+
235
+ return void 0;
236
+ });
237
+ }
238
+ }
239
+
240
+ return noop;
241
+ }, Object.values({ ...stateForSlave, ...propsFromParams }));
242
+
243
+ // 未配置自定义 loader 且开启了 autoSetLoading 场景下,使用插件默认的 loader,否则使用自定义 loader
244
+ const microAppLoader =
245
+ loader ||
246
+ (propsFromParams.autoSetLoading
247
+ ? (loading) => <MicroAppLoader loading={loading} />
248
+ : null);
249
+
250
+ return Boolean(microAppLoader) || Boolean(microAppErrorBoundary) ? (
251
+ <div style={{ position: 'relative' }} className={wrapperClassName}>
252
+ {Boolean(microAppLoader) && microAppLoader(loading)}
253
+ {Boolean(microAppErrorBoundary) &&
254
+ Boolean(error) &&
255
+ microAppErrorBoundary(error)}
256
+ <div ref={containerRef} className={className} />
257
+ </div>
258
+ ) : (
259
+ <div ref={containerRef} className={className} />
260
+ );
261
+ },
262
+ );
@@ -0,0 +1,43 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable */
3
+
4
+ import React, { useCallback, useEffect, useRef } from 'react';
5
+ import { MicroApp, Props as MicroAppProps } from './MicroApp';
6
+
7
+ export interface Props extends MicroAppProps {
8
+ history?: never;
9
+ }
10
+
11
+ export function MicroAppWithMemoHistory(componentProps: Props) {
12
+ const { url, ...rest } = componentProps;
13
+ const history = useRef();
14
+ // url 的变更不会透传给下游,组件内自己会处理掉,所以这里直接用 ref 来存
15
+ const historyOpts = useRef({
16
+ type: 'memory',
17
+ initialEntries: [url],
18
+ initialIndex: 1,
19
+ });
20
+ const historyInitHandler = useCallback((h) => (history.current = h), []);
21
+
22
+ useEffect(() => {
23
+ // push history for slave app when url property changed
24
+ // the initial url will be ignored because the history has not been initialized
25
+ if (history.current && url) {
26
+ history.current.push(url);
27
+ }
28
+ }, [url]);
29
+
30
+ useEffect(() => {
31
+ // reset the history when name changed
32
+ historyOpts.current.initialEntries = [url];
33
+ historyOpts.current.initialIndex = 1;
34
+ }, [componentProps.name]);
35
+
36
+ return (
37
+ <MicroApp
38
+ {...rest}
39
+ history={historyOpts.current}
40
+ onHistoryInit={historyInitHandler}
41
+ />
42
+ );
43
+ }
@@ -0,0 +1,133 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable */
3
+ /**
4
+ * @author Kuitos
5
+ * @since 2019-06-20
6
+ */
7
+
8
+ import { ReactComponentElement } from 'react';
9
+ import type { IRouteProps } from 'umi';
10
+
11
+ export const defaultMountContainerId = 'root-subapp';
12
+
13
+ // @formatter:off
14
+ export const noop = () => {};
15
+ // @formatter:on
16
+
17
+ export function toArray<T>(source: T | T[]): T[] {
18
+ return Array.isArray(source) ? source : [source];
19
+ }
20
+
21
+ function testPathWithStaticPrefix(pathPrefix: string, realPath: string) {
22
+ if (pathPrefix.endsWith('/')) {
23
+ return realPath.startsWith(pathPrefix);
24
+ }
25
+
26
+ const pathRegex = new RegExp(`^${pathPrefix}([/?])+.*$`, 'g');
27
+ const normalizedPath = `${realPath}/`;
28
+ return pathRegex.test(normalizedPath);
29
+ }
30
+
31
+ // function testPathWithDynamicRoute(dynamicRoute: string, realPath: string) {
32
+ // // FIXME 这个是旧的使用方式才会调到的 api,先临时这么苟一下消除报错,引导用户去迁移吧
33
+ // const pathToRegexp = require('path-to-regexp');
34
+ // return pathToRegexp(dynamicRoute, { strict: true, end: false }).test(
35
+ // realPath,
36
+ // );
37
+ // }
38
+ //
39
+ // export function testPathWithPrefix(pathPrefix: string, realPath: string) {
40
+ // return (
41
+ // testPathWithStaticPrefix(pathPrefix, realPath) ||
42
+ // testPathWithDynamicRoute(pathPrefix, realPath)
43
+ // );
44
+ // }
45
+
46
+ export function patchMicroAppRoute(
47
+ route: any,
48
+ getMicroAppRouteComponent: (opts: {
49
+ appName: string;
50
+ base: string;
51
+ masterHistoryType: string;
52
+ routeProps?: any;
53
+ }) => string | ReactComponentElement<any>,
54
+ masterOptions: {
55
+ base: string;
56
+ masterHistoryType: string;
57
+ routeBindingAlias: string;
58
+ },
59
+ ) {
60
+ const { base, masterHistoryType, routeBindingAlias } = masterOptions;
61
+ // 当配置了 routeBindingAlias 时,优先从 routeBindingAlias 里取配置,但同时也兼容使用了默认的 microApp 方式
62
+ const microAppName = route[routeBindingAlias] || route.microApp;
63
+ const microAppProps =
64
+ route[`${routeBindingAlias}Props`] || route.microAppProps || {};
65
+ if (microAppName) {
66
+ if (route.routes?.length) {
67
+ const childrenRouteHasComponent = route.routes.some(
68
+ (r: any) => r.component,
69
+ );
70
+ if (childrenRouteHasComponent) {
71
+ throw new Error(
72
+ `[@umijs/plugin-qiankun]: You can not attach micro app ${microAppName} to route ${route.path} whose children has own component!`,
73
+ );
74
+ }
75
+ }
76
+
77
+ route.exact = false;
78
+
79
+ const { settings = {}, ...componentProps } = microAppProps;
80
+ const routeProps = {
81
+ // 兼容以前的 settings 配置
82
+ settings: route.settings || settings || {},
83
+ ...componentProps,
84
+ };
85
+ const opts = {
86
+ appName: microAppName,
87
+ base,
88
+ masterHistoryType,
89
+ routeProps,
90
+ };
91
+ route.component = getMicroAppRouteComponent(opts);
92
+ }
93
+ }
94
+
95
+ const recursiveSearch = (
96
+ routes: IRouteProps[],
97
+ path: string,
98
+ ): IRouteProps | null => {
99
+ for (let i = 0; i < routes.length; i++) {
100
+ if (routes[i].path === path) {
101
+ return routes[i];
102
+ }
103
+ if (routes[i].routes && routes[i].routes?.length) {
104
+ const found = recursiveSearch(routes[i].routes || [], path);
105
+ if (found) {
106
+ return found;
107
+ }
108
+ }
109
+ }
110
+ return null;
111
+ };
112
+
113
+ export function insertRoute(routes: IRouteProps[], microAppRoute: IRouteProps) {
114
+ const found = recursiveSearch(routes, microAppRoute.insert);
115
+ if (found) {
116
+ if (
117
+ !microAppRoute.path ||
118
+ !found.path ||
119
+ !microAppRoute.path.startsWith(found.path)
120
+ ) {
121
+ throw new Error(
122
+ `[plugin-qiankun]: path "${microAppRoute.path}" need to starts with "${found.path}"`,
123
+ );
124
+ }
125
+ found.exact = false;
126
+ found.routes = found.routes || [];
127
+ found.routes.push(microAppRoute);
128
+ } else {
129
+ throw new Error(
130
+ `[plugin-qiankun]: path "${microAppRoute.insert}" not found`,
131
+ );
132
+ }
133
+ }
@@ -0,0 +1,7 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable */
3
+
4
+ export const defaultMasterRootId = 'root-master';
5
+ export const defaultHistoryType = 'browser';
6
+ export const qiankunStateForSlaveModelNamespace = '@@qiankunStateForSlave';
7
+ export const qiankunStateFromMasterModelNamespace = '@@qiankunStateFromMaster';
@@ -0,0 +1,45 @@
1
+ import React from 'react';
2
+ import { MicroApp } from './MicroApp';
3
+ {{#runtimeHistory}}
4
+ import { getCreateHistoryOptions } from 'umi';
5
+ {{/runtimeHistory}}
6
+ import { useLocation } from 'umi';
7
+
8
+ export function getMicroAppRouteComponent(opts: {
9
+ appName: string;
10
+ base: string;
11
+ masterHistoryType: string;
12
+ routeProps?: any;
13
+ }) {
14
+ const { base, masterHistoryType, appName, routeProps } = opts;
15
+ const RouteComponent = ({ match }: any) => {
16
+ const url = useLocation().pathname;
17
+
18
+ // 默认取静态配置的 base
19
+ let umiConfigBase = base === '/' ? '' : base;
20
+
21
+ {{#runtimeHistory}}
22
+ // 存在 getCreateHistoryOptions 说明当前应用开启了 runtimeHistory,此时取运行时的 history 配置的 basename
23
+ const { basename = '/' } = getCreateHistoryOptions();
24
+ umiConfigBase = basename === '/' ? '' : basename;
25
+ {{/runtimeHistory}}
26
+
27
+ let runtimeMatchedBase =
28
+ umiConfigBase + (url.endsWith('/') ? url.substr(0, url.length - 1) : url);
29
+
30
+ {{#dynamicRoot}}
31
+ // @see https://github.com/umijs/umi/blob/master/packages/preset-built-in/src/plugins/commands/htmlUtils.ts#L102
32
+ runtimeMatchedBase = window.routerBase || location.pathname.split('/').slice(0, -(path.split('/').length - 1)).concat('').join('/');
33
+ {{/dynamicRoot}}
34
+
35
+ const componentProps = {
36
+ name: appName,
37
+ base: runtimeMatchedBase,
38
+ history: masterHistoryType,
39
+ ...routeProps,
40
+ };
41
+ return <MicroApp {...componentProps} />;
42
+ };
43
+
44
+ return RouteComponent;
45
+ }
@@ -0,0 +1,130 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable */
3
+
4
+ import { getPluginManager } from '@@/core/plugin';
5
+ import { prefetchApps } from 'qiankun';
6
+ import { ApplyPluginsType } from 'umi';
7
+ import { insertRoute, noop, patchMicroAppRoute } from './common';
8
+ import { getMicroAppRouteComponent } from './getMicroAppRouteComponent';
9
+ import { getMasterOptions, setMasterOptions } from './masterOptions';
10
+ import { MasterOptions, MicroAppRoute } from './types';
11
+
12
+ let microAppRuntimeRoutes: MicroAppRoute[];
13
+
14
+ async function getMasterRuntime() {
15
+ const config = await getPluginManager().applyPlugins({
16
+ key: 'qiankun',
17
+ type: ApplyPluginsType.modify,
18
+ initialValue: {},
19
+ async: true,
20
+ });
21
+ const { master } = config;
22
+ return master || config;
23
+ }
24
+
25
+ // modify route with "microApp" attribute to use real component
26
+ function patchMicroAppRouteComponent(routes: any[]) {
27
+ const insertRoutes = microAppRuntimeRoutes.filter((r) => r.insert);
28
+ // 先处理 insert 配置
29
+ insertRoutes.forEach((route) => {
30
+ insertRoute(routes, route);
31
+ });
32
+
33
+ const getRootRoutes = (routes: any[]) => {
34
+ const rootRoute = routes.find((route) => route.path === '/');
35
+ if (rootRoute) {
36
+ // 如果根路由是叶子节点,则直接返回其父节点
37
+ if (!rootRoute.routes) {
38
+ return routes;
39
+ }
40
+ return getRootRoutes(rootRoute.routes);
41
+ }
42
+ return routes;
43
+ };
44
+
45
+ const rootRoutes = getRootRoutes(routes);
46
+ if (rootRoutes) {
47
+ const { routeBindingAlias, base, masterHistoryType } =
48
+ getMasterOptions() as MasterOptions;
49
+ microAppRuntimeRoutes.reverse().forEach((microAppRoute) => {
50
+ const patchRoute = (route: any) => {
51
+ patchMicroAppRoute(route, getMicroAppRouteComponent, {
52
+ base,
53
+ masterHistoryType,
54
+ routeBindingAlias,
55
+ });
56
+ if (route.routes?.length) {
57
+ route.routes.forEach(patchRoute);
58
+ }
59
+ };
60
+
61
+ patchRoute(microAppRoute);
62
+ !microAppRoute.insert && rootRoutes.unshift(microAppRoute);
63
+ });
64
+ }
65
+ }
66
+
67
+ export async function render(oldRender: typeof noop) {
68
+ const runtimeOptions = await getMasterRuntime();
69
+ let masterOptions: MasterOptions = {
70
+ ...getMasterOptions(),
71
+ ...runtimeOptions,
72
+ };
73
+
74
+ const masterApps = masterOptions.apps || [];
75
+ const credentialsApps = masterApps.filter((app) => app.credentials);
76
+ if (credentialsApps.length) {
77
+ const defaultFetch = masterOptions.fetch || window.fetch;
78
+ const fetchWithCredentials = (url: string, init?: RequestInit) => {
79
+ // 如果当前 url 为 credentials 应用的 entry,则为其加上 cors 相关配置
80
+ if (credentialsApps.some((app) => app.entry === url)) {
81
+ return defaultFetch(url, {
82
+ ...init,
83
+ mode: 'cors',
84
+ credentials: 'include',
85
+ });
86
+ }
87
+ return defaultFetch(url, init);
88
+ };
89
+ // 设置新的 fetch
90
+ masterOptions = { ...masterOptions, fetch: fetchWithCredentials };
91
+ }
92
+
93
+ // 更新 master options
94
+ setMasterOptions(masterOptions);
95
+
96
+ const { apps = [], routes, ...options } = masterOptions;
97
+ microAppRuntimeRoutes = routes;
98
+
99
+ // 主应用相关的配置注册完毕后即可开启渲染
100
+ oldRender();
101
+
102
+ // 未使用 base 配置的可以认为是路由关联或者使用标签装载的应用
103
+ const loadableApps = apps.filter((app) => !app.base);
104
+ if (loadableApps.length) {
105
+ const { prefetch, ...importEntryOpts } = options;
106
+ if (prefetch === 'all') {
107
+ prefetchApps(loadableApps, importEntryOpts);
108
+ } else if (Array.isArray(prefetch)) {
109
+ const specialPrefetchApps = loadableApps.filter(
110
+ (app) => prefetch.indexOf(app.name) !== -1,
111
+ );
112
+ prefetchApps(specialPrefetchApps, importEntryOpts);
113
+ }
114
+ }
115
+
116
+ // 使用了 base 配置的应用为可注册应用
117
+ // 不再支持
118
+ const registrableApps = apps.filter((app) => app.base);
119
+ if (registrableApps.length) {
120
+ console.error(
121
+ '[plugins/qiankun] 检测到还在使用旧版配置,该配置已移除,请尽快升级到最新配置方式以获得更好的开发体验,详见 https://umijs.org/plugins/plugin-qiankun#%E5%8D%87%E7%BA%A7%E6%8C%87%E5%8D%97',
122
+ );
123
+ }
124
+ }
125
+
126
+ export function patchRoutes({ routes }: { routes: any[] }) {
127
+ if (microAppRuntimeRoutes) {
128
+ patchMicroAppRouteComponent(routes);
129
+ }
130
+ }
@@ -0,0 +1,44 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable */
3
+ import { FrameworkConfiguration, FrameworkLifeCycles } from 'qiankun';
4
+
5
+ type BaseIConfig = any;
6
+
7
+ export type HistoryType = 'browser' | 'hash';
8
+ export type App = {
9
+ name: string;
10
+ entry: string | { scripts: string[]; styles: string[] };
11
+ base?: string | string[];
12
+ history?: HistoryType;
13
+ // 取 entry 时是否需要开启跨域 credentials
14
+ credentials?: boolean;
15
+ props?: any;
16
+ } & Pick<BaseIConfig, 'mountElementId'>;
17
+
18
+ export type MicroAppRoute = {
19
+ path: string;
20
+ microApp: string;
21
+ } & Record<string, any>;
22
+
23
+ export type MasterOptions = {
24
+ enable?: boolean;
25
+ apps?: App[];
26
+ routes?: MicroAppRoute[];
27
+ lifeCycles?: FrameworkLifeCycles<object>;
28
+ masterHistoryType?: HistoryType;
29
+ base?: string;
30
+ // 关联路由标记的别名,默认 microApp
31
+ routeBindingAlias?: string;
32
+ // 导出的组件别名,默认 MicroApp
33
+ exportComponentAlias?: string;
34
+ } & FrameworkConfiguration;
35
+
36
+ export type SlaveOptions = {
37
+ enable?: boolean;
38
+ devSourceMap?: boolean;
39
+ keepOriginalRoutes?: boolean | string;
40
+ shouldNotModifyRuntimePublicPath?: boolean;
41
+ shouldNotModifyDefaultBase?: boolean;
42
+ // library name 是否增加 -[name] 应对多 chunk 场景
43
+ shouldNotAddLibraryChunkName?: boolean;
44
+ };
@@ -0,0 +1,15 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable */
3
+ __USE_MODEL__;
4
+ import React from 'react';
5
+
6
+ const noop = () => {};
7
+
8
+ const connectMaster = <T extends object>(Component: React.ComponentType<T>) => {
9
+ return (props: T, ...rest: any[]) => {
10
+ const masterProps = (useModel || noop)('@@qiankunStateFromMaster') || {};
11
+ return <Component {...props} {...rest} {...masterProps} />;
12
+ };
13
+ };
14
+
15
+ export { connectMaster };