@umijs/plugins 4.0.0-rc.13 → 4.0.0-rc.16
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/access.js +18 -13
- package/dist/antd.js +21 -6
- package/dist/dva.js +10 -2
- package/dist/initial-state.js +1 -1
- package/dist/layout.js +2 -1
- package/dist/locale.js +32 -34
- package/dist/model.js +16 -35
- package/dist/qiankun/master.js +28 -5
- package/dist/qiankun/slave.js +54 -29
- package/dist/qiankun.js +1 -0
- package/dist/request.js +90 -9
- package/dist/utils/localeUtils.js +5 -14
- package/dist/utils/modelUtils.d.ts +5 -1
- package/dist/utils/modelUtils.js +85 -3
- package/libs/qiankun/master/MicroApp.tsx +7 -0
- package/libs/qiankun/master/common.ts +15 -10
- package/libs/qiankun/master/getMicroAppRouteComponent.tsx.tpl +5 -7
- package/libs/qiankun/master/masterRuntimePlugin.tsx +6 -5
- package/libs/qiankun/slave/connectMaster.tsx +0 -1
- package/libs/qiankun/slave/lifecycles.ts +12 -8
- package/libs/qiankun/slave/qiankunModel.ts +0 -1
- package/libs/qiankun/slave/slaveRuntimePlugin.ts +9 -15
- package/package.json +9 -9
package/dist/access.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
4
|
};
|
|
11
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
7
|
const path_1 = require("path");
|
|
13
8
|
const withTmpPath_1 = require("./utils/withTmpPath");
|
|
14
9
|
exports.default = (api) => {
|
|
@@ -20,19 +15,29 @@ exports.default = (api) => {
|
|
|
20
15
|
},
|
|
21
16
|
enableBy: api.EnableBy.config,
|
|
22
17
|
});
|
|
23
|
-
api.onGenerateFiles(() =>
|
|
18
|
+
api.onGenerateFiles(async () => {
|
|
19
|
+
// allow enable access without access file
|
|
20
|
+
const hasAccessFile = ['js', 'jsx', 'ts', 'tsx'].some((ext) => fs_1.default.existsSync((0, path_1.join)(api.paths.absSrcPath, `access.${ext}`)));
|
|
24
21
|
// runtime.tsx
|
|
25
22
|
api.writeTmpFile({
|
|
26
23
|
path: 'runtime.tsx',
|
|
27
24
|
content: `
|
|
28
|
-
import React from 'react'
|
|
29
|
-
|
|
25
|
+
import React from 'react';${hasAccessFile
|
|
26
|
+
? `
|
|
27
|
+
import accessFactory from '@/access'
|
|
30
28
|
import { useModel } from '@@/plugin-model';
|
|
29
|
+
`
|
|
30
|
+
: ''}
|
|
31
31
|
import { AccessContext } from './context';
|
|
32
32
|
|
|
33
|
-
function Provider(props) {
|
|
33
|
+
function Provider(props) {${hasAccessFile
|
|
34
|
+
? `
|
|
34
35
|
const { initialState } = useModel('@@initialState');
|
|
35
36
|
const access = React.useMemo(() => accessFactory(initialState), [initialState]);
|
|
37
|
+
`
|
|
38
|
+
: `
|
|
39
|
+
const access = {};
|
|
40
|
+
`}
|
|
36
41
|
return (
|
|
37
42
|
<AccessContext.Provider value={access}>
|
|
38
43
|
{ props.children }
|
|
@@ -123,7 +128,7 @@ import React from 'react';
|
|
|
123
128
|
export const AccessContext = React.createContext<any>(null);
|
|
124
129
|
`,
|
|
125
130
|
});
|
|
126
|
-
})
|
|
131
|
+
});
|
|
127
132
|
api.addRuntimePlugin(() => {
|
|
128
133
|
return [(0, withTmpPath_1.withTmpPath)({ api, path: 'runtime.tsx' })];
|
|
129
134
|
});
|
package/dist/antd.js
CHANGED
|
@@ -30,7 +30,12 @@ exports.default = (api) => {
|
|
|
30
30
|
});
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
|
-
enableBy
|
|
33
|
+
enableBy({ userConfig }) {
|
|
34
|
+
// 由于本插件有 api.modifyConfig 的调用,以及 Umi 框架的限制
|
|
35
|
+
// 在其他插件中通过 api.modifyDefaultConfig 设置 antd 并不能让 api.modifyConfig 生效
|
|
36
|
+
// 所以这里通过环境变量来判断是否启用
|
|
37
|
+
return process.env.UMI_PLUGIN_ANTD_ENABLE || userConfig.antd;
|
|
38
|
+
},
|
|
34
39
|
});
|
|
35
40
|
function checkPkgPath() {
|
|
36
41
|
if (!pkgPath) {
|
|
@@ -48,6 +53,12 @@ exports.default = (api) => {
|
|
|
48
53
|
});
|
|
49
54
|
api.modifyConfig((memo) => {
|
|
50
55
|
checkPkgPath();
|
|
56
|
+
const antd = memo.antd || {};
|
|
57
|
+
// defaultConfig 的取值在 config 之后,所以改用环境变量传默认值
|
|
58
|
+
if (process.env.UMI_PLUGIN_ANTD_ENABLE) {
|
|
59
|
+
const { defaultConfig } = JSON.parse(process.env.UMI_PLUGIN_ANTD_ENABLE);
|
|
60
|
+
Object.assign(antd, defaultConfig);
|
|
61
|
+
}
|
|
51
62
|
// antd import
|
|
52
63
|
memo.alias.antd = pkgPath;
|
|
53
64
|
// moment > dayjs
|
|
@@ -57,12 +68,16 @@ exports.default = (api) => {
|
|
|
57
68
|
// dark mode & compact mode
|
|
58
69
|
if (memo.antd.dark || memo.antd.compact) {
|
|
59
70
|
const { getThemeVariables } = require('antd/dist/theme');
|
|
60
|
-
memo.theme =
|
|
71
|
+
memo.theme = {
|
|
72
|
+
...getThemeVariables(memo.antd),
|
|
73
|
+
...memo.theme,
|
|
74
|
+
};
|
|
61
75
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
76
|
+
// antd theme
|
|
77
|
+
memo.theme = {
|
|
78
|
+
'root-entry-name': 'default',
|
|
79
|
+
...memo.theme,
|
|
80
|
+
};
|
|
66
81
|
return memo;
|
|
67
82
|
});
|
|
68
83
|
// babel-plugin-import
|
package/dist/dva.js
CHANGED
|
@@ -25,11 +25,11 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.getAllModels = exports.getModelUtil = void 0;
|
|
27
27
|
const t = __importStar(require("@umijs/bundler-utils/compiled/babel/types"));
|
|
28
|
+
const utils_1 = require("@umijs/utils");
|
|
28
29
|
const path_1 = require("path");
|
|
29
30
|
const plugin_utils_1 = require("umi/plugin-utils");
|
|
30
31
|
const modelUtils_1 = require("./utils/modelUtils");
|
|
31
32
|
const withTmpPath_1 = require("./utils/withTmpPath");
|
|
32
|
-
const utils_1 = require("@umijs/utils");
|
|
33
33
|
exports.default = (api) => {
|
|
34
34
|
const pkgPath = (0, path_1.join)(__dirname, '../libs/dva.ts');
|
|
35
35
|
api.describe({
|
|
@@ -80,15 +80,22 @@ import dvaImmer, { enableES5, enableAllPlugins } from '${(0, utils_1.winPath)(re
|
|
|
80
80
|
`
|
|
81
81
|
: ''}
|
|
82
82
|
import React, { useRef } from 'react';
|
|
83
|
-
import { history } from 'umi';
|
|
83
|
+
import { history, ApplyPluginsType, useAppData } from 'umi';
|
|
84
84
|
import { models } from './models';
|
|
85
85
|
|
|
86
86
|
export function RootContainer(props: any) {
|
|
87
|
+
const { pluginManager } = useAppData();
|
|
87
88
|
const app = useRef<any>();
|
|
89
|
+
const runtimeDva = pluginManager.applyPlugins({
|
|
90
|
+
key: 'dva',
|
|
91
|
+
type: ApplyPluginsType.modify,
|
|
92
|
+
initialValue: {},
|
|
93
|
+
});
|
|
88
94
|
if (!app.current) {
|
|
89
95
|
app.current = create(
|
|
90
96
|
{
|
|
91
97
|
history,
|
|
98
|
+
...(runtimeDva.config || {}),
|
|
92
99
|
},
|
|
93
100
|
{
|
|
94
101
|
initialReducer: {},
|
|
@@ -139,6 +146,7 @@ export { connect, useDispatch, useStore, useSelector } from 'dva';`,
|
|
|
139
146
|
api.addRuntimePlugin(() => {
|
|
140
147
|
return [(0, withTmpPath_1.withTmpPath)({ api, path: 'runtime.tsx' })];
|
|
141
148
|
});
|
|
149
|
+
api.addRuntimePluginKey(() => ['dva']);
|
|
142
150
|
// dva list model
|
|
143
151
|
api.registerCommand({
|
|
144
152
|
name: 'dva',
|
package/dist/initial-state.js
CHANGED
|
@@ -107,7 +107,7 @@ export default () => ({ loading: false, refresh: () => {} })
|
|
|
107
107
|
content: `
|
|
108
108
|
import React from 'react';
|
|
109
109
|
import Provider from './Provider';
|
|
110
|
-
export function
|
|
110
|
+
export function dataflowProvider(container) {
|
|
111
111
|
return <Provider>{ container }</Provider>;
|
|
112
112
|
}
|
|
113
113
|
`,
|
package/dist/layout.js
CHANGED
|
@@ -137,7 +137,8 @@ const { formatMessage } = useIntl();
|
|
|
137
137
|
}
|
|
138
138
|
if (menuItemProps.path && location.pathname !== menuItemProps.path) {
|
|
139
139
|
return (
|
|
140
|
-
|
|
140
|
+
// handle wildcard route path, for example /slave/* from qiankun
|
|
141
|
+
<Link to={menuItemProps.path.replace('/*', '')} target={menuItemProps.target}>
|
|
141
142
|
{defaultDom}
|
|
142
143
|
</Link>
|
|
143
144
|
);
|
package/dist/locale.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.packageNormalize = void 0;
|
|
13
4
|
const fs_1 = require("fs");
|
|
@@ -58,9 +49,9 @@ exports.default = (api) => {
|
|
|
58
49
|
},
|
|
59
50
|
]
|
|
60
51
|
: []);
|
|
61
|
-
const addAntdLocales = (args) =>
|
|
52
|
+
const addAntdLocales = async (args) => {
|
|
62
53
|
var _a;
|
|
63
|
-
return
|
|
54
|
+
return await api.applyPlugins({
|
|
64
55
|
key: 'addAntdLocales',
|
|
65
56
|
type: api.ApplyPluginsType.add,
|
|
66
57
|
initialValue: [
|
|
@@ -68,29 +59,32 @@ exports.default = (api) => {
|
|
|
68
59
|
],
|
|
69
60
|
args,
|
|
70
61
|
});
|
|
71
|
-
}
|
|
72
|
-
const getList = (resolveKey) =>
|
|
73
|
-
var
|
|
62
|
+
};
|
|
63
|
+
const getList = async (resolveKey) => {
|
|
64
|
+
var _a;
|
|
74
65
|
const { paths } = api;
|
|
75
66
|
return (0, localeUtils_1.getLocaleList)({
|
|
76
67
|
localeFolder: 'locales',
|
|
77
|
-
separator: (
|
|
68
|
+
separator: (_a = api.config.locale) === null || _a === void 0 ? void 0 : _a.baseSeparator,
|
|
78
69
|
absSrcPath: paths.absSrcPath,
|
|
79
70
|
absPagesPath: paths.absPagesPath,
|
|
80
71
|
addAntdLocales,
|
|
81
72
|
resolveKey,
|
|
82
73
|
});
|
|
83
|
-
}
|
|
84
|
-
api.onGenerateFiles(() =>
|
|
85
|
-
var
|
|
74
|
+
};
|
|
75
|
+
api.onGenerateFiles(async () => {
|
|
76
|
+
var _a, _b, _c, _d;
|
|
86
77
|
const localeTpl = (0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../libs/locale/locale.tpl'), 'utf-8');
|
|
87
78
|
// moment2dayjs
|
|
88
79
|
const resolveKey = api.config.moment2dayjs ? 'dayjs' : 'moment';
|
|
89
80
|
const momentPkgPath = (0, plugin_utils_1.winPath)((0, path_1.dirname)(require.resolve(`${resolveKey}/package.json`)));
|
|
90
81
|
const EventEmitterPkg = (0, plugin_utils_1.winPath)((0, path_1.dirname)(require.resolve('event-emitter/package')));
|
|
91
|
-
const { baseSeparator, baseNavigator, antd, title, useLocalStorage } =
|
|
92
|
-
|
|
93
|
-
|
|
82
|
+
const { baseSeparator, baseNavigator, antd, title, useLocalStorage } = {
|
|
83
|
+
...defaultConfig,
|
|
84
|
+
...api.config.locale,
|
|
85
|
+
};
|
|
86
|
+
const defaultLocale = ((_a = api.config.locale) === null || _a === void 0 ? void 0 : _a.default) || `zh${baseSeparator}CN`;
|
|
87
|
+
const localeList = await getList(resolveKey);
|
|
94
88
|
const momentLocales = localeList
|
|
95
89
|
.map(({ momentLocale }) => momentLocale)
|
|
96
90
|
.filter((locale) => locale);
|
|
@@ -100,7 +94,7 @@ exports.default = (api) => {
|
|
|
100
94
|
let MomentLocales = momentLocales;
|
|
101
95
|
let DefaultMomentLocale = '';
|
|
102
96
|
// set moment default accounding to locale.default
|
|
103
|
-
if (!MomentLocales.length && ((
|
|
97
|
+
if (!MomentLocales.length && ((_b = api.config.locale) === null || _b === void 0 ? void 0 : _b.default)) {
|
|
104
98
|
const [lang, country = ''] = defaultLocale.split(baseSeparator);
|
|
105
99
|
const { momentLocale } = (0, localeUtils_1.getMomentLocale)(lang, country, resolveKey);
|
|
106
100
|
if (momentLocale) {
|
|
@@ -110,9 +104,9 @@ exports.default = (api) => {
|
|
|
110
104
|
}
|
|
111
105
|
let DefaultAntdLocales = [];
|
|
112
106
|
// set antd default locale
|
|
113
|
-
if (!antdLocales.length && ((
|
|
107
|
+
if (!antdLocales.length && ((_c = api.config.locale) === null || _c === void 0 ? void 0 : _c.antd)) {
|
|
114
108
|
const [lang, country = ''] = defaultLocale.split(baseSeparator);
|
|
115
|
-
DefaultAntdLocales = plugin_utils_1.lodash.uniq(
|
|
109
|
+
DefaultAntdLocales = plugin_utils_1.lodash.uniq(await addAntdLocales({
|
|
116
110
|
lang,
|
|
117
111
|
country,
|
|
118
112
|
}));
|
|
@@ -148,16 +142,20 @@ exports.default = (api) => {
|
|
|
148
142
|
UseLocalStorage: !!useLocalStorage,
|
|
149
143
|
LocaleDir: localeDirName,
|
|
150
144
|
ExistLocaleDir: (0, fs_1.existsSync)(localeDirPath),
|
|
151
|
-
LocaleList: localeList.map((locale) => (
|
|
145
|
+
LocaleList: localeList.map((locale) => ({
|
|
146
|
+
...locale,
|
|
147
|
+
antdLocale: locale.antdLocale.map((antdLocale, index) => ({
|
|
152
148
|
locale: antdLocale,
|
|
153
149
|
index: index,
|
|
154
|
-
})),
|
|
150
|
+
})),
|
|
151
|
+
paths: locale.paths.map((path, index) => ({
|
|
155
152
|
path,
|
|
156
153
|
index,
|
|
157
|
-
}))
|
|
154
|
+
})),
|
|
155
|
+
})),
|
|
158
156
|
Antd: !!antd,
|
|
159
157
|
DefaultLocale: JSON.stringify(defaultLocale),
|
|
160
|
-
warningPkgPath: (0, plugin_utils_1.winPath)(require.resolve('warning/package')),
|
|
158
|
+
warningPkgPath: (0, plugin_utils_1.winPath)((0, path_1.dirname)(require.resolve('warning/package'))),
|
|
161
159
|
reactIntlPkgPath,
|
|
162
160
|
}),
|
|
163
161
|
});
|
|
@@ -177,25 +175,25 @@ exports.default = (api) => {
|
|
|
177
175
|
Antd: !!antd,
|
|
178
176
|
LocaleList: localeList,
|
|
179
177
|
ShowSelectLang: localeList.length > 1 && !!antd,
|
|
180
|
-
antdFiles: ((
|
|
178
|
+
antdFiles: ((_d = api.config) === null || _d === void 0 ? void 0 : _d.ssr) ? 'lib' : 'es',
|
|
181
179
|
}),
|
|
182
180
|
});
|
|
183
181
|
// index.ts
|
|
184
182
|
api.writeTmpFile({
|
|
185
183
|
path: 'index.ts',
|
|
186
184
|
content: `
|
|
187
|
-
export { setLocale, getLocale, useIntl, formatMessage, FormattedMessage } from './localeExports.ts';
|
|
185
|
+
export { setLocale, getLocale, useIntl, injectIntl, formatMessage, FormattedMessage } from './localeExports.ts';
|
|
188
186
|
export { SelectLang } from './SelectLang.tsx';
|
|
189
187
|
`,
|
|
190
188
|
});
|
|
191
|
-
})
|
|
189
|
+
});
|
|
192
190
|
// Runtime Plugin
|
|
193
191
|
api.addRuntimePlugin(() => [(0, withTmpPath_1.withTmpPath)({ api, path: 'runtime.tsx' })]);
|
|
194
192
|
api.addRuntimePluginKey(() => ['locale']);
|
|
195
193
|
// watch locale files
|
|
196
|
-
api.addTmpGenerateWatcherPaths(() =>
|
|
194
|
+
api.addTmpGenerateWatcherPaths(async () => {
|
|
197
195
|
const resolveKey = api.config.moment2dayjs ? 'dayjs' : 'moment';
|
|
198
|
-
const localeList =
|
|
196
|
+
const localeList = await getList(resolveKey);
|
|
199
197
|
return (0, localeUtils_1.exactLocalePaths)(localeList);
|
|
200
|
-
})
|
|
198
|
+
});
|
|
201
199
|
};
|
package/dist/model.js
CHANGED
|
@@ -22,15 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
26
|
const t = __importStar(require("@umijs/bundler-utils/compiled/babel/types"));
|
|
36
27
|
const fs_1 = require("fs");
|
|
@@ -49,17 +40,8 @@ exports.default = (api) => {
|
|
|
49
40
|
},
|
|
50
41
|
enableBy: api.EnableBy.config,
|
|
51
42
|
});
|
|
52
|
-
api.
|
|
53
|
-
const models =
|
|
54
|
-
memo.pluginModel = {
|
|
55
|
-
models,
|
|
56
|
-
};
|
|
57
|
-
return memo;
|
|
58
|
-
}));
|
|
59
|
-
api.onGenerateFiles((args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
60
|
-
const models = args.isFirstTime
|
|
61
|
-
? api.appData.pluginModel.models
|
|
62
|
-
: yield getAllModels(api);
|
|
43
|
+
api.onGenerateFiles(async () => {
|
|
44
|
+
const models = await getAllModels(api);
|
|
63
45
|
// model.ts
|
|
64
46
|
api.writeTmpFile({
|
|
65
47
|
path: 'model.ts',
|
|
@@ -94,7 +76,7 @@ export function dataflowProvider(container, opts) {
|
|
|
94
76
|
}
|
|
95
77
|
`,
|
|
96
78
|
});
|
|
97
|
-
})
|
|
79
|
+
});
|
|
98
80
|
api.addTmpGenerateWatcherPaths(() => {
|
|
99
81
|
return [(0, path_1.join)(api.paths.absSrcPath, 'models')];
|
|
100
82
|
});
|
|
@@ -102,19 +84,18 @@ export function dataflowProvider(container, opts) {
|
|
|
102
84
|
return [(0, withTmpPath_1.withTmpPath)({ api, path: 'runtime.tsx' })];
|
|
103
85
|
});
|
|
104
86
|
};
|
|
105
|
-
function getAllModels(api) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
});
|
|
87
|
+
async function getAllModels(api) {
|
|
88
|
+
const extraModels = await api.applyPlugins({
|
|
89
|
+
key: 'addExtraModels',
|
|
90
|
+
type: api.ApplyPluginsType.add,
|
|
91
|
+
initialValue: [],
|
|
92
|
+
});
|
|
93
|
+
return new modelUtils_1.ModelUtils(api, {
|
|
94
|
+
astTest({ node }) {
|
|
95
|
+
return t.isArrowFunctionExpression(node) || t.isFunctionDeclaration(node);
|
|
96
|
+
},
|
|
97
|
+
}).getAllModels({
|
|
98
|
+
sort: {},
|
|
99
|
+
extraModels: [...extraModels, ...(api.config.model.extraModels || [])],
|
|
119
100
|
});
|
|
120
101
|
}
|
package/dist/qiankun/master.js
CHANGED
|
@@ -23,7 +23,17 @@ exports.default = (api) => {
|
|
|
23
23
|
api.addRuntimePlugin(() => {
|
|
24
24
|
return [(0, withTmpPath_1.withTmpPath)({ api, path: 'masterRuntimePlugin.tsx' })];
|
|
25
25
|
});
|
|
26
|
-
api.modifyDefaultConfig((config) => (
|
|
26
|
+
api.modifyDefaultConfig((config) => ({
|
|
27
|
+
...config,
|
|
28
|
+
mountElementId: constants_1.defaultMasterRootId,
|
|
29
|
+
qiankun: {
|
|
30
|
+
...config.qiankun,
|
|
31
|
+
master: {
|
|
32
|
+
...JSON.parse(process.env.INITIAL_QIANKUN_MASTER_OPTIONS || '{}'),
|
|
33
|
+
...(config.qiankun || {}).master,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
}));
|
|
27
37
|
// TODO: modify routes
|
|
28
38
|
api.modifyRoutes((memo) => {
|
|
29
39
|
Object.keys(memo).forEach((id) => {
|
|
@@ -38,7 +48,7 @@ exports.default = (api) => {
|
|
|
38
48
|
const normalizedRouteProps = JSON.stringify(routeProps).replace(/"/g, "'");
|
|
39
49
|
route.file = `(async () => {
|
|
40
50
|
const { getMicroAppRouteComponent } = await import('@@/plugin-qiankun-master/getMicroAppRouteComponent');
|
|
41
|
-
return getMicroAppRouteComponent({ appName: '${appName}', base: '${base}', masterHistoryType: '${masterHistoryType}', routeProps: ${normalizedRouteProps} })
|
|
51
|
+
return getMicroAppRouteComponent({ appName: '${appName}', base: '${base}', routePath: '${route.path}', masterHistoryType: '${masterHistoryType}', routeProps: ${normalizedRouteProps} })
|
|
42
52
|
})()`;
|
|
43
53
|
}
|
|
44
54
|
});
|
|
@@ -65,7 +75,11 @@ exports.default = (api) => {
|
|
|
65
75
|
api.writeTmpFile({
|
|
66
76
|
path: 'masterOptions.ts',
|
|
67
77
|
content: `
|
|
68
|
-
let options = ${JSON.stringify(
|
|
78
|
+
let options = ${JSON.stringify({
|
|
79
|
+
masterHistoryType: ((_a = api.config.history) === null || _a === void 0 ? void 0 : _a.type) || constants_1.defaultHistoryType,
|
|
80
|
+
base: api.config.base || '/',
|
|
81
|
+
...api.config.qiankun.master,
|
|
82
|
+
})};
|
|
69
83
|
export const getMasterOptions = () => options;
|
|
70
84
|
export const setMasterOptions = (newOpts) => options = ({ ...options, ...newOpts });
|
|
71
85
|
`,
|
|
@@ -99,16 +113,25 @@ export const setMasterOptions = (newOpts) => options = ({ ...options, ...newOpts
|
|
|
99
113
|
});
|
|
100
114
|
}
|
|
101
115
|
else {
|
|
116
|
+
let content = getFileContent(file);
|
|
117
|
+
if (!api.config.qiankun.externalQiankun) {
|
|
118
|
+
content = content.replace(/from 'qiankun'/g, `from '${(0, plugin_utils_1.winPath)((0, path_1.dirname)(require.resolve('qiankun/package')))}'`);
|
|
119
|
+
}
|
|
102
120
|
api.writeTmpFile({
|
|
103
121
|
path: file.replace(/\.tpl$/, ''),
|
|
104
|
-
content:
|
|
122
|
+
content: content
|
|
105
123
|
.replace('__USE_MODEL__', api.isPluginEnable('model')
|
|
106
124
|
? `import { useModel } from '@@/plugin-model'`
|
|
107
125
|
: `const useModel = null;`)
|
|
108
|
-
.replace(/from 'qiankun'/g, `from '${(0, plugin_utils_1.winPath)((0, path_1.dirname)(require.resolve('qiankun/package')))}'`)
|
|
109
126
|
.replace(/from 'lodash\//g, `from '${(0, plugin_utils_1.winPath)((0, path_1.dirname)(require.resolve('lodash/package')))}/`),
|
|
110
127
|
});
|
|
111
128
|
}
|
|
112
129
|
});
|
|
130
|
+
api.writeTmpFile({
|
|
131
|
+
path: 'index.ts',
|
|
132
|
+
content: `
|
|
133
|
+
export { MicroApp } from './MicroApp';
|
|
134
|
+
`,
|
|
135
|
+
});
|
|
113
136
|
});
|
|
114
137
|
};
|
package/dist/qiankun/slave.js
CHANGED
|
@@ -30,16 +30,29 @@ exports.default = (api) => {
|
|
|
30
30
|
key: 'addExtraModels',
|
|
31
31
|
fn() {
|
|
32
32
|
return [
|
|
33
|
-
|
|
33
|
+
(0, withTmpPath_1.withTmpPath)({
|
|
34
|
+
api,
|
|
35
|
+
path: `qiankunModel.ts#{"namespace":"${constants_1.qiankunStateFromMasterModelNamespace}"}`,
|
|
36
|
+
}),
|
|
34
37
|
];
|
|
35
38
|
},
|
|
36
39
|
});
|
|
37
40
|
api.modifyDefaultConfig((memo) => {
|
|
38
41
|
var _a, _b, _c, _d;
|
|
39
|
-
const initialSlaveOptions =
|
|
40
|
-
|
|
42
|
+
const initialSlaveOptions = {
|
|
43
|
+
devSourceMap: true,
|
|
44
|
+
...JSON.parse(process.env.INITIAL_QIANKUN_SLAVE_OPTIONS || '{}'),
|
|
45
|
+
...(memo.qiankun || {}).slave,
|
|
46
|
+
};
|
|
47
|
+
const modifiedDefaultConfig = {
|
|
48
|
+
...memo,
|
|
41
49
|
// 默认开启 runtimePublicPath,避免出现 dynamic import 场景子应用资源地址出问题
|
|
42
|
-
runtimePublicPath: true,
|
|
50
|
+
runtimePublicPath: true,
|
|
51
|
+
qiankun: {
|
|
52
|
+
...memo.qiankun,
|
|
53
|
+
slave: initialSlaveOptions,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
43
56
|
const shouldNotModifyDefaultBase = (_c = (_b = (_a = api.userConfig.qiankun) === null || _a === void 0 ? void 0 : _a.slave) === null || _b === void 0 ? void 0 : _b.shouldNotModifyDefaultBase) !== null && _c !== void 0 ? _c : initialSlaveOptions.shouldNotModifyDefaultBase;
|
|
44
57
|
const historyType = ((_d = api.userConfig.history) === null || _d === void 0 ? void 0 : _d.type) || 'browser';
|
|
45
58
|
if (!shouldNotModifyDefaultBase && historyType !== 'hash') {
|
|
@@ -52,8 +65,11 @@ exports.default = (api) => {
|
|
|
52
65
|
var _a, _b;
|
|
53
66
|
// mfsu 场景默认给子应用增加 mfName 配置,从而避免冲突
|
|
54
67
|
if (config.mfsu !== false) {
|
|
55
|
-
config.mfsu =
|
|
56
|
-
|
|
68
|
+
config.mfsu = {
|
|
69
|
+
...config.mfsu,
|
|
70
|
+
mfName: ((_a = config.mfsu) === null || _a === void 0 ? void 0 : _a.mfName) ||
|
|
71
|
+
`mf_${(_b = api.pkg.name) === null || _b === void 0 ? void 0 : _b.replace(/^@/, '').replace(/\W/g, '_')}`,
|
|
72
|
+
};
|
|
57
73
|
}
|
|
58
74
|
return config;
|
|
59
75
|
});
|
|
@@ -110,30 +126,39 @@ if (!window.__POWERED_BY_QIANKUN__) {
|
|
|
110
126
|
function getFileContent(file) {
|
|
111
127
|
return (0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../../libs/qiankun/slave', file), 'utf-8');
|
|
112
128
|
}
|
|
113
|
-
api.onGenerateFiles(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
129
|
+
api.onGenerateFiles({
|
|
130
|
+
fn() {
|
|
131
|
+
// api.writeTmpFile({
|
|
132
|
+
// path: 'slaveOptions.ts',
|
|
133
|
+
// content: `
|
|
134
|
+
// let options = ${JSON.stringify((api.config.qiankun || {}).slave || {})};
|
|
135
|
+
// export const getSlaveOptions = () => options;
|
|
136
|
+
// export const setSlaveOptions = (newOpts) => options = ({ ...options, ...newOpts });
|
|
137
|
+
// `,
|
|
138
|
+
// });
|
|
139
|
+
[
|
|
140
|
+
'qiankunModel.ts',
|
|
141
|
+
'connectMaster.tsx',
|
|
142
|
+
'slaveRuntimePlugin.ts',
|
|
143
|
+
'lifecycles.ts',
|
|
144
|
+
].forEach((file) => {
|
|
145
|
+
api.writeTmpFile({
|
|
146
|
+
path: file.replace(/\.tpl$/, ''),
|
|
147
|
+
content: getFileContent(file)
|
|
148
|
+
.replace('__USE_MODEL__', api.isPluginEnable('model')
|
|
149
|
+
? `import { useModel } from '@@/plugin-model'`
|
|
150
|
+
: `const useModel = null;`)
|
|
151
|
+
.replace(/from 'qiankun'/g, `from '${(0, plugin_utils_1.winPath)((0, path_1.dirname)(require.resolve('qiankun/package')))}'`)
|
|
152
|
+
.replace(/from 'lodash\//g, `from '${(0, plugin_utils_1.winPath)((0, path_1.dirname)(require.resolve('lodash/package')))}/`),
|
|
153
|
+
});
|
|
154
|
+
});
|
|
128
155
|
api.writeTmpFile({
|
|
129
|
-
path:
|
|
130
|
-
content:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
: `const useModel = null;`)
|
|
134
|
-
.replace(/from 'qiankun'/g, `from '${(0, plugin_utils_1.winPath)((0, path_1.dirname)(require.resolve('qiankun/package')))}'`)
|
|
135
|
-
.replace(/from 'lodash\//g, `from '${(0, plugin_utils_1.winPath)((0, path_1.dirname)(require.resolve('lodash/package')))}/`),
|
|
156
|
+
path: 'index.ts',
|
|
157
|
+
content: `
|
|
158
|
+
export { connectMaster } from './connectMaster';
|
|
159
|
+
`,
|
|
136
160
|
});
|
|
137
|
-
}
|
|
161
|
+
},
|
|
162
|
+
before: 'model',
|
|
138
163
|
});
|
|
139
164
|
};
|
package/dist/qiankun.js
CHANGED
package/dist/request.js
CHANGED
|
@@ -102,7 +102,10 @@ function useRequest(service: any, options: any = {}) {
|
|
|
102
102
|
|
|
103
103
|
// request 方法 opts 参数的接口
|
|
104
104
|
interface IRequestOptions extends AxiosRequestConfig {
|
|
105
|
-
skipErrorHandler?: boolean
|
|
105
|
+
skipErrorHandler?: boolean;
|
|
106
|
+
requestInterceptors?: IRequestInterceptorTuple[];
|
|
107
|
+
responseInterceptors?: IResponseInterceptorTuple[];
|
|
108
|
+
[key: string]: any;
|
|
106
109
|
}
|
|
107
110
|
|
|
108
111
|
interface IRequestOptionsWithResponse extends IRequestOptions {
|
|
@@ -123,12 +126,21 @@ interface IRequest{
|
|
|
123
126
|
interface IErrorHandler {
|
|
124
127
|
(error: RequestError, opts: IRequestOptions): void;
|
|
125
128
|
}
|
|
129
|
+
type IRequestInterceptorAxios = (config: RequestOptions) => RequestOptions;
|
|
130
|
+
type IRequestInterceptorUmiRequest = (url: string, config : RequestOptions) => { url: string, options: RequestOptions };
|
|
131
|
+
type IRequestInterceptor = IRequestInterceptorAxios;
|
|
132
|
+
type IErrorInterceptor = (error: Error) => Promise<Error>;
|
|
133
|
+
type IResponseInterceptor = <T = any>(response : AxiosResponse<T>) => AxiosResponse<T> ;
|
|
134
|
+
type IRequestInterceptorTuple = [IRequestInterceptor , IErrorInterceptor] | [ IRequestInterceptor ] | IRequestInterceptor
|
|
135
|
+
type IResponseInterceptorTuple = [IResponseInterceptor, IErrorInterceptor] | [IResponseInterceptor] | IResponseInterceptor
|
|
126
136
|
|
|
127
137
|
export interface RequestConfig extends AxiosRequestConfig {
|
|
128
138
|
errorConfig?: {
|
|
129
139
|
errorHandler?: IErrorHandler;
|
|
130
140
|
errorThrower?: <T = any>( res: T ) => void
|
|
131
141
|
};
|
|
142
|
+
requestInterceptors?: IRequestInterceptorTuple[];
|
|
143
|
+
responseInterceptors?: IResponseInterceptorTuple[];
|
|
132
144
|
}
|
|
133
145
|
|
|
134
146
|
let requestInstance: AxiosInstance;
|
|
@@ -142,15 +154,44 @@ const getConfig = (): RequestConfig => {
|
|
|
142
154
|
});
|
|
143
155
|
return config;
|
|
144
156
|
};
|
|
157
|
+
|
|
145
158
|
const getRequestInstance = (): AxiosInstance => {
|
|
146
159
|
if (requestInstance) return requestInstance;
|
|
147
160
|
const config = getConfig();
|
|
148
161
|
requestInstance = axios.create(config);
|
|
149
162
|
|
|
163
|
+
config?.requestInterceptors?.forEach((interceptor) => {
|
|
164
|
+
if(interceptor instanceof Array){
|
|
165
|
+
requestInstance.interceptors.request.use((config) => {
|
|
166
|
+
const { url } = config;
|
|
167
|
+
if(interceptor[0].length === 2){
|
|
168
|
+
const { url: newUrl, options } = interceptor[0](url, config);
|
|
169
|
+
return { ...options, url: newUrl };
|
|
170
|
+
}
|
|
171
|
+
return interceptor[0](config);
|
|
172
|
+
}, interceptor[1]);
|
|
173
|
+
} else {
|
|
174
|
+
requestInstance.interceptors.request.use((config) => {
|
|
175
|
+
const { url } = config;
|
|
176
|
+
if(interceptor.length === 2){
|
|
177
|
+
const { url: newUrl, options } = interceptor(url, config);
|
|
178
|
+
return { ...options, url: newUrl };
|
|
179
|
+
}
|
|
180
|
+
return interceptor(config);
|
|
181
|
+
})
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
config?.responseInterceptors?.forEach((interceptor) => {
|
|
186
|
+
interceptor instanceof Array ?
|
|
187
|
+
requestInstance.interceptors.response.use(interceptor[0], interceptor[1]):
|
|
188
|
+
requestInstance.interceptors.response.use(interceptor);
|
|
189
|
+
});
|
|
190
|
+
|
|
150
191
|
// 当响应的数据 success 是 false 的时候,抛出 error 以供 errorHandler 处理。
|
|
151
|
-
requestInstance.interceptors.response.use((response)=>{
|
|
192
|
+
requestInstance.interceptors.response.use((response) => {
|
|
152
193
|
const { data } = response;
|
|
153
|
-
if(config?.errorConfig?.errorThrower){
|
|
194
|
+
if(data?.success === false && config?.errorConfig?.errorThrower){
|
|
154
195
|
config.errorConfig.errorThrower(data);
|
|
155
196
|
}
|
|
156
197
|
return response;
|
|
@@ -158,17 +199,55 @@ const getRequestInstance = (): AxiosInstance => {
|
|
|
158
199
|
return requestInstance;
|
|
159
200
|
};
|
|
160
201
|
|
|
161
|
-
const request: IRequest = (url: string, opts: any = { method: 'GET' }) => {
|
|
202
|
+
const request: IRequest = (url: string, opts: any = { method: 'GET' }) => {
|
|
162
203
|
const requestInstance = getRequestInstance();
|
|
163
204
|
const config = getConfig();
|
|
164
|
-
const { getResponse = false } = opts;
|
|
205
|
+
const { getResponse = false, requestInterceptors, responseInterceptors } = opts;
|
|
206
|
+
const requestInterceptorsToEject = requestInterceptors?.map((interceptor) => {
|
|
207
|
+
if(interceptor instanceof Array){
|
|
208
|
+
return requestInstance.interceptors.request.use((config) => {
|
|
209
|
+
const { url } = config;
|
|
210
|
+
if(interceptor[0].length === 2){
|
|
211
|
+
const { url: newUrl, options } = interceptor[0](url, config);
|
|
212
|
+
return { ...options, url: newUrl };
|
|
213
|
+
}
|
|
214
|
+
return interceptor[0](config);
|
|
215
|
+
}, interceptor[1]);
|
|
216
|
+
} else {
|
|
217
|
+
return requestInstance.interceptors.request.use((config) => {
|
|
218
|
+
const { url } = config;
|
|
219
|
+
if(interceptor.length === 2){
|
|
220
|
+
const { url: newUrl, options } = interceptor(url, config);
|
|
221
|
+
return { ...options, url: newUrl };
|
|
222
|
+
}
|
|
223
|
+
return interceptor(config);
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
const responseInterceptorsToEject = responseInterceptors?.map((interceptor) => {
|
|
228
|
+
return interceptor instanceof Array ?
|
|
229
|
+
requestInstance.interceptors.response.use(interceptor[0], interceptor[1]):
|
|
230
|
+
requestInstance.interceptors.response.use(interceptor);
|
|
231
|
+
});
|
|
165
232
|
return new Promise((resolve, reject)=>{
|
|
166
233
|
requestInstance
|
|
167
234
|
.request({...opts, url})
|
|
168
235
|
.then((res)=>{
|
|
236
|
+
requestInterceptorsToEject?.forEach((interceptor) => {
|
|
237
|
+
requestInstance.interceptors.request.eject(interceptor);
|
|
238
|
+
});
|
|
239
|
+
responseInterceptorsToEject?.forEach((interceptor) => {
|
|
240
|
+
requestInstance.interceptors.response.eject(interceptor);
|
|
241
|
+
});
|
|
169
242
|
resolve(getResponse ? res : res.data);
|
|
170
243
|
})
|
|
171
244
|
.catch((error)=>{
|
|
245
|
+
requestInterceptorsToEject?.forEach((interceptor) => {
|
|
246
|
+
requestInstance.interceptors.request.eject(interceptor);
|
|
247
|
+
});
|
|
248
|
+
responseInterceptorsToEject?.forEach((interceptor) => {
|
|
249
|
+
requestInstance.interceptors.response.eject(interceptor);
|
|
250
|
+
});
|
|
172
251
|
try {
|
|
173
252
|
const handler =
|
|
174
253
|
config.errorConfig?.errorHandler;
|
|
@@ -212,6 +291,12 @@ export type {
|
|
|
212
291
|
formatResult,
|
|
213
292
|
}),
|
|
214
293
|
});
|
|
294
|
+
api.writeTmpFile({
|
|
295
|
+
path: 'types.d.ts',
|
|
296
|
+
content: `
|
|
297
|
+
export type { RequestConfig } from './request';
|
|
298
|
+
`,
|
|
299
|
+
});
|
|
215
300
|
api.writeTmpFile({
|
|
216
301
|
path: 'index.ts',
|
|
217
302
|
content: `
|
|
@@ -220,10 +305,6 @@ export {
|
|
|
220
305
|
UseRequestProvider,
|
|
221
306
|
request,
|
|
222
307
|
} from './request';
|
|
223
|
-
|
|
224
|
-
export type {
|
|
225
|
-
RequestConfig
|
|
226
|
-
} from './request';
|
|
227
308
|
`,
|
|
228
309
|
});
|
|
229
310
|
});
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.isNeedPolyfill = exports.exactLocalePaths = exports.getLocaleList = exports.getAntdLocale = exports.getMomentLocale = void 0;
|
|
13
4
|
const fs_1 = require("fs");
|
|
@@ -55,7 +46,7 @@ const modulesHasLocale = (localePath) => {
|
|
|
55
46
|
return false;
|
|
56
47
|
}
|
|
57
48
|
};
|
|
58
|
-
const getLocaleList = (opts) =>
|
|
49
|
+
const getLocaleList = async (opts) => {
|
|
59
50
|
const { localeFolder, separator = '-', absSrcPath = '', absPagesPath = '', addAntdLocales, resolveKey = 'moment', } = opts;
|
|
60
51
|
const localeFileMath = new RegExp(`^([a-z]{2})${separator}?([A-Z]{2})?\.(js|json|ts)$`);
|
|
61
52
|
const localeFiles = plugin_utils_1.glob
|
|
@@ -80,11 +71,11 @@ const getLocaleList = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
80
71
|
};
|
|
81
72
|
});
|
|
82
73
|
const groups = plugin_utils_1.lodash.groupBy(localeFiles, 'name');
|
|
83
|
-
const promises = Object.keys(groups).map((name) =>
|
|
74
|
+
const promises = Object.keys(groups).map(async (name) => {
|
|
84
75
|
const [lang, country = ''] = name.split(separator);
|
|
85
76
|
const { momentLocale } = (0, exports.getMomentLocale)(lang, country, resolveKey);
|
|
86
77
|
const antdLocale = plugin_utils_1.lodash
|
|
87
|
-
.uniq(
|
|
78
|
+
.uniq(await addAntdLocales({ lang, country }))
|
|
88
79
|
.filter((localePath) => modulesHasLocale(localePath));
|
|
89
80
|
return {
|
|
90
81
|
lang,
|
|
@@ -97,9 +88,9 @@ const getLocaleList = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
97
88
|
paths: groups[name].map((item) => (0, plugin_utils_1.winPath)(item.path)),
|
|
98
89
|
momentLocale,
|
|
99
90
|
};
|
|
100
|
-
})
|
|
91
|
+
});
|
|
101
92
|
return Promise.all(promises);
|
|
102
|
-
}
|
|
93
|
+
};
|
|
103
94
|
exports.getLocaleList = getLocaleList;
|
|
104
95
|
const exactLocalePaths = (data) => {
|
|
105
96
|
return plugin_utils_1.lodash.flatten(data.map((item) => item.paths));
|
|
@@ -12,7 +12,9 @@ export declare class Model {
|
|
|
12
12
|
namespace: string;
|
|
13
13
|
id: string;
|
|
14
14
|
exportName: string;
|
|
15
|
-
|
|
15
|
+
deps: string[];
|
|
16
|
+
constructor(file: string, sort: {} | undefined, id: number);
|
|
17
|
+
findDeps(sort: object): string[];
|
|
16
18
|
}
|
|
17
19
|
export declare class ModelUtils {
|
|
18
20
|
api: IApi;
|
|
@@ -20,8 +22,10 @@ export declare class ModelUtils {
|
|
|
20
22
|
count: number;
|
|
21
23
|
constructor(api: IApi | null, opts: IOpts);
|
|
22
24
|
getAllModels(opts: {
|
|
25
|
+
sort?: object;
|
|
23
26
|
extraModels: string[];
|
|
24
27
|
}): Model[];
|
|
28
|
+
getSortedNamespaces(models: Model[]): string[];
|
|
25
29
|
getModels(opts: {
|
|
26
30
|
base: string;
|
|
27
31
|
pattern?: string;
|
package/dist/utils/modelUtils.js
CHANGED
|
@@ -29,13 +29,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
exports.ModelUtils = exports.Model = void 0;
|
|
30
30
|
const parser = __importStar(require("@umijs/bundler-utils/compiled/babel/parser"));
|
|
31
31
|
const traverse_1 = __importDefault(require("@umijs/bundler-utils/compiled/babel/traverse"));
|
|
32
|
+
const t = __importStar(require("@umijs/bundler-utils/compiled/babel/types"));
|
|
32
33
|
const esbuild_1 = require("@umijs/bundler-utils/compiled/esbuild");
|
|
33
34
|
const fs_1 = require("fs");
|
|
34
35
|
const path_1 = require("path");
|
|
35
36
|
const plugin_utils_1 = require("umi/plugin-utils");
|
|
36
37
|
const astUtils_1 = require("./astUtils");
|
|
37
38
|
class Model {
|
|
38
|
-
constructor(file, id) {
|
|
39
|
+
constructor(file, sort, id) {
|
|
39
40
|
let namespace;
|
|
40
41
|
let exportName;
|
|
41
42
|
const [_file, meta] = file.split('#');
|
|
@@ -48,6 +49,36 @@ class Model {
|
|
|
48
49
|
this.id = `model_${id}`;
|
|
49
50
|
this.namespace = namespace || (0, path_1.basename)(file, (0, path_1.extname)(file));
|
|
50
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];
|
|
51
82
|
}
|
|
52
83
|
}
|
|
53
84
|
exports.Model = Model;
|
|
@@ -61,7 +92,7 @@ class ModelUtils {
|
|
|
61
92
|
getAllModels(opts) {
|
|
62
93
|
// reset count
|
|
63
94
|
this.count = 1;
|
|
64
|
-
|
|
95
|
+
const models = [
|
|
65
96
|
...this.getModels({
|
|
66
97
|
base: (0, path_1.join)(this.api.paths.absSrcPath, 'models'),
|
|
67
98
|
pattern: '**/*.{ts,tsx,js,jsx}',
|
|
@@ -76,8 +107,59 @@ class ModelUtils {
|
|
|
76
107
|
}),
|
|
77
108
|
...opts.extraModels,
|
|
78
109
|
].map((file) => {
|
|
79
|
-
return new Model(file, this.count++);
|
|
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
|
+
}
|
|
80
161
|
});
|
|
162
|
+
return [...new Set(final)];
|
|
81
163
|
}
|
|
82
164
|
getModels(opts) {
|
|
83
165
|
return plugin_utils_1.glob
|
|
@@ -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';
|
|
@@ -48,6 +48,7 @@ export function patchMicroAppRoute(
|
|
|
48
48
|
getMicroAppRouteComponent: (opts: {
|
|
49
49
|
appName: string;
|
|
50
50
|
base: string;
|
|
51
|
+
routePath: string;
|
|
51
52
|
masterHistoryType: string;
|
|
52
53
|
routeProps?: any;
|
|
53
54
|
}) => string | ReactComponentElement<any>,
|
|
@@ -63,9 +64,9 @@ export function patchMicroAppRoute(
|
|
|
63
64
|
const microAppProps =
|
|
64
65
|
route[`${routeBindingAlias}Props`] || route.microAppProps || {};
|
|
65
66
|
if (microAppName) {
|
|
66
|
-
if (route.
|
|
67
|
-
const childrenRouteHasComponent = route.
|
|
68
|
-
(r: any) => r.
|
|
67
|
+
if (route.children?.length) {
|
|
68
|
+
const childrenRouteHasComponent = route.children.some(
|
|
69
|
+
(r: any) => r.element,
|
|
69
70
|
);
|
|
70
71
|
if (childrenRouteHasComponent) {
|
|
71
72
|
throw new Error(
|
|
@@ -74,7 +75,10 @@ export function patchMicroAppRoute(
|
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
|
|
78
|
+
// 自动追加通配符,匹配子应用的路由
|
|
79
|
+
if (!route.path.endsWith('/*')) {
|
|
80
|
+
route.path = route.path.replace(/\/?$/, '/*');
|
|
81
|
+
}
|
|
78
82
|
|
|
79
83
|
const { settings = {}, ...componentProps } = microAppProps;
|
|
80
84
|
const routeProps = {
|
|
@@ -85,10 +89,11 @@ export function patchMicroAppRoute(
|
|
|
85
89
|
const opts = {
|
|
86
90
|
appName: microAppName,
|
|
87
91
|
base,
|
|
92
|
+
routePath: route.path,
|
|
88
93
|
masterHistoryType,
|
|
89
94
|
routeProps,
|
|
90
95
|
};
|
|
91
|
-
route.
|
|
96
|
+
route.element = React.createElement(getMicroAppRouteComponent(opts), null);
|
|
92
97
|
}
|
|
93
98
|
}
|
|
94
99
|
|
|
@@ -100,8 +105,8 @@ const recursiveSearch = (
|
|
|
100
105
|
if (routes[i].path === path) {
|
|
101
106
|
return routes[i];
|
|
102
107
|
}
|
|
103
|
-
if (routes[i].
|
|
104
|
-
const found = recursiveSearch(routes[i].
|
|
108
|
+
if (routes[i].children && routes[i].children?.length) {
|
|
109
|
+
const found = recursiveSearch(routes[i].children || [], path);
|
|
105
110
|
if (found) {
|
|
106
111
|
return found;
|
|
107
112
|
}
|
|
@@ -123,8 +128,8 @@ export function insertRoute(routes: IRouteProps[], microAppRoute: IRouteProps) {
|
|
|
123
128
|
);
|
|
124
129
|
}
|
|
125
130
|
found.exact = false;
|
|
126
|
-
found.
|
|
127
|
-
found.
|
|
131
|
+
found.children = found.children || [];
|
|
132
|
+
found.children.push(microAppRoute);
|
|
128
133
|
} else {
|
|
129
134
|
throw new Error(
|
|
130
135
|
`[plugin-qiankun]: path "${microAppRoute.insert}" not found`,
|
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { MicroApp } from './MicroApp';
|
|
3
|
-
import { useLocation } from 'umi';
|
|
4
3
|
|
|
5
4
|
export function getMicroAppRouteComponent(opts: {
|
|
6
5
|
appName: string;
|
|
7
6
|
base: string;
|
|
7
|
+
routePath: string;
|
|
8
8
|
masterHistoryType: string;
|
|
9
9
|
routeProps?: any;
|
|
10
10
|
}) {
|
|
11
|
-
const { base, masterHistoryType, appName, routeProps } = opts;
|
|
12
|
-
const RouteComponent = (
|
|
13
|
-
const url = useLocation().pathname;
|
|
14
|
-
|
|
11
|
+
const { base, masterHistoryType, appName, routeProps, routePath } = opts;
|
|
12
|
+
const RouteComponent = () => {
|
|
15
13
|
// 默认取静态配置的 base
|
|
16
14
|
let umiConfigBase = base === '/' ? '' : base;
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
// 拼接子应用挂载路由
|
|
17
|
+
let runtimeMatchedBase = umiConfigBase + routePath.replace('/*', '');
|
|
20
18
|
|
|
21
19
|
{{#dynamicRoot}}
|
|
22
20
|
// @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.
|
|
37
|
+
if (!rootRoute.children) {
|
|
38
38
|
return routes;
|
|
39
39
|
}
|
|
40
|
-
return getRootRoutes(rootRoute.
|
|
40
|
+
return getRootRoutes(rootRoute.children);
|
|
41
41
|
}
|
|
42
42
|
return routes;
|
|
43
43
|
};
|
|
@@ -50,11 +50,12 @@ function patchMicroAppRouteComponent(routes: any[]) {
|
|
|
50
50
|
const patchRoute = (route: any) => {
|
|
51
51
|
patchMicroAppRoute(route, getMicroAppRouteComponent, {
|
|
52
52
|
base,
|
|
53
|
+
routePath: route.path,
|
|
53
54
|
masterHistoryType,
|
|
54
55
|
routeBindingAlias,
|
|
55
56
|
});
|
|
56
|
-
if (route.
|
|
57
|
-
route.
|
|
57
|
+
if (route.children?.length) {
|
|
58
|
+
route.children.forEach(patchRoute);
|
|
58
59
|
}
|
|
59
60
|
};
|
|
60
61
|
|
|
@@ -123,7 +124,7 @@ export async function render(oldRender: typeof noop) {
|
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
|
|
126
|
-
export function
|
|
127
|
+
export function patchClientRoutes({ routes }: { routes: any[] }) {
|
|
127
128
|
if (microAppRuntimeRoutes) {
|
|
128
129
|
patchMicroAppRouteComponent(routes);
|
|
129
130
|
}
|
|
@@ -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
|
|
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
|
|
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
|
-
|
|
112
|
+
contextOptsStack.push(clientRenderOpts);
|
|
115
113
|
}
|
|
116
114
|
|
|
117
115
|
// 第一次 mount defer 被 resolve 后umi 会自动触发 render,非第一次 mount 则需手动触发
|
|
@@ -121,6 +119,12 @@ export function genMount(mountElementId: string) {
|
|
|
121
119
|
defer.resolve();
|
|
122
120
|
}
|
|
123
121
|
|
|
122
|
+
// 如果需要手动控制 loading,通过主应用配置 props.autoSetLoading false 可以关闭
|
|
123
|
+
// 考虑到 react 18 之后 callback 不再准
|
|
124
|
+
// 所以在这里直接返回,而不使用 ReactDOM.render 的第三个参数
|
|
125
|
+
if (props.autoSetLoading && typeof props.setLoading === 'function') {
|
|
126
|
+
props.setLoading(false);
|
|
127
|
+
}
|
|
124
128
|
hasMountedAtLeastOnce = true;
|
|
125
129
|
};
|
|
126
130
|
}
|
|
@@ -1,21 +1,15 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
|
-
|
|
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
|
-
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umijs/plugins",
|
|
3
|
-
"version": "4.0.0-rc.
|
|
3
|
+
"version": "4.0.0-rc.16",
|
|
4
4
|
"description": "@umijs/plugins",
|
|
5
5
|
"homepage": "https://github.com/umijs/umi-next/tree/master/packages/plugins#readme",
|
|
6
6
|
"bugs": "https://github.com/umijs/umi-next/issues",
|
|
@@ -17,19 +17,19 @@
|
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "pnpm tsc",
|
|
20
|
-
"build:deps": "
|
|
20
|
+
"build:deps": "umi-scripts bundleDeps",
|
|
21
21
|
"dev": "pnpm build -- --watch",
|
|
22
|
-
"test": "
|
|
22
|
+
"test": "umi-scripts jest-turbo"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ahooksjs/use-request": "^2.0.0",
|
|
26
26
|
"@ant-design/icons": "^4.7.0",
|
|
27
|
-
"@ant-design/pro-layout": "^6.
|
|
28
|
-
"@umijs/bundler-utils": "4.0.0-rc.
|
|
27
|
+
"@ant-design/pro-layout": "^6.38.0",
|
|
28
|
+
"@umijs/bundler-utils": "4.0.0-rc.16",
|
|
29
29
|
"antd-dayjs-webpack-plugin": "^1.0.6",
|
|
30
|
-
"axios": "^0.
|
|
30
|
+
"axios": "^0.27.2",
|
|
31
31
|
"babel-plugin-import": "^1.13.3",
|
|
32
|
-
"dayjs": "^1.11.
|
|
32
|
+
"dayjs": "^1.11.2",
|
|
33
33
|
"dva-core": "^2.0.4",
|
|
34
34
|
"dva-immer": "^1.0.0",
|
|
35
35
|
"dva-loading": "^3.0.22",
|
|
@@ -39,12 +39,12 @@
|
|
|
39
39
|
"moment": "^2.29.3",
|
|
40
40
|
"qiankun": "^2.7.0",
|
|
41
41
|
"react-intl": "3.12.1",
|
|
42
|
-
"react-redux": "^8.0.
|
|
42
|
+
"react-redux": "^8.0.1",
|
|
43
43
|
"redux": "^4.2.0",
|
|
44
44
|
"warning": "^4.0.3"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"umi": "4.0.0-rc.
|
|
47
|
+
"umi": "4.0.0-rc.16"
|
|
48
48
|
},
|
|
49
49
|
"publishConfig": {
|
|
50
50
|
"access": "public"
|