@umijs/plugins 4.0.0-canary.20220429.2 → 4.0.0-canary.20220506.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 (53) hide show
  1. package/dist/access.d.ts +3 -0
  2. package/dist/access.js +139 -0
  3. package/dist/analytics.d.ts +3 -0
  4. package/dist/analytics.js +67 -0
  5. package/dist/antd.d.ts +3 -0
  6. package/dist/antd.js +137 -0
  7. package/dist/dva.d.ts +6 -0
  8. package/dist/dva.js +198 -0
  9. package/dist/icons.d.ts +3 -0
  10. package/dist/icons.js +5 -0
  11. package/dist/initial-state.d.ts +3 -0
  12. package/dist/initial-state.js +116 -0
  13. package/dist/layout.d.ts +3 -0
  14. package/dist/layout.js +538 -0
  15. package/dist/locale.d.ts +4 -0
  16. package/dist/locale.js +199 -0
  17. package/dist/model.d.ts +3 -0
  18. package/dist/model.js +101 -0
  19. package/dist/moment2dayjs.d.ts +3 -0
  20. package/dist/moment2dayjs.js +96 -0
  21. package/dist/qiankun/constants.d.ts +5 -0
  22. package/dist/qiankun/constants.js +8 -0
  23. package/dist/qiankun/master.d.ts +6 -0
  24. package/dist/qiankun/master.js +134 -0
  25. package/dist/qiankun/slave.d.ts +3 -0
  26. package/dist/qiankun/slave.js +158 -0
  27. package/dist/qiankun.d.ts +3 -0
  28. package/dist/qiankun.js +19 -0
  29. package/dist/request.d.ts +3 -0
  30. package/dist/request.js +311 -0
  31. package/dist/tailwindcss.d.ts +3 -0
  32. package/dist/tailwindcss.js +40 -0
  33. package/dist/unocss.d.ts +3 -0
  34. package/dist/unocss.js +39 -0
  35. package/dist/utils/astUtils.d.ts +3 -0
  36. package/dist/utils/astUtils.js +38 -0
  37. package/dist/utils/localeUtils.d.ts +33 -0
  38. package/dist/utils/localeUtils.js +126 -0
  39. package/dist/utils/modelUtils.d.ts +39 -0
  40. package/dist/utils/modelUtils.js +231 -0
  41. package/dist/utils/resolveProjectDep.d.ts +5 -0
  42. package/dist/utils/resolveProjectDep.js +15 -0
  43. package/dist/utils/withTmpPath.d.ts +6 -0
  44. package/dist/utils/withTmpPath.js +11 -0
  45. package/libs/qiankun/master/MicroApp.tsx +7 -0
  46. package/libs/qiankun/master/common.ts +13 -10
  47. package/libs/qiankun/master/getMicroAppRouteComponent.tsx.tpl +5 -5
  48. package/libs/qiankun/master/masterRuntimePlugin.tsx +5 -5
  49. package/libs/qiankun/slave/connectMaster.tsx +0 -1
  50. package/libs/qiankun/slave/lifecycles.ts +6 -8
  51. package/libs/qiankun/slave/qiankunModel.ts +0 -1
  52. package/libs/qiankun/slave/slaveRuntimePlugin.ts +9 -15
  53. package/package.json +3 -3
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isNeedPolyfill = exports.exactLocalePaths = exports.getLocaleList = exports.getAntdLocale = exports.getMomentLocale = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const plugin_utils_1 = require("umi/plugin-utils");
7
+ /**
8
+ * 获取 moment 包的 locale 名称
9
+ * @param lang 语言
10
+ * @param country 国家
11
+ * @param resolveKey 用来resolve的key,moment 或者 dayjs,为了使 dayjs 可以替换 moment
12
+ */
13
+ const getMomentLocale = (lang, country, resolveKey) => {
14
+ var _a, _b;
15
+ const momentLocation = require
16
+ .resolve(`${resolveKey}/locale/zh-cn`)
17
+ .replace(/zh\-cn\.js$/, '');
18
+ if ((0, fs_1.existsSync)((0, path_1.join)(momentLocation, `${lang}-${(_a = country === null || country === void 0 ? void 0 : country.toLocaleLowerCase) === null || _a === void 0 ? void 0 : _a.call(country)}.js`))) {
19
+ const momentLocale = `${lang}-${(_b = country === null || country === void 0 ? void 0 : country.toLocaleLowerCase) === null || _b === void 0 ? void 0 : _b.call(country)}`;
20
+ return {
21
+ momentLocale,
22
+ };
23
+ }
24
+ if ((0, fs_1.existsSync)((0, path_1.join)(momentLocation, `${lang}.js`))) {
25
+ return {
26
+ momentLocale: lang,
27
+ };
28
+ }
29
+ return { momentLocale: '' };
30
+ };
31
+ exports.getMomentLocale = getMomentLocale;
32
+ const getAntdLocale = (lang, country) => `${lang}_${(country || lang).toLocaleUpperCase()}`;
33
+ exports.getAntdLocale = getAntdLocale;
34
+ /**
35
+ * 有些情况下可能项目包含的locale和antd的不匹配
36
+ * 这个方法用于检测
37
+ * @param localePath
38
+ * @returns
39
+ */
40
+ const modulesHasLocale = (localePath) => {
41
+ try {
42
+ require.resolve(localePath);
43
+ return true;
44
+ }
45
+ catch (error) {
46
+ return false;
47
+ }
48
+ };
49
+ const getLocaleList = async (opts) => {
50
+ const { localeFolder, separator = '-', absSrcPath = '', absPagesPath = '', addAntdLocales, resolveKey = 'moment', } = opts;
51
+ const localeFileMath = new RegExp(`^([a-z]{2})${separator}?([A-Z]{2})?\.(js|json|ts)$`);
52
+ const localeFiles = plugin_utils_1.glob
53
+ .sync('*.{ts,js,json}', {
54
+ cwd: (0, plugin_utils_1.winPath)((0, path_1.join)(absSrcPath, localeFolder)),
55
+ })
56
+ .map((name) => (0, plugin_utils_1.winPath)((0, path_1.join)(absSrcPath, localeFolder, name)))
57
+ .concat(plugin_utils_1.glob
58
+ .sync(`**/${localeFolder}/*.{ts,js,json}`, {
59
+ cwd: absPagesPath,
60
+ })
61
+ .map((name) => (0, plugin_utils_1.winPath)((0, path_1.join)(absPagesPath, name))))
62
+ .filter((p) => localeFileMath.test((0, path_1.basename)(p)) && (0, fs_1.existsSync)(p))
63
+ .map((fullName) => {
64
+ var _a, _b;
65
+ const fileName = (0, path_1.basename)(fullName);
66
+ const fileInfo = (_b = (_a = localeFileMath
67
+ .exec(fileName)) === null || _a === void 0 ? void 0 : _a.slice(1, 3)) === null || _b === void 0 ? void 0 : _b.filter(Boolean);
68
+ return {
69
+ name: (fileInfo || []).join(separator),
70
+ path: fullName,
71
+ };
72
+ });
73
+ const groups = plugin_utils_1.lodash.groupBy(localeFiles, 'name');
74
+ const promises = Object.keys(groups).map(async (name) => {
75
+ const [lang, country = ''] = name.split(separator);
76
+ const { momentLocale } = (0, exports.getMomentLocale)(lang, country, resolveKey);
77
+ const antdLocale = plugin_utils_1.lodash
78
+ .uniq(await addAntdLocales({ lang, country }))
79
+ .filter((localePath) => modulesHasLocale(localePath));
80
+ return {
81
+ lang,
82
+ name,
83
+ // react-intl Function.supportedLocalesOf
84
+ // Uncaught RangeError: Incorrect locale information provided
85
+ locale: name.split(separator).join('-'),
86
+ country,
87
+ antdLocale,
88
+ paths: groups[name].map((item) => (0, plugin_utils_1.winPath)(item.path)),
89
+ momentLocale,
90
+ };
91
+ });
92
+ return Promise.all(promises);
93
+ };
94
+ exports.getLocaleList = getLocaleList;
95
+ const exactLocalePaths = (data) => {
96
+ return plugin_utils_1.lodash.flatten(data.map((item) => item.paths));
97
+ };
98
+ exports.exactLocalePaths = exactLocalePaths;
99
+ function isNeedPolyfill(targets = {}) {
100
+ // data come from https://caniuse.com/#search=intl
101
+ // you can find all browsers in https://github.com/browserslist/browserslist#browsers
102
+ const polyfillTargets = {
103
+ ie: 10,
104
+ firefox: 28,
105
+ chrome: 23,
106
+ safari: 9.1,
107
+ opera: 12.1,
108
+ ios: 9.3,
109
+ ios_saf: 9.3,
110
+ operamini: Infinity,
111
+ op_mini: Infinity,
112
+ android: 4.3,
113
+ blackberry: Infinity,
114
+ operamobile: 12.1,
115
+ op_mob: 12.1,
116
+ explorermobil: 10,
117
+ ie_mob: 10,
118
+ ucandroid: Infinity,
119
+ };
120
+ return (Object.keys(targets).find((key) => {
121
+ const lowKey = key.toLocaleLowerCase();
122
+ // @ts-ignore
123
+ return polyfillTargets[lowKey] && polyfillTargets[lowKey] >= targets[key];
124
+ }) !== undefined);
125
+ }
126
+ exports.isNeedPolyfill = isNeedPolyfill;
@@ -0,0 +1,39 @@
1
+ import * as t from '@umijs/bundler-utils/compiled/babel/types';
2
+ import { IApi } from 'umi';
3
+ interface IOpts {
4
+ contentTest?: (content: string) => Boolean;
5
+ astTest?: (opts: {
6
+ node: t.Node;
7
+ content: string;
8
+ }) => Boolean;
9
+ }
10
+ export declare class Model {
11
+ file: string;
12
+ namespace: string;
13
+ id: string;
14
+ exportName: string;
15
+ deps: string[];
16
+ constructor(file: string, sort: {} | undefined, id: number);
17
+ findDeps(sort: object): string[];
18
+ }
19
+ export declare class ModelUtils {
20
+ api: IApi;
21
+ opts: IOpts;
22
+ count: number;
23
+ constructor(api: IApi | null, opts: IOpts);
24
+ getAllModels(opts: {
25
+ sort?: object;
26
+ extraModels: string[];
27
+ }): Model[];
28
+ getSortedNamespaces(models: Model[]): string[];
29
+ getModels(opts: {
30
+ base: string;
31
+ pattern?: string;
32
+ }): string[];
33
+ isModelValid(opts: {
34
+ content: string;
35
+ file: string;
36
+ }): boolean;
37
+ static getModelsContent(models: Model[]): string;
38
+ }
39
+ export {};
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.ModelUtils = exports.Model = void 0;
30
+ const parser = __importStar(require("@umijs/bundler-utils/compiled/babel/parser"));
31
+ const traverse_1 = __importDefault(require("@umijs/bundler-utils/compiled/babel/traverse"));
32
+ const t = __importStar(require("@umijs/bundler-utils/compiled/babel/types"));
33
+ const esbuild_1 = require("@umijs/bundler-utils/compiled/esbuild");
34
+ const fs_1 = require("fs");
35
+ const path_1 = require("path");
36
+ const plugin_utils_1 = require("umi/plugin-utils");
37
+ const astUtils_1 = require("./astUtils");
38
+ class Model {
39
+ constructor(file, sort, id) {
40
+ let namespace;
41
+ let exportName;
42
+ const [_file, meta] = file.split('#');
43
+ if (meta) {
44
+ const metaObj = JSON.parse(meta);
45
+ namespace = metaObj.namespace;
46
+ exportName = metaObj.exportName;
47
+ }
48
+ this.file = _file;
49
+ this.id = `model_${id}`;
50
+ this.namespace = namespace || (0, path_1.basename)(file, (0, path_1.extname)(file));
51
+ this.exportName = exportName || 'default';
52
+ this.deps = sort ? this.findDeps(sort) : [];
53
+ }
54
+ findDeps(sort) {
55
+ const content = (0, fs_1.readFileSync)(this.file, 'utf-8');
56
+ // transform with esbuild first
57
+ // to reduce unexpected ast problem
58
+ const loader = (0, path_1.extname)(this.file).slice(1);
59
+ const result = (0, esbuild_1.transformSync)(content, {
60
+ loader,
61
+ sourcemap: false,
62
+ minify: false,
63
+ });
64
+ // transform with babel
65
+ const deps = new Set();
66
+ const ast = parser.parse(result.code, {
67
+ sourceType: 'module',
68
+ sourceFilename: this.file,
69
+ plugins: [],
70
+ });
71
+ // TODO: use sort
72
+ sort;
73
+ (0, traverse_1.default)(ast, {
74
+ CallExpression: (path) => {
75
+ if (t.isIdentifier(path.node.callee, { name: 'useModel' }) &&
76
+ t.isStringLiteral(path.node.arguments[0])) {
77
+ deps.add(path.node.arguments[0].value);
78
+ }
79
+ },
80
+ });
81
+ return [...deps];
82
+ }
83
+ }
84
+ exports.Model = Model;
85
+ class ModelUtils {
86
+ constructor(api, opts) {
87
+ this.opts = {};
88
+ this.count = 1;
89
+ this.api = api;
90
+ this.opts = opts;
91
+ }
92
+ getAllModels(opts) {
93
+ // reset count
94
+ this.count = 1;
95
+ const models = [
96
+ ...this.getModels({
97
+ base: (0, path_1.join)(this.api.paths.absSrcPath, 'models'),
98
+ pattern: '**/*.{ts,tsx,js,jsx}',
99
+ }),
100
+ ...this.getModels({
101
+ base: (0, path_1.join)(this.api.paths.absPagesPath),
102
+ pattern: '**/models/**/*.{ts,tsx,js,jsx}',
103
+ }),
104
+ ...this.getModels({
105
+ base: (0, path_1.join)(this.api.paths.absPagesPath),
106
+ pattern: '**/model.{ts,tsx,js,jsx}',
107
+ }),
108
+ ...opts.extraModels,
109
+ ].map((file) => {
110
+ return new Model(file, opts.sort, this.count++);
111
+ });
112
+ // check duplicate
113
+ const namespaces = models.map((model) => model.namespace);
114
+ if (new Set(namespaces).size !== namespaces.length) {
115
+ throw new Error(`Duplicate namespace in models: ${namespaces.join(', ')}`);
116
+ }
117
+ // sort models by deps
118
+ if (opts.sort) {
119
+ const namespaces = this.getSortedNamespaces(models);
120
+ models.sort((a, b) => namespaces.indexOf(a.namespace) - namespaces.indexOf(b.namespace));
121
+ }
122
+ return models;
123
+ }
124
+ getSortedNamespaces(models) {
125
+ let final = [];
126
+ models.forEach((model, index) => {
127
+ const { deps, namespace } = model;
128
+ if (deps && deps.length) {
129
+ const itemGroup = [...deps, namespace];
130
+ const cannotUse = [namespace];
131
+ for (let i = 0; i <= index; i += 1) {
132
+ if (models[i].deps.filter((v) => cannotUse.includes(v)).length) {
133
+ if (!cannotUse.includes(models[i].namespace)) {
134
+ cannotUse.push(models[i].namespace);
135
+ i = -1;
136
+ }
137
+ }
138
+ }
139
+ const errorList = deps.filter((v) => cannotUse.includes(v));
140
+ if (errorList.length) {
141
+ throw Error(`Circular dependencies: ${namespace} can't use ${errorList.join(', ')}`);
142
+ }
143
+ const intersection = final.filter((v) => itemGroup.includes(v));
144
+ if (intersection.length) {
145
+ // first intersection
146
+ const finalIndex = final.indexOf(intersection[0]);
147
+ // replace with groupItem
148
+ final = final
149
+ .slice(0, finalIndex)
150
+ .concat(itemGroup)
151
+ .concat(final.slice(finalIndex + 1));
152
+ }
153
+ else {
154
+ final.push(...itemGroup);
155
+ }
156
+ }
157
+ if (!final.includes(namespace)) {
158
+ // first occurrence append to the end
159
+ final.push(namespace);
160
+ }
161
+ });
162
+ return [...new Set(final)];
163
+ }
164
+ getModels(opts) {
165
+ return plugin_utils_1.glob
166
+ .sync(opts.pattern || '**/*.{ts,js}', {
167
+ cwd: opts.base,
168
+ absolute: true,
169
+ })
170
+ .map(plugin_utils_1.winPath)
171
+ .filter((file) => {
172
+ if (/\.d.ts$/.test(file))
173
+ return false;
174
+ if (/\.(test|e2e|spec).([jt])sx?$/.test(file))
175
+ return false;
176
+ const content = (0, fs_1.readFileSync)(file, 'utf-8');
177
+ return this.isModelValid({ content, file });
178
+ });
179
+ }
180
+ isModelValid(opts) {
181
+ const { file, content } = opts;
182
+ if (this.opts.contentTest && this.opts.contentTest(content)) {
183
+ return true;
184
+ }
185
+ // transform with esbuild first
186
+ // to reduce unexpected ast problem
187
+ const loader = (0, path_1.extname)(file).slice(1);
188
+ const result = (0, esbuild_1.transformSync)(content, {
189
+ loader,
190
+ sourcemap: false,
191
+ minify: false,
192
+ });
193
+ // transform with babel
194
+ let ret = false;
195
+ const ast = parser.parse(result.code, {
196
+ sourceType: 'module',
197
+ sourceFilename: file,
198
+ plugins: [],
199
+ });
200
+ (0, traverse_1.default)(ast, {
201
+ ExportDefaultDeclaration: (path) => {
202
+ let node = path.node.declaration;
203
+ node = (0, astUtils_1.getIdentifierDeclaration)(node, path);
204
+ if (this.opts.astTest && this.opts.astTest({ node, content })) {
205
+ ret = true;
206
+ }
207
+ },
208
+ });
209
+ return ret;
210
+ }
211
+ static getModelsContent(models) {
212
+ const imports = [];
213
+ const modelProps = [];
214
+ models.forEach((model) => {
215
+ if (model.exportName !== 'default') {
216
+ imports.push(`import { ${model.exportName} as ${model.id} } from '${model.file}';`);
217
+ }
218
+ else {
219
+ imports.push(`import ${model.id} from '${model.file}';`);
220
+ }
221
+ modelProps.push(`${model.id}: { namespace: '${model.namespace}', model: ${model.id} },`);
222
+ });
223
+ return `
224
+ ${imports.join('\n')}
225
+
226
+ export const models = {
227
+ ${modelProps.join('\n')}
228
+ }`;
229
+ }
230
+ }
231
+ exports.ModelUtils = ModelUtils;
@@ -0,0 +1,5 @@
1
+ export declare function resolveProjectDep(opts: {
2
+ pkg: any;
3
+ cwd: string;
4
+ dep: string;
5
+ }): string | undefined;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveProjectDep = void 0;
4
+ const path_1 = require("path");
5
+ const plugin_utils_1 = require("umi/plugin-utils");
6
+ function resolveProjectDep(opts) {
7
+ var _a, _b;
8
+ if (((_a = opts.pkg.dependencies) === null || _a === void 0 ? void 0 : _a[opts.dep]) ||
9
+ ((_b = opts.pkg.devDependencies) === null || _b === void 0 ? void 0 : _b[opts.dep])) {
10
+ return (0, path_1.dirname)(plugin_utils_1.resolve.sync(`${opts.dep}/package.json`, {
11
+ basedir: opts.cwd,
12
+ }));
13
+ }
14
+ }
15
+ exports.resolveProjectDep = resolveProjectDep;
@@ -0,0 +1,6 @@
1
+ import { IApi } from 'umi';
2
+ export declare function withTmpPath(opts: {
3
+ api: IApi;
4
+ path: string;
5
+ noPluginDir?: boolean;
6
+ }): string;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withTmpPath = void 0;
4
+ const path_1 = require("path");
5
+ const plugin_utils_1 = require("umi/plugin-utils");
6
+ function withTmpPath(opts) {
7
+ return (0, plugin_utils_1.winPath)((0, path_1.join)(opts.api.paths.absTmpPath, opts.api.plugin.key && !opts.noPluginDir
8
+ ? `plugin-${opts.api.plugin.key}`
9
+ : '', opts.path));
10
+ }
11
+ exports.withTmpPath = withTmpPath;
@@ -139,6 +139,13 @@ export const MicroApp = forwardRef(
139
139
  setComponentError(null);
140
140
  setLoading(true);
141
141
  const configuration = {
142
+ fetch(url) {
143
+ return window.fetch(url, {
144
+ headers: {
145
+ accept: 'text/html',
146
+ },
147
+ });
148
+ },
142
149
  globalContext: window,
143
150
  ...globalSettings,
144
151
  ...settingsFromProps,
@@ -5,7 +5,7 @@
5
5
  * @since 2019-06-20
6
6
  */
7
7
 
8
- import { ReactComponentElement } from 'react';
8
+ import React, { ReactComponentElement } from 'react';
9
9
  import type { IRouteProps } from 'umi';
10
10
 
11
11
  export const defaultMountContainerId = 'root-subapp';
@@ -63,9 +63,9 @@ export function patchMicroAppRoute(
63
63
  const microAppProps =
64
64
  route[`${routeBindingAlias}Props`] || route.microAppProps || {};
65
65
  if (microAppName) {
66
- if (route.routes?.length) {
67
- const childrenRouteHasComponent = route.routes.some(
68
- (r: any) => r.component,
66
+ if (route.children?.length) {
67
+ const childrenRouteHasComponent = route.children.some(
68
+ (r: any) => r.element,
69
69
  );
70
70
  if (childrenRouteHasComponent) {
71
71
  throw new Error(
@@ -74,7 +74,10 @@ export function patchMicroAppRoute(
74
74
  }
75
75
  }
76
76
 
77
- route.exact = false;
77
+ // 自动追加通配符,匹配子应用的路由
78
+ if (!route.path.endsWith('/*')) {
79
+ route.path = route.path.replace(/\/?$/, '/*');
80
+ }
78
81
 
79
82
  const { settings = {}, ...componentProps } = microAppProps;
80
83
  const routeProps = {
@@ -88,7 +91,7 @@ export function patchMicroAppRoute(
88
91
  masterHistoryType,
89
92
  routeProps,
90
93
  };
91
- route.component = getMicroAppRouteComponent(opts);
94
+ route.element = React.createElement(getMicroAppRouteComponent(opts), null);
92
95
  }
93
96
  }
94
97
 
@@ -100,8 +103,8 @@ const recursiveSearch = (
100
103
  if (routes[i].path === path) {
101
104
  return routes[i];
102
105
  }
103
- if (routes[i].routes && routes[i].routes?.length) {
104
- const found = recursiveSearch(routes[i].routes || [], path);
106
+ if (routes[i].chidlren && routes[i].chidlren?.length) {
107
+ const found = recursiveSearch(routes[i].chidlren || [], path);
105
108
  if (found) {
106
109
  return found;
107
110
  }
@@ -123,8 +126,8 @@ export function insertRoute(routes: IRouteProps[], microAppRoute: IRouteProps) {
123
126
  );
124
127
  }
125
128
  found.exact = false;
126
- found.routes = found.routes || [];
127
- found.routes.push(microAppRoute);
129
+ found.chidlren = found.chidlren || [];
130
+ found.chidlren.push(microAppRoute);
128
131
  } else {
129
132
  throw new Error(
130
133
  `[plugin-qiankun]: path "${microAppRoute.insert}" not found`,
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { MicroApp } from './MicroApp';
3
- import { useLocation } from 'umi';
3
+ import { useRouteData } from 'umi';
4
4
 
5
5
  export function getMicroAppRouteComponent(opts: {
6
6
  appName: string;
@@ -9,14 +9,14 @@ export function getMicroAppRouteComponent(opts: {
9
9
  routeProps?: any;
10
10
  }) {
11
11
  const { base, masterHistoryType, appName, routeProps } = opts;
12
- const RouteComponent = ({ match }: any) => {
13
- const url = useLocation().pathname;
12
+ const RouteComponent = () => {
13
+ const { route } = useRouteData();
14
14
 
15
15
  // 默认取静态配置的 base
16
16
  let umiConfigBase = base === '/' ? '' : base;
17
17
 
18
- let runtimeMatchedBase =
19
- umiConfigBase + (url.endsWith('/') ? url.substr(0, url.length - 1) : url);
18
+ // 拼接子应用挂载路由
19
+ let runtimeMatchedBase = umiConfigBase + route.path.replace('/*', '');
20
20
 
21
21
  {{#dynamicRoot}}
22
22
  // @see https://github.com/umijs/umi/blob/master/packages/preset-built-in/src/plugins/commands/htmlUtils.ts#L102
@@ -34,10 +34,10 @@ function patchMicroAppRouteComponent(routes: any[]) {
34
34
  const rootRoute = routes.find((route) => route.path === '/');
35
35
  if (rootRoute) {
36
36
  // 如果根路由是叶子节点,则直接返回其父节点
37
- if (!rootRoute.routes) {
37
+ if (!rootRoute.chidlren) {
38
38
  return routes;
39
39
  }
40
- return getRootRoutes(rootRoute.routes);
40
+ return getRootRoutes(rootRoute.chidlren);
41
41
  }
42
42
  return routes;
43
43
  };
@@ -53,8 +53,8 @@ function patchMicroAppRouteComponent(routes: any[]) {
53
53
  masterHistoryType,
54
54
  routeBindingAlias,
55
55
  });
56
- if (route.routes?.length) {
57
- route.routes.forEach(patchRoute);
56
+ if (route.chidlren?.length) {
57
+ route.chidlren.forEach(patchRoute);
58
58
  }
59
59
  };
60
60
 
@@ -123,7 +123,7 @@ export async function render(oldRender: typeof noop) {
123
123
  }
124
124
  }
125
125
 
126
- export function patchRoutes({ routes }: { routes: any[] }) {
126
+ export function patchClientRoutes({ routes }: { routes: any[] }) {
127
127
  if (microAppRuntimeRoutes) {
128
128
  patchMicroAppRouteComponent(routes);
129
129
  }
@@ -1,5 +1,4 @@
1
1
  // @ts-nocheck
2
- /* eslint-disable */
3
2
  __USE_MODEL__;
4
3
  import React from 'react';
5
4
 
@@ -1,5 +1,4 @@
1
1
  // @ts-nocheck
2
- /* eslint-disable */
3
2
  import { getPluginManager } from '@@/core/plugin';
4
3
  import ReactDOM from 'react-dom';
5
4
  import { ApplyPluginsType } from 'umi';
@@ -22,7 +21,7 @@ let render = noop;
22
21
  let hasMountedAtLeastOnce = false;
23
22
 
24
23
  export default () => defer.promise;
25
- export const clientRenderOptsStack: any[] = [];
24
+ export const contextOptsStack: any[] = [];
26
25
 
27
26
  // function normalizeHistory(
28
27
  // history?: 'string' | Record<string, any>,
@@ -79,10 +78,7 @@ export function genMount(mountElementId: string) {
79
78
  // 默认开启
80
79
  // 如果需要手动控制 loading,通过主应用配置 props.autoSetLoading false 可以关闭
81
80
  callback: () => {
82
- if (
83
- props?.autoSetLoading &&
84
- typeof props?.setLoading === 'function'
85
- ) {
81
+ if (props.autoSetLoading && typeof props.setLoading === 'function') {
86
82
  props.setLoading(false);
87
83
  }
88
84
 
@@ -94,9 +90,11 @@ export function genMount(mountElementId: string) {
94
90
  // 支持通过 props 注入 container 来限定子应用 mountElementId 的查找范围
95
91
  // 避免多个子应用出现在同一主应用时出现 mount 冲突
96
92
  rootElement:
97
- props?.container?.querySelector(`#${mountElementId}`) ||
93
+ props.container?.querySelector(`#${mountElementId}`) ||
98
94
  mountElementId,
99
95
 
96
+ basename: props.base,
97
+
100
98
  // 当存在同一个 umi 子应用在同一个页面被多实例渲染的场景时(比如一个页面里,同时展示了这个子应用的多个路由页面)
101
99
  // mount 钩子会被调用多次,但是具体什么时候对应的实例开始 render 则是不定的,即它调用 applyPlugins('modifyClientRenderOpts') 的时机是不确定的
102
100
  // 为了保证每次 applyPlugins('modifyClientRenderOpts') 调用是生成正确的 history,我们需要这里通过闭包上下文维持 mount 调用时的一些配置信息
@@ -111,7 +109,7 @@ export function genMount(mountElementId: string) {
111
109
  // },
112
110
  };
113
111
 
114
- clientRenderOptsStack.push(clientRenderOpts);
112
+ contextOptsStack.push(clientRenderOpts);
115
113
  }
116
114
 
117
115
  // 第一次 mount defer 被 resolve 后umi 会自动触发 render,非第一次 mount 则需手动触发
@@ -1,5 +1,4 @@
1
1
  // @ts-nocheck
2
- /* eslint-disable */
3
2
  import { useState } from 'react';
4
3
 
5
4
  let initState: any;
@@ -1,21 +1,15 @@
1
1
  // @ts-nocheck
2
- /* eslint-disable */
3
- import qiankunRender from './lifecycles';
2
+ import qiankunRender, { contextOptsStack } from './lifecycles';
4
3
 
5
4
  export function render(oldRender: any) {
6
5
  return qiankunRender().then(oldRender);
7
6
  }
8
7
 
9
- // export function modifyClientRenderOpts(memo: any) {
10
- // // 每次应用 render 的时候会调 modifyClientRenderOpts,这时尝试从队列中取 render 的配置
11
- // const clientRenderOpts = clientRenderOptsStack.shift();
12
- // if (clientRenderOpts) {
13
- // const history = clientRenderOpts.getHistory();
14
- // delete clientRenderOpts.getHistory;
15
- // clientRenderOpts.history = history;
16
- // }
17
- // return {
18
- // ...memo,
19
- // ...clientRenderOpts,
20
- // };
21
- // }
8
+ export function modifyContextOpts(memo: any) {
9
+ // 每次应用 render 的时候会调 modifyClientRenderOpts,这时尝试从队列中取 render 的配置
10
+ const clientRenderOpts = contextOptsStack.shift();
11
+ return {
12
+ ...memo,
13
+ ...clientRenderOpts,
14
+ };
15
+ }