@umijs/preset-umi 4.0.0-beta.14 → 4.0.0-beta.18
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/commands/build.js +1 -1
- package/dist/commands/dev/createRouteMiddleware.js +2 -2
- package/dist/commands/dev/dev.js +9 -3
- package/dist/commands/dev/getMarkupArgs.js +2 -1
- package/dist/commands/generate/prettier.js +35 -3
- package/dist/commands/plugin.js +0 -1
- package/dist/features/appData/appData.js +27 -0
- package/dist/features/configPlugins/configPlugins.js +5 -2
- package/dist/features/configPlugins/schema.js +14 -4
- package/dist/features/esmi/Service.js +1 -0
- package/dist/features/esmi/esbuildPlugins/requireToImport.d.ts +8 -0
- package/dist/features/esmi/esbuildPlugins/requireToImport.js +61 -0
- package/dist/features/esmi/esbuildPlugins/topLevelExternal.d.ts +13 -0
- package/dist/features/esmi/esbuildPlugins/topLevelExternal.js +37 -0
- package/dist/features/esmi/esmi.js +60 -15
- package/dist/features/lowImport/babelPlugin.js +18 -5
- package/dist/features/mock/getMockData.d.ts +4 -0
- package/dist/features/mock/getMockData.js +14 -5
- package/dist/features/mock/mock.js +9 -2
- package/dist/features/polyfill/polyfill.js +51 -9
- package/dist/features/polyfill/publicPathPolyfill.d.ts +3 -0
- package/dist/features/polyfill/publicPathPolyfill.js +14 -0
- package/dist/features/tmpFiles/routes.js +38 -3
- package/dist/features/tmpFiles/tmpFiles.js +99 -7
- package/dist/features/vite/vite.d.ts +3 -0
- package/dist/features/vite/vite.js +34 -0
- package/dist/index.js +2 -0
- package/dist/libs/scan.d.ts +5 -1
- package/dist/libs/scan.js +58 -4
- package/dist/registerMethods.js +2 -2
- package/dist/types.d.ts +3 -0
- package/dist/utils/transformIEAR.js +7 -2
- package/package.json +13 -12
- package/templates/history.tpl +15 -0
- package/templates/umi.tpl +4 -0
package/dist/commands/build.js
CHANGED
|
@@ -110,7 +110,7 @@ umi build --clean
|
|
|
110
110
|
const { vite } = api.args;
|
|
111
111
|
const markupArgs = yield (0, getMarkupArgs_1.getMarkupArgs)({ api });
|
|
112
112
|
// @ts-ignore
|
|
113
|
-
const markup = yield (0, server_1.getMarkup)(Object.assign(Object.assign({}, markupArgs), { scripts: ['/umi.js'].concat(markupArgs.scripts), esmScript: !!opts.config.esm || vite, path: '/' }));
|
|
113
|
+
const markup = yield (0, server_1.getMarkup)(Object.assign(Object.assign({}, markupArgs), { styles: ['/umi.css'].concat(markupArgs.styles), scripts: ['/umi.js'].concat(markupArgs.scripts), esmScript: !!opts.config.esm || vite, path: '/' }));
|
|
114
114
|
(0, fs_1.writeFileSync)((0, path_1.join)(api.paths.absOutputPath, 'index.html'), markup, 'utf-8');
|
|
115
115
|
utils_1.logger.event('build index.html');
|
|
116
116
|
// print size
|
|
@@ -28,11 +28,11 @@ function createRouteMiddleware(opts) {
|
|
|
28
28
|
// add noshim attr for skip importmap shim logic for this modules
|
|
29
29
|
{ content: viteRefreshScript, noshim: '' },
|
|
30
30
|
{ src: '/@vite/client', noshim: '' },
|
|
31
|
-
'/.umi/umi.ts',
|
|
31
|
+
opts.api.appData.hasSrcDir ? '/src/.umi/umi.ts' : '/.umi/umi.ts',
|
|
32
32
|
];
|
|
33
33
|
const markupArgs = yield (0, getMarkupArgs_1.getMarkupArgs)(opts);
|
|
34
34
|
// @ts-ignore
|
|
35
|
-
const requestHandler = yield (0, server_1.createRequestHandler)(Object.assign(Object.assign({}, markupArgs), { scripts: (vite ? viteScripts : ['/umi.js']).concat(markupArgs.scripts), esmScript: vite }));
|
|
35
|
+
const requestHandler = yield (0, server_1.createRequestHandler)(Object.assign(Object.assign({}, markupArgs), { styles: ['/umi.css'].concat(markupArgs.styles), scripts: (vite ? viteScripts : ['/umi.js']).concat(markupArgs.scripts), esmScript: vite }));
|
|
36
36
|
requestHandler(req, res, next);
|
|
37
37
|
});
|
|
38
38
|
}
|
package/dist/commands/dev/dev.js
CHANGED
|
@@ -56,7 +56,7 @@ umi dev
|
|
|
56
56
|
PORT=8888 umi dev
|
|
57
57
|
`,
|
|
58
58
|
fn() {
|
|
59
|
-
var _a;
|
|
59
|
+
var _a, _b;
|
|
60
60
|
return __awaiter(this, void 0, void 0, function* () {
|
|
61
61
|
const enableVite = api.args.vite;
|
|
62
62
|
// clear tmp except cache
|
|
@@ -102,9 +102,10 @@ PORT=8888 umi dev
|
|
|
102
102
|
key: 'addTmpGenerateWatcherPaths',
|
|
103
103
|
initialValue: [
|
|
104
104
|
absPagesPath,
|
|
105
|
+
!api.config.routes && ((_a = api.config.conventionRoutes) === null || _a === void 0 ? void 0 : _a.base),
|
|
105
106
|
(0, path_1.join)(absSrcPath, 'layouts'),
|
|
106
107
|
...(0, watch_1.expandJSPaths)((0, path_1.join)(absSrcPath, 'app')),
|
|
107
|
-
],
|
|
108
|
+
].filter(Boolean),
|
|
108
109
|
});
|
|
109
110
|
utils_1.lodash.uniq(watcherPaths.map(utils_1.winPath)).forEach((p) => {
|
|
110
111
|
(0, watch_1.watch)({
|
|
@@ -238,7 +239,12 @@ PORT=8888 umi dev
|
|
|
238
239
|
key: 'onDevCompileDone',
|
|
239
240
|
args: opts,
|
|
240
241
|
});
|
|
241
|
-
}, mfsuWithESBuild: (
|
|
242
|
+
}, mfsuWithESBuild: (_b = api.config.mfsu) === null || _b === void 0 ? void 0 : _b.esbuild, cache: {
|
|
243
|
+
buildDependencies: [
|
|
244
|
+
api.pkgPath,
|
|
245
|
+
api.service.configManager.mainConfigFile || '',
|
|
246
|
+
].filter(Boolean),
|
|
247
|
+
} });
|
|
242
248
|
if (enableVite) {
|
|
243
249
|
yield bundlerVite.dev(opts);
|
|
244
250
|
}
|
|
@@ -15,6 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.getMarkupArgs = void 0;
|
|
16
16
|
const cheerio_1 = __importDefault(require("@umijs/utils/compiled/cheerio"));
|
|
17
17
|
function getMarkupArgs(opts) {
|
|
18
|
+
var _a;
|
|
18
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
19
20
|
const headScripts = yield opts.api.applyPlugins({
|
|
20
21
|
key: 'addHTMLHeadScripts',
|
|
@@ -42,7 +43,7 @@ function getMarkupArgs(opts) {
|
|
|
42
43
|
});
|
|
43
44
|
return {
|
|
44
45
|
mountElementId: opts.api.config.mountElementId,
|
|
45
|
-
base: opts.api.config.base,
|
|
46
|
+
base: ((_a = opts.api.config.history) === null || _a === void 0 ? void 0 : _a.type) === 'browser' ? opts.api.config.base : '/',
|
|
46
47
|
routes: opts.api.appData.routes,
|
|
47
48
|
favicon,
|
|
48
49
|
headScripts,
|
|
@@ -8,8 +8,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
15
|
const core_1 = require("@umijs/core");
|
|
16
|
+
const utils_1 = require("@umijs/utils");
|
|
17
|
+
const assert_1 = __importDefault(require("assert"));
|
|
13
18
|
const fs_1 = require("fs");
|
|
14
19
|
const path_1 = require("path");
|
|
15
20
|
exports.default = (api) => {
|
|
@@ -23,9 +28,36 @@ exports.default = (api) => {
|
|
|
23
28
|
// 存在 .prettierrc,不开启
|
|
24
29
|
return !(0, fs_1.existsSync)((0, path_1.join)(api.paths.cwd, '.prettierrc'));
|
|
25
30
|
},
|
|
26
|
-
fn: (
|
|
27
|
-
//
|
|
28
|
-
|
|
31
|
+
fn: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
32
|
+
// 1、修改 package.json,加上 prettier 和插件
|
|
33
|
+
api.pkg.devDependencies = Object.assign(Object.assign({}, api.pkg.devDependencies), { prettier: '^2', 'prettier-plugin-organize-imports': '^2', 'prettier-plugin-packagejson': '^2' });
|
|
34
|
+
(0, fs_1.writeFileSync)(api.pkgPath, JSON.stringify(api.pkg, null, 2));
|
|
35
|
+
utils_1.logger.info('Write package.json');
|
|
36
|
+
// 2、添加 .prettierrc 和 .prettierignore
|
|
37
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(api.cwd, '.prettierrc'), `
|
|
38
|
+
{
|
|
39
|
+
"printWidth": 80,
|
|
40
|
+
"singleQuote": true,
|
|
41
|
+
"trailingComma": "all",
|
|
42
|
+
"proseWrap": "never",
|
|
43
|
+
"overrides": [{ "files": ".prettierrc", "options": { "parser": "json" } }],
|
|
44
|
+
"plugins": ["prettier-plugin-organize-imports", "prettier-plugin-packagejson"]
|
|
45
|
+
}
|
|
46
|
+
`.trimLeft());
|
|
47
|
+
utils_1.logger.info('Write .prettierrc');
|
|
48
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(api.cwd, '.prettierignore'), `
|
|
49
|
+
node_modules
|
|
50
|
+
.umi
|
|
51
|
+
.umi-production
|
|
52
|
+
`.trimLeft());
|
|
53
|
+
utils_1.logger.info('Write .prettierignore');
|
|
54
|
+
// 3、执行 npm install
|
|
55
|
+
const npmClient = api.userConfig.npmClient;
|
|
56
|
+
(0, assert_1.default)(npmClient, `npmClient is required in your config.`);
|
|
57
|
+
(0, utils_1.installWithNpmClient)({
|
|
58
|
+
npmClient,
|
|
59
|
+
});
|
|
60
|
+
utils_1.logger.info(`Install dependencies with ${npmClient}`);
|
|
29
61
|
}),
|
|
30
62
|
});
|
|
31
63
|
};
|
package/dist/commands/plugin.js
CHANGED
|
@@ -14,6 +14,7 @@ const utils_1 = require("@umijs/utils");
|
|
|
14
14
|
const fs_1 = require("fs");
|
|
15
15
|
const path_1 = require("path");
|
|
16
16
|
const watch_1 = require("../../commands/dev/watch");
|
|
17
|
+
const scan_1 = require("../../libs/scan");
|
|
17
18
|
const routes_1 = require("../tmpFiles/routes");
|
|
18
19
|
exports.default = (api) => {
|
|
19
20
|
api.modifyAppData((memo) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -29,6 +30,7 @@ exports.default = (api) => {
|
|
|
29
30
|
version: require((0, path_1.join)(api.config.alias.react, 'package.json')).version,
|
|
30
31
|
};
|
|
31
32
|
memo.appJS = yield getAppJsInfo();
|
|
33
|
+
memo.vite = api.args.vite ? {} : undefined;
|
|
32
34
|
return memo;
|
|
33
35
|
}));
|
|
34
36
|
// Execute earliest, so that other onGenerateFiles can get it
|
|
@@ -43,6 +45,31 @@ exports.default = (api) => {
|
|
|
43
45
|
},
|
|
44
46
|
stage: Number.NEGATIVE_INFINITY,
|
|
45
47
|
});
|
|
48
|
+
// used in esmi and vite
|
|
49
|
+
api.register({
|
|
50
|
+
key: 'updateAppDataDeps',
|
|
51
|
+
fn() {
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
const resolver = (0, scan_1.createResolver)({
|
|
54
|
+
alias: api.config.alias,
|
|
55
|
+
});
|
|
56
|
+
api.appData.deps = yield (0, scan_1.scan)({
|
|
57
|
+
entry: (0, path_1.join)(api.paths.absTmpPath, 'umi.ts'),
|
|
58
|
+
externals: api.config.externals,
|
|
59
|
+
resolver,
|
|
60
|
+
});
|
|
61
|
+
// FIXME: force include react & react-dom
|
|
62
|
+
if (api.appData.deps['react']) {
|
|
63
|
+
api.appData.deps['react'].version = api.appData.react.version;
|
|
64
|
+
}
|
|
65
|
+
api.appData.deps['react-dom'] = {
|
|
66
|
+
version: api.appData.react.version,
|
|
67
|
+
matches: ['react-dom'],
|
|
68
|
+
subpaths: [],
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
},
|
|
72
|
+
});
|
|
46
73
|
function getAppJsInfo() {
|
|
47
74
|
return __awaiter(this, void 0, void 0, function* () {
|
|
48
75
|
for (const path of (0, watch_1.expandJSPaths)((0, path_1.join)(api.paths.absSrcPath, 'app'))) {
|
|
@@ -16,8 +16,7 @@ function resolveProjectDep(opts) {
|
|
|
16
16
|
exports.default = (api) => {
|
|
17
17
|
const configDefaults = {
|
|
18
18
|
alias: {
|
|
19
|
-
umi:
|
|
20
|
-
'@umijs/renderer-react': (0, path_1.dirname)(require.resolve('@umijs/renderer-react/package.json')),
|
|
19
|
+
umi: '@@/exports',
|
|
21
20
|
react: resolveProjectDep({
|
|
22
21
|
pkg: api.pkg,
|
|
23
22
|
cwd: api.cwd,
|
|
@@ -36,6 +35,10 @@ exports.default = (api) => {
|
|
|
36
35
|
publicPath: '/',
|
|
37
36
|
mountElementId: 'root',
|
|
38
37
|
base: '/',
|
|
38
|
+
history: { type: 'browser' },
|
|
39
|
+
targets: {
|
|
40
|
+
chrome: 87,
|
|
41
|
+
},
|
|
39
42
|
};
|
|
40
43
|
const bundleSchemas = (0, schema_1.getSchemas)();
|
|
41
44
|
const extraSchemas = (0, schema_2.getSchemas)();
|
|
@@ -5,14 +5,24 @@ const utils_1 = require("@umijs/utils");
|
|
|
5
5
|
function getSchemas() {
|
|
6
6
|
return {
|
|
7
7
|
base: (Joi) => Joi.string(),
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
conventionRoutes: (Joi) => Joi.object({
|
|
9
|
+
exclude: Joi.array().items(Joi.any()),
|
|
10
|
+
base: Joi.string(),
|
|
11
|
+
}),
|
|
10
12
|
favicon: (Joi) => Joi.string(),
|
|
11
|
-
headScripts: (Joi) => Joi.array()
|
|
12
|
-
|
|
13
|
+
headScripts: (Joi) => Joi.array(),
|
|
14
|
+
history: (Joi) => Joi.object({
|
|
15
|
+
type: Joi.string().valid('browser', 'hash', 'memory'),
|
|
16
|
+
}),
|
|
17
|
+
links: (Joi) => Joi.array(),
|
|
18
|
+
metas: (Joi) => Joi.array(),
|
|
13
19
|
mountElementId: (Joi) => Joi.string(),
|
|
14
20
|
npmClient: (Joi) => Joi.string().valid(utils_1.NpmClientEnum.pnpm, utils_1.NpmClientEnum.tnpm, utils_1.NpmClientEnum.cnpm, utils_1.NpmClientEnum.yarn, utils_1.NpmClientEnum.npm),
|
|
21
|
+
plugins: (Joi) => Joi.array().items(Joi.string()),
|
|
22
|
+
publicPath: (Joi) => Joi.string().regex(/\/$/).error(new Error('publicPath must end with /')),
|
|
15
23
|
routes: (Joi) => Joi.array().items(Joi.object()),
|
|
24
|
+
scripts: (Joi) => Joi.array(),
|
|
25
|
+
styles: (Joi) => Joi.array(),
|
|
16
26
|
};
|
|
17
27
|
}
|
|
18
28
|
exports.getSchemas = getSchemas;
|
|
@@ -101,6 +101,7 @@ class ESMIService {
|
|
|
101
101
|
});
|
|
102
102
|
// get the build ticket id
|
|
103
103
|
const ticketId = yield this.build(data);
|
|
104
|
+
utils_1.logger.info(`ticketId: ${ticketId}`);
|
|
104
105
|
// continue to the next request after 2s
|
|
105
106
|
const next = () => new Promise((resolve) => setTimeout(() => resolve(deferrer()), 2000));
|
|
106
107
|
const deferrer = () => {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Plugin } from '@umijs/bundler-utils/compiled/esbuild';
|
|
2
|
+
import type { DepOptimizationOptions } from 'vite';
|
|
3
|
+
/**
|
|
4
|
+
* transform require call to import
|
|
5
|
+
*/
|
|
6
|
+
export default function requireToImportPlugin({ exclude, }: {
|
|
7
|
+
exclude: NonNullable<DepOptimizationOptions['exclude']>;
|
|
8
|
+
}): Plugin;
|
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const lodash_1 = require("@umijs/utils/compiled/lodash");
|
|
13
|
+
/**
|
|
14
|
+
* transform require call to import
|
|
15
|
+
*/
|
|
16
|
+
function requireToImportPlugin({ exclude, }) {
|
|
17
|
+
const regSafeExclude = exclude.map((e) => e.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
18
|
+
const requireRegExp = new RegExp(`^(${regSafeExclude.join('|')})$`);
|
|
19
|
+
return {
|
|
20
|
+
name: 'preset-umi:esmi-require-to-import',
|
|
21
|
+
setup(build) {
|
|
22
|
+
// handler require calls for external deps
|
|
23
|
+
build.onResolve({
|
|
24
|
+
filter: requireRegExp,
|
|
25
|
+
}, (args) => __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
if (args.kind === 'require-call') {
|
|
27
|
+
return {
|
|
28
|
+
path: args.path,
|
|
29
|
+
namespace: 'esmi-require-to-import',
|
|
30
|
+
pluginData: {
|
|
31
|
+
resolveDir: args.resolveDir,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}));
|
|
36
|
+
// replace load content
|
|
37
|
+
build.onLoad({
|
|
38
|
+
filter: /.*/,
|
|
39
|
+
namespace: 'esmi-require-to-import',
|
|
40
|
+
}, (args) => {
|
|
41
|
+
const { resolveDir } = args.pluginData || {};
|
|
42
|
+
const packageName = args.path;
|
|
43
|
+
const starSpecifier = `${(0, lodash_1.camelCase)(packageName)}Star`;
|
|
44
|
+
const defaultSpecifier = `${(0, lodash_1.camelCase)(packageName)}Default`;
|
|
45
|
+
return {
|
|
46
|
+
resolveDir,
|
|
47
|
+
contents: [
|
|
48
|
+
`import * as ${starSpecifier} from '${packageName}';`,
|
|
49
|
+
'',
|
|
50
|
+
`const ${defaultSpecifier} = ${starSpecifier}.default ? ${starSpecifier}.default : ${starSpecifier};`,
|
|
51
|
+
'',
|
|
52
|
+
`export default ${defaultSpecifier};`,
|
|
53
|
+
`export * from '${packageName}';`,
|
|
54
|
+
'',
|
|
55
|
+
].join('\n'),
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
exports.default = requireToImportPlugin;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Plugin } from '@umijs/bundler-utils/compiled/esbuild';
|
|
2
|
+
import type { DepOptimizationOptions } from 'vite';
|
|
3
|
+
import type { createResolver } from '../../../libs/scan';
|
|
4
|
+
/**
|
|
5
|
+
* only external top level import, exclude sub-path imports for esmi
|
|
6
|
+
* example:
|
|
7
|
+
* - import from 'antd' will be externalized
|
|
8
|
+
* - import from 'antd/dist/antd.less' will not be externalized
|
|
9
|
+
*/
|
|
10
|
+
export default function topLevelExternal({ exclude, resolver, }: {
|
|
11
|
+
exclude: NonNullable<DepOptimizationOptions['exclude']>;
|
|
12
|
+
resolver: ReturnType<typeof createResolver>;
|
|
13
|
+
}): Plugin;
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
/**
|
|
13
|
+
* only external top level import, exclude sub-path imports for esmi
|
|
14
|
+
* example:
|
|
15
|
+
* - import from 'antd' will be externalized
|
|
16
|
+
* - import from 'antd/dist/antd.less' will not be externalized
|
|
17
|
+
*/
|
|
18
|
+
function topLevelExternal({ exclude, resolver, }) {
|
|
19
|
+
const regSafeExclude = exclude.map((e) => e.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
20
|
+
const subImportRegExp = new RegExp(`^(${regSafeExclude.join('|')})/`);
|
|
21
|
+
const extRegExp = /\.((?<!d)\.ts|jsx?|tsx)$/;
|
|
22
|
+
return {
|
|
23
|
+
name: 'preset-umi:esmi-top-level-external',
|
|
24
|
+
setup(build) {
|
|
25
|
+
build.onResolve({
|
|
26
|
+
filter: subImportRegExp,
|
|
27
|
+
}, (args) => __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
const resolved = yield resolver.resolve(args.resolveDir, args.path);
|
|
29
|
+
// only process javascript-like files
|
|
30
|
+
if (extRegExp.test(resolved)) {
|
|
31
|
+
return { path: resolved };
|
|
32
|
+
}
|
|
33
|
+
}));
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
exports.default = topLevelExternal;
|
|
@@ -16,8 +16,11 @@ const es_module_lexer_1 = require("@umijs/bundler-utils/compiled/es-module-lexer
|
|
|
16
16
|
const magic_string_1 = __importDefault(require("magic-string"));
|
|
17
17
|
const path_1 = require("path");
|
|
18
18
|
const scan_1 = require("../../libs/scan");
|
|
19
|
+
const requireToImport_1 = __importDefault(require("./esbuildPlugins/requireToImport"));
|
|
20
|
+
const topLevelExternal_1 = __importDefault(require("./esbuildPlugins/topLevelExternal"));
|
|
19
21
|
const Service_1 = __importDefault(require("./Service"));
|
|
20
22
|
let importmap = { imports: {}, scopes: {} };
|
|
23
|
+
let importmatches = {};
|
|
21
24
|
/**
|
|
22
25
|
* esmi vite plugin
|
|
23
26
|
*/
|
|
@@ -25,13 +28,36 @@ function esmi(opts) {
|
|
|
25
28
|
return {
|
|
26
29
|
name: 'preset-umi:esmi',
|
|
27
30
|
configResolved(config) {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
var _c, _d;
|
|
28
33
|
const { include, exclude } = config.optimizeDeps;
|
|
34
|
+
(_a = (_c = config.optimizeDeps).include) !== null && _a !== void 0 ? _a : (_c.include = []);
|
|
29
35
|
// do not pre-compile deps which will be loaded by importmap (for top-level deps)
|
|
30
36
|
if (include === null || include === void 0 ? void 0 : include.length) {
|
|
31
|
-
config.optimizeDeps.include = include.filter((item) => !importmap.imports[item]);
|
|
37
|
+
config.optimizeDeps.include = include.filter((item) => !importmatches[item] && !importmap.imports[item]);
|
|
32
38
|
}
|
|
33
|
-
// exclude pre-compile deps
|
|
34
|
-
config.optimizeDeps.exclude =
|
|
39
|
+
// exclude pre-compile deps
|
|
40
|
+
config.optimizeDeps.exclude = [
|
|
41
|
+
...new Set([
|
|
42
|
+
// deps from user config
|
|
43
|
+
...(exclude || []),
|
|
44
|
+
// deps from local scan
|
|
45
|
+
...Object.keys(importmatches),
|
|
46
|
+
// deps from esmi analyze result
|
|
47
|
+
...Object.keys(importmap.imports),
|
|
48
|
+
]),
|
|
49
|
+
];
|
|
50
|
+
// apply esbuild plugins
|
|
51
|
+
(_b = (_d = config.optimizeDeps).esbuildOptions) !== null && _b !== void 0 ? _b : (_d.esbuildOptions = {});
|
|
52
|
+
config.optimizeDeps.esbuildOptions.plugins = [
|
|
53
|
+
// transform require call to import
|
|
54
|
+
(0, requireToImport_1.default)({ exclude: config.optimizeDeps.exclude }),
|
|
55
|
+
// make sure vite only external top-level npm imports, and resolve sub-path npm imports
|
|
56
|
+
(0, topLevelExternal_1.default)({
|
|
57
|
+
exclude: config.optimizeDeps.exclude,
|
|
58
|
+
resolver: opts.resolver,
|
|
59
|
+
}),
|
|
60
|
+
].concat(config.optimizeDeps.esbuildOptions.plugins || []);
|
|
35
61
|
},
|
|
36
62
|
transform(source) {
|
|
37
63
|
try {
|
|
@@ -42,9 +68,17 @@ function esmi(opts) {
|
|
|
42
68
|
imports.forEach((item) => {
|
|
43
69
|
const { n: specifier, s: start, e: end } = item;
|
|
44
70
|
// replace npm package to CDN url for matched imports
|
|
45
|
-
if (specifier
|
|
46
|
-
|
|
47
|
-
|
|
71
|
+
if (specifier) {
|
|
72
|
+
const replacement =
|
|
73
|
+
// search from local scan matches first (for alias)
|
|
74
|
+
(importmatches[specifier] &&
|
|
75
|
+
importmap.imports[importmatches[specifier]]) ||
|
|
76
|
+
// search from esmi analyze result
|
|
77
|
+
importmap.imports[specifier];
|
|
78
|
+
if (replacement) {
|
|
79
|
+
s !== null && s !== void 0 ? s : (s = new magic_string_1.default(source));
|
|
80
|
+
s.overwrite(start, end, replacement);
|
|
81
|
+
}
|
|
48
82
|
}
|
|
49
83
|
});
|
|
50
84
|
return (s === null || s === void 0 ? void 0 : s.toString()) || source;
|
|
@@ -78,7 +112,11 @@ function generatePkgData(api) {
|
|
|
78
112
|
name: 'default',
|
|
79
113
|
path: 'es/index.js',
|
|
80
114
|
from: '',
|
|
81
|
-
deps: Object.entries(api.appData.deps)
|
|
115
|
+
deps: Object.entries(api.appData.deps)
|
|
116
|
+
// only compile entry imports
|
|
117
|
+
.filter(([_, { matches }]) => matches.length)
|
|
118
|
+
// convert to esmi config
|
|
119
|
+
.map(([name, { version }]) => ({
|
|
82
120
|
name,
|
|
83
121
|
version,
|
|
84
122
|
usedMap: {
|
|
@@ -102,23 +140,29 @@ exports.default = (api) => {
|
|
|
102
140
|
return __awaiter(this, void 0, void 0, function* () {
|
|
103
141
|
// scan and module graph
|
|
104
142
|
// TODO: module graph
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
resolver,
|
|
143
|
+
yield api.applyPlugins({
|
|
144
|
+
key: 'updateAppDataDeps',
|
|
145
|
+
type: api.ApplyPluginsType.event,
|
|
109
146
|
});
|
|
110
147
|
// skip umi by default
|
|
111
148
|
delete api.appData.deps['umi'];
|
|
112
|
-
// FIXME: force include react & react-dom
|
|
113
|
-
api.appData.deps['react'] = api.appData.react.version;
|
|
114
|
-
api.appData.deps['react-dom'] = api.appData.react.version;
|
|
115
149
|
const data = generatePkgData(api);
|
|
116
150
|
const deps = data.pkgInfo.exports.reduce((r, exp) => r.concat(exp.deps.map((dep) => dep.name)), []);
|
|
117
151
|
const hasNewDep = deps.some((i) => !importmap.imports[i]);
|
|
118
152
|
// update importmap from esm if there has new import
|
|
119
153
|
if (hasNewDep) {
|
|
120
|
-
// TODO: add local cache and restore
|
|
121
154
|
importmap = (_a = (yield service.getImportmap(data))) === null || _a === void 0 ? void 0 : _a.importMap;
|
|
155
|
+
// update matches map to dep name
|
|
156
|
+
importmatches = Object.keys(api.appData.deps).reduce((r, dep) => {
|
|
157
|
+
// filter subpath imports
|
|
158
|
+
if (!api.appData.deps[dep].subpaths.length) {
|
|
159
|
+
// map all matches to dep name
|
|
160
|
+
api.appData.deps[dep].matches.forEach((m) => {
|
|
161
|
+
r[m] = dep;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return r;
|
|
165
|
+
}, {});
|
|
122
166
|
// because we will replaced package name to CDN url in vite plugin
|
|
123
167
|
// so we must append scope rules for the CDN url like the import specifier
|
|
124
168
|
// example:
|
|
@@ -194,6 +238,7 @@ exports.default = (api) => {
|
|
|
194
238
|
yield refreshImportMap();
|
|
195
239
|
// TODO: refresh page when importmap changed
|
|
196
240
|
}),
|
|
241
|
+
resolver,
|
|
197
242
|
}));
|
|
198
243
|
return memo;
|
|
199
244
|
});
|
|
@@ -37,15 +37,27 @@ function default_1() {
|
|
|
37
37
|
t.isImportNamespaceSpecifier(parentNode)) {
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
// don't support member expression
|
|
41
|
+
// e.g. foo.styles
|
|
42
|
+
if (t.isMemberExpression(parentNode) &&
|
|
43
|
+
path.node === parentNode.property) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// don't support object property
|
|
47
|
+
// e.g. { styles: 1 }
|
|
48
|
+
if (t.isObjectProperty(parentNode) && path.node === parentNode.key) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// TODO: 替换方式需要缓存,避免过多临时变量
|
|
52
|
+
if ((_a = state.opts.opts.identifierToLib) === null || _a === void 0 ? void 0 : _a.hasOwnProperty(name)) {
|
|
41
53
|
path.replaceWith((0, helper_module_imports_1.addNamed)(path, name, state.opts.opts.identifierToLib[name]));
|
|
42
54
|
}
|
|
43
|
-
else if ((_b = state.opts.opts.defaultToLib) === null || _b === void 0 ? void 0 : _b
|
|
55
|
+
else if ((_b = state.opts.opts.defaultToLib) === null || _b === void 0 ? void 0 : _b.hasOwnProperty(name)) {
|
|
44
56
|
path.replaceWith((0, helper_module_imports_1.addDefault)(path, state.opts.opts.defaultToLib[name], {
|
|
45
57
|
nameHint: name,
|
|
46
58
|
}));
|
|
47
59
|
}
|
|
48
|
-
else if ((_c = state.opts.opts.namespaceToLib) === null || _c === void 0 ? void 0 : _c
|
|
60
|
+
else if ((_c = state.opts.opts.namespaceToLib) === null || _c === void 0 ? void 0 : _c.hasOwnProperty(name)) {
|
|
49
61
|
path.replaceWith((0, helper_module_imports_1.addNamespace)(path, state.opts.opts.namespaceToLib[name]));
|
|
50
62
|
}
|
|
51
63
|
// import css
|
|
@@ -56,6 +68,7 @@ function default_1() {
|
|
|
56
68
|
}
|
|
57
69
|
},
|
|
58
70
|
MemberExpression(path, state) {
|
|
71
|
+
var _a, _b;
|
|
59
72
|
const { object, property } = path.node;
|
|
60
73
|
if (path.scope.hasBinding(object.name)) {
|
|
61
74
|
return;
|
|
@@ -66,8 +79,8 @@ function default_1() {
|
|
|
66
79
|
t.isImportNamespaceSpecifier(parentNode)) {
|
|
67
80
|
return;
|
|
68
81
|
}
|
|
69
|
-
if (state.opts.opts.withObjs[object.name] &&
|
|
70
|
-
(state.opts.opts.withObjs[object.name].members || []).includes(property.name)) {
|
|
82
|
+
if (((_a = state.opts.opts.withObjs) === null || _a === void 0 ? void 0 : _a[object.name]) &&
|
|
83
|
+
(((_b = state.opts.opts.withObjs) === null || _b === void 0 ? void 0 : _b[object.name].members) || []).includes(property.name)) {
|
|
71
84
|
path.replaceWith((0, helper_module_imports_1.addNamed)(path, property.name, state.opts.opts.withObjs[object.name].importFrom));
|
|
72
85
|
}
|
|
73
86
|
},
|
|
@@ -13,12 +13,20 @@ function getMockData(opts) {
|
|
|
13
13
|
implementor: esbuild_1.default,
|
|
14
14
|
});
|
|
15
15
|
utils_1.register.clearFiles();
|
|
16
|
-
|
|
17
|
-
.
|
|
16
|
+
function normalizeMockFile(file) {
|
|
17
|
+
const cwd = opts.cwd.endsWith('/') ? opts.cwd : `${opts.cwd}/`;
|
|
18
|
+
return utils_1.chalk.yellow(file.replace(cwd, ''));
|
|
19
|
+
}
|
|
20
|
+
const ret = [constants_1.MOCK_FILE_GLOB, ...(opts.mockConfig.include || [])]
|
|
21
|
+
.reduce((memo, pattern) => {
|
|
22
|
+
memo.push(...utils_1.glob.sync(pattern, { cwd: opts.cwd, ignore: ['**/*.d.ts'] }));
|
|
23
|
+
return memo;
|
|
24
|
+
}, [])
|
|
18
25
|
.reduce((memo, file) => {
|
|
19
26
|
const mockFile = `${opts.cwd}/${file}`;
|
|
20
27
|
const m = require(mockFile);
|
|
21
|
-
|
|
28
|
+
// Cannot convert undefined or null to object
|
|
29
|
+
const obj = (m === null || m === void 0 ? void 0 : m.default) || {};
|
|
22
30
|
for (const key of Object.keys(obj)) {
|
|
23
31
|
const mock = getMock({ key, obj });
|
|
24
32
|
mock.file = mockFile;
|
|
@@ -28,7 +36,7 @@ function getMockData(opts) {
|
|
|
28
36
|
utils_1.lodash.isPlainObject(mock.handler) ||
|
|
29
37
|
typeof mock.handler === 'function', `Mock handler must be function or array or object, but got ${typeof mock.handler} for ${mock.method} in ${mock.file}`);
|
|
30
38
|
if (memo[id]) {
|
|
31
|
-
|
|
39
|
+
utils_1.logger.warn(`${id} is duplicated in ${normalizeMockFile(mockFile)} and ${normalizeMockFile(memo[id].file)}`);
|
|
32
40
|
}
|
|
33
41
|
memo[id] = mock;
|
|
34
42
|
}
|
|
@@ -47,7 +55,7 @@ function getMock(opts) {
|
|
|
47
55
|
return { method, path, handler };
|
|
48
56
|
}
|
|
49
57
|
function parseKey(key) {
|
|
50
|
-
const spliced = key.split(
|
|
58
|
+
const spliced = key.split(/\s+/);
|
|
51
59
|
const len = spliced.length;
|
|
52
60
|
if (len === 1) {
|
|
53
61
|
return { method: constants_1.DEFAULT_METHOD, path: key };
|
|
@@ -56,6 +64,7 @@ function parseKey(key) {
|
|
|
56
64
|
const [method, path] = spliced;
|
|
57
65
|
const upperCaseMethod = method.toUpperCase();
|
|
58
66
|
(0, assert_1.default)(constants_1.VALID_METHODS.includes(upperCaseMethod), `method ${method} is not supported`);
|
|
67
|
+
(0, assert_1.default)(path, `${key}, path is undefined`);
|
|
59
68
|
return { method: upperCaseMethod, path };
|
|
60
69
|
}
|
|
61
70
|
}
|
|
@@ -21,6 +21,7 @@ function default_1(api) {
|
|
|
21
21
|
exclude: Joi.array()
|
|
22
22
|
.items(Joi.string())
|
|
23
23
|
.description('exclude files not parse mock'),
|
|
24
|
+
include: Joi.array().items(Joi.string()),
|
|
24
25
|
});
|
|
25
26
|
},
|
|
26
27
|
},
|
|
@@ -37,12 +38,18 @@ function default_1(api) {
|
|
|
37
38
|
path: `${api.cwd}/mock`,
|
|
38
39
|
addToUnWatches: true,
|
|
39
40
|
onChange: () => {
|
|
40
|
-
context.mockData = (0, getMockData_1.getMockData)({
|
|
41
|
+
context.mockData = (0, getMockData_1.getMockData)({
|
|
42
|
+
cwd: api.cwd,
|
|
43
|
+
mockConfig: api.config.mock || {},
|
|
44
|
+
});
|
|
41
45
|
},
|
|
42
46
|
});
|
|
43
47
|
});
|
|
44
48
|
api.addBeforeMiddlewares(() => __awaiter(this, void 0, void 0, function* () {
|
|
45
|
-
context.mockData = (0, getMockData_1.getMockData)({
|
|
49
|
+
context.mockData = (0, getMockData_1.getMockData)({
|
|
50
|
+
cwd: api.cwd,
|
|
51
|
+
mockConfig: api.config.mock || {},
|
|
52
|
+
});
|
|
46
53
|
return [
|
|
47
54
|
(0, createMockMiddleware_1.createMockMiddleware)({
|
|
48
55
|
context,
|
|
@@ -1,14 +1,56 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@umijs/bundler-utils/compiled/babel/core");
|
|
4
|
+
const path_1 = require("path");
|
|
3
5
|
exports.default = (api) => {
|
|
4
|
-
api.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
{
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
api.describe({
|
|
7
|
+
key: 'polyfill',
|
|
8
|
+
config: {
|
|
9
|
+
schema(Joi) {
|
|
10
|
+
return Joi.object().keys({
|
|
11
|
+
imports: Joi.array().items(Joi.string()).required().unique(),
|
|
12
|
+
});
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
enableBy: () => {
|
|
16
|
+
return process.env.BABEL_POLYFILL !== 'none';
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
api.onGenerateFiles(() => {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
const coreJsImports = ((_a = api.config.polyfill) === null || _a === void 0 ? void 0 : _a.imports)
|
|
22
|
+
? (_b = api.config.polyfill) === null || _b === void 0 ? void 0 : _b.imports.map((item) => `import '${item}';`).join('\n')
|
|
23
|
+
: `import 'core-js';`;
|
|
24
|
+
const { code } = (0, core_1.transform)(`
|
|
25
|
+
${coreJsImports}
|
|
26
|
+
import 'regenerator-runtime/runtime';
|
|
27
|
+
export {};
|
|
28
|
+
`, {
|
|
29
|
+
filename: 'polyfill.ts',
|
|
30
|
+
presets: [
|
|
31
|
+
[
|
|
32
|
+
require.resolve('@umijs/bundler-utils/compiled/babel/preset-env'),
|
|
33
|
+
{
|
|
34
|
+
useBuiltIns: 'entry',
|
|
35
|
+
corejs: '3',
|
|
36
|
+
modules: false,
|
|
37
|
+
targets: api.config.targets,
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
],
|
|
41
|
+
plugins: [
|
|
42
|
+
require.resolve('@umijs/babel-preset-umi/dist/plugins/lockCoreJS'),
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
api.writeTmpFile({
|
|
46
|
+
path: 'core/polyfill.ts',
|
|
47
|
+
noPluginDir: true,
|
|
48
|
+
content: code,
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
api.addPolyfillImports(() => [{ source: `./core/polyfill` }]);
|
|
52
|
+
api.modifyConfig((memo) => {
|
|
53
|
+
memo.alias['regenerator-runtime'] = (0, path_1.dirname)(require.resolve('regenerator-runtime/package'));
|
|
54
|
+
return memo;
|
|
13
55
|
});
|
|
14
56
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = (api) => {
|
|
4
|
+
api.addPolyfillImports(() => {
|
|
5
|
+
var _a;
|
|
6
|
+
return api.config.publicPath === 'auto' && ((_a = api.config.targets) === null || _a === void 0 ? void 0 : _a.ie)
|
|
7
|
+
? [
|
|
8
|
+
{
|
|
9
|
+
source: require.resolve('current-script-polyfill'),
|
|
10
|
+
},
|
|
11
|
+
]
|
|
12
|
+
: [];
|
|
13
|
+
});
|
|
14
|
+
};
|
|
@@ -16,6 +16,7 @@ const fs_1 = require("fs");
|
|
|
16
16
|
const path_1 = require("path");
|
|
17
17
|
// get route config
|
|
18
18
|
function getRoutes(opts) {
|
|
19
|
+
var _a, _b, _c;
|
|
19
20
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
21
|
let routes = null;
|
|
21
22
|
if (opts.api.config.routes) {
|
|
@@ -25,10 +26,33 @@ function getRoutes(opts) {
|
|
|
25
26
|
}
|
|
26
27
|
else {
|
|
27
28
|
routes = (0, core_1.getConventionRoutes)({
|
|
28
|
-
base: opts.api.paths.absPagesPath,
|
|
29
|
+
base: ((_a = opts.api.config.conventionRoutes) === null || _a === void 0 ? void 0 : _a.base) || opts.api.paths.absPagesPath,
|
|
30
|
+
exclude: (_b = opts.api.config.conventionRoutes) === null || _b === void 0 ? void 0 : _b.exclude,
|
|
29
31
|
prefix: '',
|
|
30
32
|
});
|
|
31
33
|
}
|
|
34
|
+
function localPath(path) {
|
|
35
|
+
if (path.charAt(0) !== '.') {
|
|
36
|
+
return `./${path}`;
|
|
37
|
+
}
|
|
38
|
+
{
|
|
39
|
+
return path;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
for (const id of Object.keys(routes)) {
|
|
43
|
+
if (routes[id].file) {
|
|
44
|
+
// TODO: cache for performance
|
|
45
|
+
const file = (0, path_1.isAbsolute)(routes[id].file)
|
|
46
|
+
? routes[id].file
|
|
47
|
+
: utils_1.resolve.sync(localPath(routes[id].file), {
|
|
48
|
+
basedir: ((_c = opts.api.config.conventionRoutes) === null || _c === void 0 ? void 0 : _c.base) ||
|
|
49
|
+
opts.api.paths.absPagesPath,
|
|
50
|
+
extensions: ['.js', '.jsx', '.tsx', '.ts'],
|
|
51
|
+
});
|
|
52
|
+
routes[id].__content = (0, fs_1.readFileSync)(file, 'utf-8');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// layout routes
|
|
32
56
|
const absLayoutPath = (0, path_1.join)(opts.api.paths.absSrcPath, 'layouts/index.tsx');
|
|
33
57
|
const layouts = yield opts.api.applyPlugins({
|
|
34
58
|
key: 'addLayouts',
|
|
@@ -49,6 +73,16 @@ function getRoutes(opts) {
|
|
|
49
73
|
parentId: undefined,
|
|
50
74
|
},
|
|
51
75
|
routes,
|
|
76
|
+
test: layout.test,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// patch routes
|
|
80
|
+
for (const id of Object.keys(routes)) {
|
|
81
|
+
yield opts.api.applyPlugins({
|
|
82
|
+
key: 'onPatchRoute',
|
|
83
|
+
args: {
|
|
84
|
+
route: routes[id],
|
|
85
|
+
},
|
|
52
86
|
});
|
|
53
87
|
}
|
|
54
88
|
routes = yield opts.api.applyPlugins({
|
|
@@ -64,8 +98,9 @@ function getRouteComponents(opts) {
|
|
|
64
98
|
const imports = Object.keys(opts.routes)
|
|
65
99
|
.map((key) => {
|
|
66
100
|
const route = opts.routes[key];
|
|
67
|
-
if (!route.file)
|
|
68
|
-
return
|
|
101
|
+
if (!route.file) {
|
|
102
|
+
return `'${key}': () => import('./EmptyRoute'),`;
|
|
103
|
+
}
|
|
69
104
|
// e.g.
|
|
70
105
|
// component: () => <h1>foo</h1>
|
|
71
106
|
// component: (() => () => <h1>foo</h1>)()
|
|
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const bundler_utils_1 = require("@umijs/bundler-utils");
|
|
12
13
|
const utils_1 = require("@umijs/utils");
|
|
13
14
|
const fs_1 = require("fs");
|
|
14
15
|
const path_1 = require("path");
|
|
@@ -25,6 +26,11 @@ exports.default = (api) => {
|
|
|
25
26
|
},
|
|
26
27
|
});
|
|
27
28
|
api.onGenerateFiles((opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
+
var _a;
|
|
30
|
+
const rendererPath = yield api.applyPlugins({
|
|
31
|
+
key: 'modifyRendererPath',
|
|
32
|
+
initialValue: (0, path_1.dirname)(require.resolve('@umijs/renderer-react/package.json')),
|
|
33
|
+
});
|
|
28
34
|
// umi.ts
|
|
29
35
|
api.writeTmpFile({
|
|
30
36
|
noPluginDir: true,
|
|
@@ -32,10 +38,7 @@ exports.default = (api) => {
|
|
|
32
38
|
tplPath: (0, path_1.join)(constants_1.TEMPLATES_DIR, 'umi.tpl'),
|
|
33
39
|
context: {
|
|
34
40
|
mountElementId: api.config.mountElementId,
|
|
35
|
-
rendererPath
|
|
36
|
-
key: 'modifyRendererPath',
|
|
37
|
-
initialValue: '@umijs/renderer-react',
|
|
38
|
-
}),
|
|
41
|
+
rendererPath,
|
|
39
42
|
entryCode: (yield api.applyPlugins({
|
|
40
43
|
key: 'addEntryCode',
|
|
41
44
|
initialValue: [],
|
|
@@ -57,8 +60,20 @@ exports.default = (api) => {
|
|
|
57
60
|
initialValue: [],
|
|
58
61
|
})).join('\n'),
|
|
59
62
|
basename: api.config.base,
|
|
63
|
+
historyType: api.config.history.type,
|
|
60
64
|
},
|
|
61
65
|
});
|
|
66
|
+
// EmptyRoutes.tsx
|
|
67
|
+
api.writeTmpFile({
|
|
68
|
+
noPluginDir: true,
|
|
69
|
+
path: 'core/EmptyRoute.tsx',
|
|
70
|
+
content: `
|
|
71
|
+
import { Outlet } from 'umi';
|
|
72
|
+
export default function EmptyRoute() {
|
|
73
|
+
return <Outlet />;
|
|
74
|
+
}
|
|
75
|
+
`,
|
|
76
|
+
});
|
|
62
77
|
// route.ts
|
|
63
78
|
let routes;
|
|
64
79
|
if (opts.isFirstTime) {
|
|
@@ -71,13 +86,22 @@ exports.default = (api) => {
|
|
|
71
86
|
}
|
|
72
87
|
const hasSrc = api.appData.hasSrcDir;
|
|
73
88
|
// @/pages/
|
|
74
|
-
const
|
|
89
|
+
const pages = (0, path_1.basename)(((_a = api.config.conventionRoutes) === null || _a === void 0 ? void 0 : _a.base) || api.paths.absPagesPath);
|
|
90
|
+
const prefix = hasSrc ? `../../../src/${pages}/` : `../../${pages}/`;
|
|
91
|
+
const clonedRoutes = utils_1.lodash.cloneDeep(routes);
|
|
92
|
+
for (const id of Object.keys(clonedRoutes)) {
|
|
93
|
+
for (const key of Object.keys(clonedRoutes[id])) {
|
|
94
|
+
if (key.startsWith('__')) {
|
|
95
|
+
delete clonedRoutes[id][key];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
75
99
|
api.writeTmpFile({
|
|
76
100
|
noPluginDir: true,
|
|
77
101
|
path: 'core/route.tsx',
|
|
78
102
|
tplPath: (0, path_1.join)(constants_1.TEMPLATES_DIR, 'route.tpl'),
|
|
79
103
|
context: {
|
|
80
|
-
routes: JSON.stringify(
|
|
104
|
+
routes: JSON.stringify(clonedRoutes),
|
|
81
105
|
routeComponents: yield (0, routes_1.getRouteComponents)({ routes, prefix }),
|
|
82
106
|
},
|
|
83
107
|
});
|
|
@@ -111,7 +135,7 @@ exports.default = (api) => {
|
|
|
111
135
|
'dataflowProvider',
|
|
112
136
|
'outerProvider',
|
|
113
137
|
'render',
|
|
114
|
-
|
|
138
|
+
'onRouteChange',
|
|
115
139
|
],
|
|
116
140
|
});
|
|
117
141
|
api.writeTmpFile({
|
|
@@ -126,5 +150,73 @@ exports.default = (api) => {
|
|
|
126
150
|
validKeys: validKeys,
|
|
127
151
|
},
|
|
128
152
|
});
|
|
153
|
+
// history.ts
|
|
154
|
+
api.writeTmpFile({
|
|
155
|
+
noPluginDir: true,
|
|
156
|
+
path: 'core/history.ts',
|
|
157
|
+
tplPath: (0, path_1.join)(constants_1.TEMPLATES_DIR, 'history.tpl'),
|
|
158
|
+
context: {
|
|
159
|
+
rendererPath,
|
|
160
|
+
},
|
|
161
|
+
});
|
|
129
162
|
}));
|
|
163
|
+
function getExports(opts) {
|
|
164
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
165
|
+
const content = (0, fs_1.readFileSync)(opts.path, 'utf-8');
|
|
166
|
+
const [_, exports] = yield (0, bundler_utils_1.parseModule)({ content, path: opts.path });
|
|
167
|
+
return exports || [];
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
// Generate @@/exports.ts
|
|
171
|
+
api.register({
|
|
172
|
+
key: 'onGenerateFiles',
|
|
173
|
+
fn: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
174
|
+
const exports = [];
|
|
175
|
+
// @umijs/renderer-react
|
|
176
|
+
exports.push('// @umijs/renderer-react');
|
|
177
|
+
const rendererReactPath = (0, path_1.dirname)(require.resolve('@umijs/renderer-react/package.json'));
|
|
178
|
+
exports.push(`export { ${(yield getExports({
|
|
179
|
+
path: (0, path_1.join)(rendererReactPath, 'dist/index.js'),
|
|
180
|
+
})).join(', ')} } from '${rendererReactPath}';`);
|
|
181
|
+
// umi/client/client/plugin
|
|
182
|
+
exports.push('// umi/client/client/plugin');
|
|
183
|
+
const umiDir = process.env.UMI_DIR;
|
|
184
|
+
const umiPluginPath = (0, path_1.join)(umiDir, 'client/client/plugin.js');
|
|
185
|
+
exports.push(`export { ${(yield getExports({
|
|
186
|
+
path: umiPluginPath,
|
|
187
|
+
})).join(', ')} } from '${umiPluginPath}';`);
|
|
188
|
+
// @@/core/history.ts
|
|
189
|
+
exports.push(`export { history, createHistory } from './core/history';`);
|
|
190
|
+
// plugins
|
|
191
|
+
exports.push('// plugins');
|
|
192
|
+
const plugins = (0, fs_1.readdirSync)(api.paths.absTmpPath).filter((file) => {
|
|
193
|
+
if (file.startsWith('plugin-') &&
|
|
194
|
+
((0, fs_1.existsSync)((0, path_1.join)(api.paths.absTmpPath, file, 'index.ts')) ||
|
|
195
|
+
(0, fs_1.existsSync)((0, path_1.join)(api.paths.absTmpPath, file, 'index.tsx')))) {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
for (const plugin of plugins) {
|
|
200
|
+
let file;
|
|
201
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(api.paths.absTmpPath, plugin, 'index.ts'))) {
|
|
202
|
+
file = (0, path_1.join)(api.paths.absTmpPath, plugin, 'index.ts');
|
|
203
|
+
}
|
|
204
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(api.paths.absTmpPath, plugin, 'index.tsx'))) {
|
|
205
|
+
file = (0, path_1.join)(api.paths.absTmpPath, plugin, 'index.tsx');
|
|
206
|
+
}
|
|
207
|
+
const pluginExports = yield getExports({
|
|
208
|
+
path: file,
|
|
209
|
+
});
|
|
210
|
+
if (pluginExports.length) {
|
|
211
|
+
exports.push(`export { ${pluginExports.join(', ')} } from '${(0, path_1.join)(api.paths.absTmpPath, plugin)}';`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
api.writeTmpFile({
|
|
215
|
+
noPluginDir: true,
|
|
216
|
+
path: 'exports.ts',
|
|
217
|
+
content: exports.join('\n'),
|
|
218
|
+
});
|
|
219
|
+
}),
|
|
220
|
+
stage: Infinity,
|
|
221
|
+
});
|
|
130
222
|
};
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.default = (api) => {
|
|
13
|
+
// scan deps into api.appData by default for vite mode
|
|
14
|
+
api.register({
|
|
15
|
+
key: 'onBeforeCompiler',
|
|
16
|
+
stage: Number.POSITIVE_INFINITY,
|
|
17
|
+
fn() {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
yield api.applyPlugins({
|
|
20
|
+
key: 'updateAppDataDeps',
|
|
21
|
+
type: api.ApplyPluginsType.event,
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
// include extra monorepo package deps for vite pre-bundle
|
|
27
|
+
api.modifyViteConfig((memo) => {
|
|
28
|
+
var _a, _b;
|
|
29
|
+
memo.optimizeDeps = Object.assign(Object.assign({}, (memo.optimizeDeps || {})), { include: (_b = (_a = memo.optimizeDeps) === null || _a === void 0 ? void 0 : _a.include) === null || _b === void 0 ? void 0 : _b.concat(Object.values(api.appData.deps)
|
|
30
|
+
.map(({ matches }) => matches[0])
|
|
31
|
+
.filter((item) => (item === null || item === void 0 ? void 0 : item.startsWith('@fs')) && !(item === null || item === void 0 ? void 0 : item.includes('node_modules')))) });
|
|
32
|
+
return memo;
|
|
33
|
+
});
|
|
34
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -13,9 +13,11 @@ exports.default = () => {
|
|
|
13
13
|
require.resolve('./features/favicon/favicon'),
|
|
14
14
|
require.resolve('./features/mock/mock'),
|
|
15
15
|
require.resolve('./features/polyfill/polyfill'),
|
|
16
|
+
require.resolve('./features/polyfill/publicPathPolyfill'),
|
|
16
17
|
require.resolve('./features/tmpFiles/tmpFiles'),
|
|
17
18
|
require.resolve('./features/transform/transform'),
|
|
18
19
|
require.resolve('./features/lowImport/lowImport'),
|
|
20
|
+
require.resolve('./features/vite/vite'),
|
|
19
21
|
// commands
|
|
20
22
|
require.resolve('./commands/build'),
|
|
21
23
|
require.resolve('./commands/config/config'),
|
package/dist/libs/scan.d.ts
CHANGED
package/dist/libs/scan.js
CHANGED
|
@@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.scan = exports.createResolver = exports.getContent = exports.scanContent = void 0;
|
|
16
|
+
const bundler_utils_1 = require("@umijs/bundler-utils");
|
|
16
17
|
const es_module_lexer_1 = require("@umijs/bundler-utils/compiled/es-module-lexer");
|
|
17
18
|
const esbuild_1 = require("@umijs/bundler-utils/compiled/esbuild");
|
|
18
19
|
const utils_1 = require("@umijs/utils");
|
|
@@ -31,7 +32,22 @@ function scanContent(opts) {
|
|
|
31
32
|
return __awaiter(this, void 0, void 0, function* () {
|
|
32
33
|
yield es_module_lexer_1.init;
|
|
33
34
|
const [imports] = (0, es_module_lexer_1.parse)(opts.content);
|
|
34
|
-
const deps = imports
|
|
35
|
+
const deps = imports
|
|
36
|
+
.filter(
|
|
37
|
+
// exclude all type-only deps
|
|
38
|
+
(imp) => {
|
|
39
|
+
const stmt = opts.content.slice(imp.ss, imp.se);
|
|
40
|
+
return (
|
|
41
|
+
// skip dynamicImport
|
|
42
|
+
imp.d > -1 ||
|
|
43
|
+
// import a from or import a,
|
|
44
|
+
/^import\s+[a-zA-Z_$][\w_$]*(\s+from|\s*,)/.test(stmt) ||
|
|
45
|
+
// export a from or export *
|
|
46
|
+
/^export\s+([a-zA-Z_$][\w_$]*\s+from|\*)/.test(stmt) ||
|
|
47
|
+
// { a, type b } or { type a, b }
|
|
48
|
+
/(?<!type\s+){(\s*(?!type)[a-zA-Z_$]|.*,\s*(?!type)[a-zA-Z_$])/.test(stmt));
|
|
49
|
+
})
|
|
50
|
+
.map((imp) => {
|
|
35
51
|
let importType = ImportType.import;
|
|
36
52
|
if (imp.d > -1)
|
|
37
53
|
importType = ImportType.dynamicImport;
|
|
@@ -79,6 +95,7 @@ function createResolver(opts) {
|
|
|
79
95
|
}
|
|
80
96
|
exports.createResolver = createResolver;
|
|
81
97
|
function scan(opts) {
|
|
98
|
+
var _a, _b;
|
|
82
99
|
return __awaiter(this, void 0, void 0, function* () {
|
|
83
100
|
const cache = new Map();
|
|
84
101
|
const queueDeps = [opts.entry];
|
|
@@ -93,12 +110,49 @@ function scan(opts) {
|
|
|
93
110
|
cache.set(depPath, deps);
|
|
94
111
|
for (const dep of deps) {
|
|
95
112
|
const resolved = yield opts.resolver.resolve((0, path_1.dirname)(depPath), dep.url);
|
|
96
|
-
if (
|
|
97
|
-
resolved.includes('umi-next/packages')) {
|
|
113
|
+
if ((0, bundler_utils_1.isDepPath)(resolved)) {
|
|
98
114
|
const pkgPath = utils_1.pkgUp.sync({ cwd: resolved });
|
|
99
115
|
(0, assert_1.default)(pkgPath, `package.json for found for ${resolved}`);
|
|
100
116
|
const pkg = require(pkgPath);
|
|
101
|
-
|
|
117
|
+
const entryResolved = yield opts.resolver
|
|
118
|
+
.resolve((0, path_1.dirname)(pkgPath), '.')
|
|
119
|
+
// alias may resolve error (eg: dva from @umijs/plugins)
|
|
120
|
+
// fallback to null for mark it as subpath usage
|
|
121
|
+
.catch(() => null);
|
|
122
|
+
const isSubpath = entryResolved !== resolved;
|
|
123
|
+
ret[pkg.name] = {
|
|
124
|
+
version: pkg.version,
|
|
125
|
+
// collect entry matches
|
|
126
|
+
matches: [
|
|
127
|
+
// avoid duplicate
|
|
128
|
+
...new Set([
|
|
129
|
+
...(((_a = ret[pkg.name]) === null || _a === void 0 ? void 0 : _a.matches) || []),
|
|
130
|
+
// only collect non-subpath matches
|
|
131
|
+
...(!isSubpath
|
|
132
|
+
? [
|
|
133
|
+
// match origin path from source code
|
|
134
|
+
dep.url,
|
|
135
|
+
// match resolved absolute path
|
|
136
|
+
resolved,
|
|
137
|
+
// match no ext name path
|
|
138
|
+
resolved.replace(/\/\.[^\.]+$/, ''),
|
|
139
|
+
// match parent dir for index module
|
|
140
|
+
...(/\/index[^\/]+$/.test(resolved)
|
|
141
|
+
? [(0, path_1.dirname)(resolved)]
|
|
142
|
+
: []),
|
|
143
|
+
]
|
|
144
|
+
: []),
|
|
145
|
+
]),
|
|
146
|
+
],
|
|
147
|
+
// collect subpath matches
|
|
148
|
+
subpaths: [
|
|
149
|
+
// avoid duplicate
|
|
150
|
+
...new Set([
|
|
151
|
+
...(((_b = ret[pkg.name]) === null || _b === void 0 ? void 0 : _b.subpaths) || []),
|
|
152
|
+
...(isSubpath ? [dep.url] : []),
|
|
153
|
+
]),
|
|
154
|
+
],
|
|
155
|
+
};
|
|
102
156
|
}
|
|
103
157
|
else if (['.ts', '.tsx', '.js', '.jsx', '.mjs'].includes((0, path_1.extname)(resolved))) {
|
|
104
158
|
queueDeps.push(resolved);
|
package/dist/registerMethods.js
CHANGED
|
@@ -7,14 +7,14 @@ const utils_1 = require("@umijs/utils");
|
|
|
7
7
|
const assert_1 = __importDefault(require("assert"));
|
|
8
8
|
const fs_1 = require("fs");
|
|
9
9
|
const path_1 = require("path");
|
|
10
|
-
const transformIEAR_1 = __importDefault(require("./utils/transformIEAR"));
|
|
11
10
|
const isTypeScriptFile_1 = require("./utils/isTypeScriptFile");
|
|
11
|
+
const transformIEAR_1 = __importDefault(require("./utils/transformIEAR"));
|
|
12
12
|
exports.default = (api) => {
|
|
13
13
|
[
|
|
14
14
|
'onGenerateFiles',
|
|
15
15
|
'onBeforeCompiler',
|
|
16
16
|
'onBuildComplete',
|
|
17
|
-
|
|
17
|
+
'onPatchRoute',
|
|
18
18
|
// 'onPatchRouteBefore',
|
|
19
19
|
// 'onPatchRoutes',
|
|
20
20
|
// 'onPatchRoutesBefore',
|
package/dist/types.d.ts
CHANGED
|
@@ -101,6 +101,9 @@ export declare type IApi = PluginAPI & IServicePluginAPI & {
|
|
|
101
101
|
stats: any;
|
|
102
102
|
time: number;
|
|
103
103
|
}>;
|
|
104
|
+
onPatchRoute: IEvent<{
|
|
105
|
+
route: IRoute;
|
|
106
|
+
}>;
|
|
104
107
|
addEntryImports: IAdd<null, IEntryImport[]>;
|
|
105
108
|
addEntryImportsAhead: IAdd<null, IEntryImport[]>;
|
|
106
109
|
addEntryCodeAhead: IAdd<null, string[]>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.IEAR_REG_EXP = void 0;
|
|
4
|
+
const bundler_utils_1 = require("@umijs/bundler-utils");
|
|
4
5
|
const utils_1 = require("@umijs/utils");
|
|
5
6
|
const path_1 = require("path");
|
|
6
7
|
/**
|
|
@@ -84,10 +85,14 @@ function transformIEAR({ content, path }, api) {
|
|
|
84
85
|
return content.replace(exports.IEAR_REG_EXP, (_, prefix, quote, absPath) => {
|
|
85
86
|
if (absPath.startsWith(api.paths.absTmpPath)) {
|
|
86
87
|
// transform .umi absolute imports
|
|
87
|
-
absPath = (0, utils_1.winPath)((0, path_1.relative)((0, path_1.dirname)(path), absPath))
|
|
88
|
+
absPath = (0, utils_1.winPath)((0, path_1.relative)((0, path_1.dirname)(path), absPath)).replace(
|
|
89
|
+
// prepend ./ for same or sub level imports
|
|
90
|
+
/^(?!\.\.\/)/, './');
|
|
88
91
|
}
|
|
89
|
-
else if (
|
|
92
|
+
else if ((0, bundler_utils_1.isDepPath)(absPath)) {
|
|
90
93
|
// transform node_modules absolute imports
|
|
94
|
+
// why @fs
|
|
95
|
+
// 由于我们临时文件下大量绝对路径的引用,而绝对路径的引用不会被 Vite 预编译
|
|
91
96
|
absPath = `@fs${absPath}`;
|
|
92
97
|
}
|
|
93
98
|
return `${prefix}${quote}${absPath}${quote}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umijs/preset-umi",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.18",
|
|
4
4
|
"description": "@umijs/preset-umi",
|
|
5
5
|
"homepage": "https://github.com/umijs/umi-next/tree/master/packages/preset-umi#readme",
|
|
6
6
|
"bugs": "https://github.com/umijs/umi-next/issues",
|
|
@@ -24,21 +24,22 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@types/multer": "1.4.7",
|
|
27
|
-
"@umijs/ast": "4.0.0-beta.
|
|
28
|
-
"@umijs/babel-preset-umi": "4.0.0-beta.
|
|
29
|
-
"@umijs/bundler-utils": "4.0.0-beta.
|
|
30
|
-
"@umijs/bundler-vite": "4.0.0-beta.
|
|
31
|
-
"@umijs/bundler-webpack": "4.0.0-beta.
|
|
32
|
-
"@umijs/core": "4.0.0-beta.
|
|
33
|
-
"@umijs/renderer-react": "4.0.0-beta.
|
|
34
|
-
"@umijs/server": "4.0.0-beta.
|
|
35
|
-
"@umijs/utils": "4.0.0-beta.
|
|
27
|
+
"@umijs/ast": "4.0.0-beta.18",
|
|
28
|
+
"@umijs/babel-preset-umi": "4.0.0-beta.18",
|
|
29
|
+
"@umijs/bundler-utils": "4.0.0-beta.18",
|
|
30
|
+
"@umijs/bundler-vite": "4.0.0-beta.18",
|
|
31
|
+
"@umijs/bundler-webpack": "4.0.0-beta.18",
|
|
32
|
+
"@umijs/core": "4.0.0-beta.18",
|
|
33
|
+
"@umijs/renderer-react": "4.0.0-beta.18",
|
|
34
|
+
"@umijs/server": "4.0.0-beta.18",
|
|
35
|
+
"@umijs/utils": "4.0.0-beta.18",
|
|
36
|
+
"core-js": "3.19.2",
|
|
36
37
|
"current-script-polyfill": "1.0.0",
|
|
37
38
|
"enhanced-resolve": "5.8.3",
|
|
38
39
|
"magic-string": "0.25.7",
|
|
39
40
|
"path-to-regexp": "1.7.0",
|
|
40
|
-
"react": "
|
|
41
|
-
"react-dom": "
|
|
41
|
+
"react": "17.0.2",
|
|
42
|
+
"react-dom": "17.0.2",
|
|
42
43
|
"react-router": "6.1.1",
|
|
43
44
|
"react-router-dom": "6.1.1"
|
|
44
45
|
},
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createHashHistory, createMemoryHistory, createBrowserHistory, History } from '{{{ rendererPath }}}';
|
|
2
|
+
|
|
3
|
+
let history: History;
|
|
4
|
+
export function createHistory(opts: any) {
|
|
5
|
+
if (opts.type === 'hash') {
|
|
6
|
+
history = createHashHistory();
|
|
7
|
+
} else if (opts.type === 'memory') {
|
|
8
|
+
history = createMemoryHistory();
|
|
9
|
+
} else {
|
|
10
|
+
history = createBrowserHistory();
|
|
11
|
+
}
|
|
12
|
+
return history;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { history };
|
package/templates/umi.tpl
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { renderClient } from '{{{ rendererPath }}}';
|
|
4
4
|
import { getRoutes } from './core/route';
|
|
5
5
|
import { createPluginManager } from './core/plugin';
|
|
6
|
+
import { createHistory } from './core/history';
|
|
6
7
|
import { ApplyPluginsType, PluginManager } from 'umi';
|
|
7
8
|
{{{ imports }}}
|
|
8
9
|
|
|
@@ -24,6 +25,9 @@ async function render() {
|
|
|
24
25
|
routeComponents,
|
|
25
26
|
pluginManager,
|
|
26
27
|
rootElement: document.getElementById('{{{ mountElementId }}}'),
|
|
28
|
+
history: createHistory({
|
|
29
|
+
type: '{{{ historyType }}}',
|
|
30
|
+
}),
|
|
27
31
|
{{#basename}}
|
|
28
32
|
basename: '{{{ basename }}}',
|
|
29
33
|
{{/basename}}
|