@umijs/preset-umi 4.0.35 → 4.0.37

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.
@@ -264,7 +264,7 @@ PORT=8888 umi dev
264
264
  beforeMiddlewares: [].concat([
265
265
  ...beforeMiddlewares
266
266
  ]),
267
- afterMiddlewares: enableVite ? [] : middlewares.concat([
267
+ afterMiddlewares: enableVite ? [middlewares.concat(import_faviconMiddleware.faviconMiddleware)] : middlewares.concat([
268
268
  ...api.config.mpa ? [] : [(0, import_createRouteMiddleware.createRouteMiddleware)({ api })],
269
269
  import_faviconMiddleware.faviconMiddleware
270
270
  ]),
@@ -327,18 +327,24 @@ PORT=8888 umi dev
327
327
  memo.ip = import_utils.address.ip();
328
328
  return memo;
329
329
  });
330
+ const restartServer = () => {
331
+ var _a;
332
+ import_utils.logger.info(`Restart dev server with port ${api.appData.port}...`);
333
+ (0, import_watch.unwatch)();
334
+ (_a = process.send) == null ? void 0 : _a.call(process, {
335
+ type: "RESTART",
336
+ payload: {
337
+ port: api.appData.port
338
+ }
339
+ });
340
+ };
341
+ process.on("UMI_RESTART_SERVER", () => {
342
+ restartServer();
343
+ });
330
344
  api.registerMethod({
331
345
  name: "restartServer",
332
346
  fn() {
333
- var _a;
334
- import_utils.logger.info(`Restart dev server with port ${api.appData.port}...`);
335
- (0, import_watch.unwatch)();
336
- (_a = process.send) == null ? void 0 : _a.call(process, {
337
- type: "RESTART",
338
- payload: {
339
- port: api.appData.port
340
- }
341
- });
347
+ restartServer();
342
348
  }
343
349
  });
344
350
  api.modifyViteConfig((viteConfig) => {
@@ -1,5 +1,5 @@
1
- import { generateFile } from '@umijs/utils';
2
1
  import { IApi } from '../../types';
2
+ import { type IArgsComponent } from './utils';
3
3
  declare const _default: (api: IApi) => void;
4
4
  export default _default;
5
5
  export declare class ComponentGenerator {
@@ -7,7 +7,7 @@ export declare class ComponentGenerator {
7
7
  componentName: string;
8
8
  srcPath: string;
9
9
  appRoot: string;
10
- generateFile: typeof generateFile;
10
+ args: IArgsComponent;
11
11
  };
12
12
  private readonly name;
13
13
  private readonly dir;
@@ -15,7 +15,7 @@ export declare class ComponentGenerator {
15
15
  componentName: string;
16
16
  srcPath: string;
17
17
  appRoot: string;
18
- generateFile: typeof generateFile;
18
+ args: IArgsComponent;
19
19
  });
20
20
  run(): Promise<void>;
21
21
  }
@@ -38,9 +38,13 @@ var component_default = (api) => {
38
38
  description: "Generate component boilerplate code",
39
39
  type: import_core.GeneratorType.generate,
40
40
  fn: async (options) => {
41
+ const { args } = options;
42
+ if (args.eject) {
43
+ await (0, import_utils2.tryEject)(import_utils2.ETempDir.Component, api.paths.cwd);
44
+ return;
45
+ }
41
46
  const h = new import_utils2.GeneratorHelper(api);
42
- options.generateFile;
43
- let componentNames = options.args._.slice(1);
47
+ let componentNames = args._.slice(1);
44
48
  if (componentNames.length === 0) {
45
49
  let name = "";
46
50
  name = await h.ensureVariableWithQuestion(name, {
@@ -56,8 +60,8 @@ var component_default = (api) => {
56
60
  await new ComponentGenerator({
57
61
  srcPath: api.paths.absSrcPath,
58
62
  appRoot: api.paths.cwd,
59
- generateFile: import_utils.generateFile,
60
- componentName: cn
63
+ componentName: cn,
64
+ args
61
65
  }).run();
62
66
  }
63
67
  }
@@ -71,27 +75,41 @@ var ComponentGenerator = class {
71
75
  this.dir = dir;
72
76
  }
73
77
  async run() {
74
- const { generateFile: generateFile2, appRoot } = this.opts;
78
+ const { appRoot, args } = this.opts;
75
79
  const capitalizeName = import_utils.lodash.upperFirst(this.name);
76
80
  const base = (0, import_path.join)(this.opts.srcPath, "components", this.dir, capitalizeName);
81
+ const { _, eject: _eject, fallback, ...restArgs } = args;
77
82
  const indexFile = (0, import_path.join)(base, "index.ts");
78
83
  const compFile = (0, import_path.join)(base, `${capitalizeName}.tsx`);
79
- await generateFile2({
80
- target: indexFile,
81
- path: INDEX_TPL,
82
- baseDir: appRoot,
83
- data: { compName: capitalizeName }
84
- });
85
- await generateFile2({
86
- target: compFile,
87
- path: COMP_TPL,
84
+ await (0, import_utils2.processGenerateFiles)({
85
+ filesMap: [
86
+ {
87
+ from: (0, import_path.join)(appRoot, USER_TEMPLATE_COMP_DIR, "index"),
88
+ fromFallback: INDEX_TPL,
89
+ to: indexFile,
90
+ exts: [".ts.tpl", ".ts", "tsx.tpl", "tsx"]
91
+ },
92
+ {
93
+ from: (0, import_path.join)(appRoot, USER_TEMPLATE_COMP_DIR, "component"),
94
+ fromFallback: COMP_TPL,
95
+ to: compFile,
96
+ exts: [".tsx.tpl", ".tsx"]
97
+ }
98
+ ],
88
99
  baseDir: appRoot,
89
- data: { compName: capitalizeName }
100
+ presetArgs: {
101
+ fallback
102
+ },
103
+ templateVars: {
104
+ compName: capitalizeName,
105
+ ...restArgs
106
+ }
90
107
  });
91
108
  }
92
109
  };
93
110
  var INDEX_TPL = (0, import_path.join)(import_constants.TEMPLATES_DIR, "generate/component/index.ts.tpl");
94
111
  var COMP_TPL = (0, import_path.join)(import_constants.TEMPLATES_DIR, "generate/component/component.tsx.tpl");
112
+ var USER_TEMPLATE_COMP_DIR = "templates/component";
95
113
  // Annotate the CommonJS export names for ESM import in node:
96
114
  0 && (module.exports = {
97
115
  ComponentGenerator
@@ -63,7 +63,7 @@ var jest_default = (api) => {
63
63
  "@types/testing-library__jest-dom": "^5.14.5"
64
64
  } : basicDeps;
65
65
  h.addDevDeps(packageToInstall);
66
- h.addScript("test", "jest");
66
+ h.addScript("test", "TS_NODE_TRANSPILE_ONLY=yes jest --passWithNoTests");
67
67
  const setupImports = res.willUseTLR ? [
68
68
  `import '@testing-library/jest-dom';`,
69
69
  `import '${api.appData.umi.importSource}/test-setup'`
@@ -92,20 +92,26 @@ var jest_default = (api) => {
92
92
  import { Config, configUmiAlias, createConfig } from '${importSource}/test';
93
93
 
94
94
  export default async () => {
95
- return (await configUmiAlias({
96
- ...createConfig({
97
- target: 'browser',
98
- jsTransformer: 'esbuild',
99
- // config opts for esbuild , it will pass to esbuild directly
100
- jsTransformerOpts: { jsx: 'automatic' },
101
- }),
102
- ${res.willUseTLR ? `setupFilesAfterEnv: ['<rootDir>/jest-setup.ts'],` : ""}
103
- collectCoverageFrom: [
104
- ${collectCoverageFrom.map((v) => ` '${v}'`).join(",\n")}
105
- ],
106
- // if you require some es-module npm package, please uncomment below line and insert your package name
107
- // transformIgnorePatterns: ['node_modules/(?!.*(lodash-es|your-es-pkg-name)/)']
108
- })) as Config.InitialOptions;
95
+ try{
96
+ return (await configUmiAlias({
97
+ ...createConfig({
98
+ target: 'browser',
99
+ jsTransformer: 'esbuild',
100
+ // config opts for esbuild , it will pass to esbuild directly
101
+ jsTransformerOpts: { jsx: 'automatic' },
102
+ }),
103
+
104
+ ${res.willUseTLR ? `setupFilesAfterEnv: ['<rootDir>/jest-setup.ts'],` : ""}
105
+ collectCoverageFrom: [
106
+ ${collectCoverageFrom.map((v) => ` '${v}'`).join(",\n")}
107
+ ],
108
+ // if you require some es-module npm package, please uncomment below line and insert your package name
109
+ // transformIgnorePatterns: ['node_modules/(?!.*(lodash-es|your-es-pkg-name)/)']
110
+ })) as Config.InitialOptions;
111
+ }catch(e){
112
+ console.log(e);
113
+ throw e;
114
+ }
109
115
  };
110
116
  `.trimLeft());
111
117
  import_utils.logger.info("Write jest.config.ts");
@@ -1,11 +1,11 @@
1
- import { generateFile, prompts } from '@umijs/utils';
1
+ import { prompts } from '@umijs/utils';
2
2
  import { IApi } from '../../types';
3
+ import { type IArgsPage } from './utils';
3
4
  declare const _default: (api: IApi) => void;
4
5
  export default _default;
5
6
  export declare class PageGenerator {
6
7
  readonly options: {
7
- args: any;
8
- generateFile: typeof generateFile;
8
+ args: IArgsPage;
9
9
  absPagesPath: string;
10
10
  appCwd: string;
11
11
  };
@@ -16,8 +16,7 @@ export declare class PageGenerator {
16
16
  private prompts;
17
17
  private paths;
18
18
  constructor(options: {
19
- args: any;
20
- generateFile: typeof generateFile;
19
+ args: IArgsPage;
21
20
  absPagesPath: string;
22
21
  appCwd: string;
23
22
  });
@@ -38,18 +38,22 @@ var page_default = (api) => {
38
38
  description: "Create a umi page by page name",
39
39
  type: import_core.GeneratorType.generate,
40
40
  fn: async (options) => {
41
+ const { args } = options;
42
+ if (args.eject) {
43
+ await (0, import_utils2.tryEject)(import_utils2.ETempDir.Page, api.paths.cwd);
44
+ return;
45
+ }
41
46
  return new PageGenerator({
42
- generateFile: options.generateFile,
43
- args: options.args,
47
+ args,
44
48
  absPagesPath: api.paths.absPagesPath,
45
49
  appCwd: api.paths.cwd
46
50
  }).run();
47
51
  }
48
52
  });
49
53
  };
50
- var INDEX_TPL_PATH = (0, import_path.join)(import_constants.TEMPLATES_DIR, "generate/page/index.tsx.tpl");
51
- var LEES_TPL_PATH = (0, import_path.join)(import_constants.TEMPLATES_DIR, "generate/page/index.less.tpl");
54
+ var PAGE_TEMPLATE_DIR = (0, import_path.join)(import_constants.TEMPLATES_DIR, "generate/page/");
52
55
  var DEFAULT_PAGE_NAME = "unTitledPage";
56
+ var USER_TEMPLATE_PAGE_DIR = "templates/page";
53
57
  var PageGenerator = class {
54
58
  constructor(options) {
55
59
  this.options = options;
@@ -59,7 +63,7 @@ var PageGenerator = class {
59
63
  this.needEnsureDirMode = false;
60
64
  this.prompts = import_utils2.promptsExitWhenCancel;
61
65
  this.paths = [];
62
- this.isDirMode = options.args.dir;
66
+ this.isDirMode = !!options.args.dir;
63
67
  const [_, ...inputPaths] = options.args._;
64
68
  if (inputPaths.length > 0) {
65
69
  this.paths = inputPaths;
@@ -144,36 +148,56 @@ var PageGenerator = class {
144
148
  return `${base}.{tsx,less}`;
145
149
  }
146
150
  async fileModeRun() {
147
- const { generateFile: generateFile2, absPagesPath } = this.options;
148
- const data = {
149
- color: (0, import_utils.randomColor)(),
150
- name: this.name,
151
- cssExt: ".less"
152
- };
153
- await generateFile2({
154
- path: INDEX_TPL_PATH,
155
- target: (0, import_path.join)(absPagesPath, this.dir, `${this.name}.tsx`),
156
- baseDir: this.options.appCwd,
157
- data
158
- });
159
- await generateFile2({
160
- path: LEES_TPL_PATH,
161
- target: (0, import_path.join)(absPagesPath, this.dir, `${this.name}.less`),
151
+ const { absPagesPath, args, appCwd } = this.options;
152
+ const { _, dir: _dir, eject: _eject, fallback, ...restVars } = args;
153
+ await (0, import_utils2.processGenerateFiles)({
154
+ filesMap: [
155
+ {
156
+ from: (0, import_path.join)(appCwd, USER_TEMPLATE_PAGE_DIR, "index"),
157
+ fromFallback: (0, import_path.join)(PAGE_TEMPLATE_DIR, "index.tsx.tpl"),
158
+ to: (0, import_path.join)(absPagesPath, this.dir, `${this.name}.tsx`),
159
+ exts: [".tsx.tpl", ".tsx"]
160
+ },
161
+ {
162
+ from: (0, import_path.join)(appCwd, USER_TEMPLATE_PAGE_DIR, "index"),
163
+ fromFallback: (0, import_path.join)(PAGE_TEMPLATE_DIR, "index.less.tpl"),
164
+ to: (0, import_path.join)(absPagesPath, this.dir, `${this.name}.less`),
165
+ exts: [".less.tpl", ".less"]
166
+ }
167
+ ],
162
168
  baseDir: this.options.appCwd,
163
- data
169
+ presetArgs: {
170
+ fallback
171
+ },
172
+ templateVars: {
173
+ color: (0, import_utils.randomColor)(),
174
+ name: this.name,
175
+ cssExt: ".less",
176
+ ...restVars
177
+ }
164
178
  });
165
179
  }
166
180
  async dirModeRun() {
167
- const { generateFile: generateFile2, absPagesPath } = this.options;
168
- await generateFile2({
169
- path: (0, import_path.join)(__dirname, "../../../templates/generate/page"),
170
- target: (0, import_path.join)(absPagesPath, this.dir, this.name),
171
- data: {
181
+ const { absPagesPath, args, appCwd } = this.options;
182
+ const { _, dir: _dir, eject: _eject, fallback, ...restVars } = args;
183
+ await (0, import_utils2.processGenerateFiles)({
184
+ filesMap: [
185
+ {
186
+ from: (0, import_path.join)(appCwd, USER_TEMPLATE_PAGE_DIR),
187
+ fromFallback: PAGE_TEMPLATE_DIR,
188
+ to: (0, import_path.join)(absPagesPath, this.dir, this.name)
189
+ }
190
+ ],
191
+ baseDir: appCwd,
192
+ presetArgs: {
193
+ fallback
194
+ },
195
+ templateVars: {
172
196
  color: (0, import_utils.randomColor)(),
173
197
  name: "index",
174
- cssExt: ".less"
175
- },
176
- baseDir: this.options.appCwd
198
+ cssExt: ".less",
199
+ ...restVars
200
+ }
177
201
  });
178
202
  }
179
203
  };
@@ -1,5 +1,15 @@
1
1
  import { prompts } from '@umijs/utils';
2
2
  import { IApi } from '../../types';
3
+ export interface IArgsBase {
4
+ fallback?: boolean;
5
+ eject?: boolean;
6
+ _: string[];
7
+ }
8
+ export interface IArgsPage extends IArgsBase {
9
+ dir?: boolean;
10
+ }
11
+ export interface IArgsComponent extends IArgsBase {
12
+ }
3
13
  export declare function checkStatus({ pkg }: {
4
14
  pkg: any;
5
15
  }): {
@@ -26,3 +36,23 @@ export declare class GeneratorHelper {
26
36
  export declare function getUmiJsPlugin(): any;
27
37
  export declare function promptsExitWhenCancel<T extends string = string>(questions: prompts.PromptObject<T> | Array<prompts.PromptObject<T>>, options?: Pick<prompts.Options, 'onSubmit'>): Promise<prompts.Answers<T>>;
28
38
  export declare function trim(s?: string): string;
39
+ interface IFile {
40
+ from: string;
41
+ fromFallback: string;
42
+ to: string;
43
+ exts?: string[];
44
+ }
45
+ export declare enum ETempDir {
46
+ Page = "page",
47
+ Component = "component"
48
+ }
49
+ export declare function processGenerateFiles({ filesMap, baseDir, presetArgs, templateVars, }: {
50
+ filesMap: IFile[];
51
+ baseDir: string;
52
+ presetArgs?: {
53
+ fallback?: boolean;
54
+ };
55
+ templateVars: Record<string, any>;
56
+ }): Promise<void>;
57
+ export declare function tryEject(dir: ETempDir, baseDir: string): Promise<void>;
58
+ export {};
@@ -19,11 +19,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  // src/commands/generators/utils.ts
20
20
  var utils_exports = {};
21
21
  __export(utils_exports, {
22
+ ETempDir: () => ETempDir,
22
23
  GeneratorHelper: () => GeneratorHelper,
23
24
  checkStatus: () => checkStatus,
24
25
  getUmiJsPlugin: () => getUmiJsPlugin,
26
+ processGenerateFiles: () => processGenerateFiles,
25
27
  promptsExitWhenCancel: () => promptsExitWhenCancel,
26
- trim: () => trim
28
+ trim: () => trim,
29
+ tryEject: () => tryEject
27
30
  });
28
31
  module.exports = __toCommonJS(utils_exports);
29
32
  var import_utils = require("@umijs/utils");
@@ -159,11 +162,86 @@ function promptsExitWhenCancel(questions, options) {
159
162
  function trim(s) {
160
163
  return (s == null ? void 0 : s.trim()) || "";
161
164
  }
165
+ var ETempDir = /* @__PURE__ */ ((ETempDir2) => {
166
+ ETempDir2["Page"] = "page";
167
+ ETempDir2["Component"] = "component";
168
+ return ETempDir2;
169
+ })(ETempDir || {});
170
+ async function processGenerateFiles({
171
+ filesMap,
172
+ baseDir,
173
+ presetArgs = {},
174
+ templateVars
175
+ }) {
176
+ const { fallback } = presetArgs;
177
+ const choosePath = ({ from, fromFallback, exts = [] }) => {
178
+ if (fallback) {
179
+ return fromFallback;
180
+ }
181
+ if ((0, import_fs.existsSync)(from)) {
182
+ if ((0, import_fs.statSync)(from).isDirectory() && (0, import_fs.readdirSync)(from).filter((name) => name !== ".DS_Store").length === 0) {
183
+ return fromFallback;
184
+ }
185
+ return from;
186
+ }
187
+ for (const ext of exts) {
188
+ const fullPath = from + ext;
189
+ if ((0, import_fs.existsSync)(fullPath) && (0, import_fs.statSync)(fullPath).isFile()) {
190
+ return fullPath;
191
+ }
192
+ }
193
+ return fromFallback;
194
+ };
195
+ const names = [];
196
+ for (const file of filesMap) {
197
+ const { to, fromFallback } = file;
198
+ const fromPath = choosePath(file);
199
+ const toPath = (0, import_fs.statSync)(fromPath).isDirectory() ? to : (0, import_path.join)((0, import_path.dirname)(to), (0, import_path.parse)(to).name + (0, import_path.extname)(fromPath.replace(/\.tpl$/, "")));
200
+ await (0, import_utils.generateFile)({
201
+ path: fromPath,
202
+ target: toPath,
203
+ data: templateVars,
204
+ baseDir
205
+ });
206
+ if (fromPath !== fromFallback) {
207
+ names.push((0, import_path.basename)(to));
208
+ }
209
+ }
210
+ if (names.length > 0) {
211
+ import_utils.logger.info(`${names.join(", ")} is generated by yourself template.`);
212
+ }
213
+ }
214
+ async function tryEject(dir, baseDir) {
215
+ const generateBaseDir = (0, import_path.join)(__dirname, "../../../templates/generate", dir);
216
+ const targetDir = (0, import_path.join)(baseDir, "templates", dir);
217
+ const willCopyFiles = (0, import_fs.readdirSync)(generateBaseDir);
218
+ if ((0, import_fs.existsSync)(targetDir) && (0, import_fs.statSync)(targetDir).isDirectory()) {
219
+ const userExistFiles = (0, import_fs.readdirSync)(targetDir);
220
+ const conflictFiles = willCopyFiles.filter((filename) => userExistFiles.includes(filename));
221
+ if (conflictFiles.length > 0) {
222
+ const response = await (0, import_utils.prompts)({
223
+ type: "confirm",
224
+ name: "value",
225
+ message: `Will overwrites ${conflictFiles.join(", ")} in /templates/${dir}, do you want continue ?`,
226
+ initial: false
227
+ });
228
+ if (!response.value) {
229
+ return;
230
+ }
231
+ }
232
+ }
233
+ import_utils.fsExtra.ensureDirSync(targetDir);
234
+ import_utils.fsExtra.copySync(generateBaseDir, targetDir);
235
+ import_utils.logger.info(`Ejected ${dir} template successfully. More info see: "https://umijs.org/docs/guides/generator#\u5BF9${dir === "page" /* Page */ ? "\u9875\u9762" : "\u7EC4\u4EF6"}\u6A21\u677F\u5185\u5BB9\u8FDB\u884C\u81EA\u5B9A\u4E49`);
236
+ }
162
237
  // Annotate the CommonJS export names for ESM import in node:
163
238
  0 && (module.exports = {
239
+ ETempDir,
164
240
  GeneratorHelper,
165
241
  checkStatus,
166
242
  getUmiJsPlugin,
243
+ processGenerateFiles,
167
244
  promptsExitWhenCancel,
168
- trim
245
+ trim,
246
+ tryEject
169
247
  });
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="node" />
3
2
  import type { IncomingMessage } from 'http';
4
3
  import type { IRoute } from '../../types';
5
4
  declare class UmiApiRequest {
@@ -64,7 +64,9 @@ var webpack_default = (api) => {
64
64
  }
65
65
  api.modifyWebpackConfig((config) => {
66
66
  var _a;
67
- (_a = config.plugins) == null ? void 0 : _a.push(new HtmlWebpackPlugin());
67
+ if (!api.config.mpa) {
68
+ (_a = config.plugins) == null ? void 0 : _a.push(new HtmlWebpackPlugin());
69
+ }
68
70
  return config;
69
71
  });
70
72
  api.addHTMLStyles(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umijs/preset-umi",
3
- "version": "4.0.35",
3
+ "version": "4.0.37",
4
4
  "description": "@umijs/preset-umi",
5
5
  "homepage": "https://github.com/umijs/umi/tree/master/packages/preset-umi#readme",
6
6
  "bugs": "https://github.com/umijs/umi/issues",
@@ -25,19 +25,19 @@
25
25
  "test": "umi-scripts jest-turbo"
26
26
  },
27
27
  "dependencies": {
28
- "@umijs/ast": "4.0.35",
29
- "@umijs/babel-preset-umi": "4.0.35",
30
- "@umijs/bundler-utils": "4.0.35",
31
- "@umijs/bundler-vite": "4.0.35",
32
- "@umijs/bundler-webpack": "4.0.35",
33
- "@umijs/core": "4.0.35",
28
+ "@umijs/ast": "4.0.37",
29
+ "@umijs/babel-preset-umi": "4.0.37",
30
+ "@umijs/bundler-utils": "4.0.37",
31
+ "@umijs/bundler-vite": "4.0.37",
32
+ "@umijs/bundler-webpack": "4.0.37",
33
+ "@umijs/core": "4.0.37",
34
34
  "@umijs/did-you-know": "^1.0.0",
35
35
  "@umijs/history": "5.3.1",
36
- "@umijs/mfsu": "4.0.35",
37
- "@umijs/plugin-run": "4.0.35",
38
- "@umijs/renderer-react": "4.0.35",
39
- "@umijs/server": "4.0.35",
40
- "@umijs/utils": "4.0.35",
36
+ "@umijs/mfsu": "4.0.37",
37
+ "@umijs/plugin-run": "4.0.37",
38
+ "@umijs/renderer-react": "4.0.37",
39
+ "@umijs/server": "4.0.37",
40
+ "@umijs/utils": "4.0.37",
41
41
  "babel-plugin-dynamic-import-node": "2.3.3",
42
42
  "click-to-react-component": "^1.0.8",
43
43
  "core-js": "3.22.4",
@@ -25,14 +25,28 @@ export function getValidKeys() {
25
25
  }
26
26
 
27
27
  let pluginManager = null;
28
+
29
+ // 确保 webpack 模式 import.meta.hot 代码被 tree shaking 掉
30
+ const isDev = process.env.NODE_ENV === 'development';
31
+
28
32
  export function createPluginManager() {
29
33
  pluginManager = PluginManager.create({
30
34
  plugins: getPlugins(),
31
35
  validKeys: getValidKeys(),
32
36
  });
37
+
38
+ // fix https://github.com/umijs/umi/issues/10047
39
+ // https://vitejs.dev/guide/api-hmr.html#hot-data 通过 hot data 持久化 pluginManager 解决 vite 热更时 getPluginManager 获取到 null 的情况
40
+ if (isDev && import.meta.hot) {
41
+ import.meta.hot.data.pluginManager = pluginManager
42
+ }
33
43
  return pluginManager;
34
44
  }
35
45
 
36
46
  export function getPluginManager() {
47
+ // vite 热更模式优先从 hot data 中获取 pluginManager
48
+ if (isDev && import.meta.hot) {
49
+ return import.meta.hot.data.pluginManager || pluginManager
50
+ }
37
51
  return pluginManager;
38
52
  }
package/templates/umi.tpl CHANGED
@@ -34,9 +34,10 @@ async function render() {
34
34
  });
35
35
 
36
36
  const basename = contextOpts.basename || '{{{ basename }}}';
37
+ const historyType = contextOpts.historyType || '{{{ historyType }}}';
37
38
 
38
39
  const history = createHistory({
39
- type: contextOpts.historyType || '{{{ historyType }}}',
40
+ type: historyType,
40
41
  basename,
41
42
  ...contextOpts.historyOpts,
42
43
  });
@@ -62,6 +63,7 @@ async function render() {
62
63
  publicPath,
63
64
  runtimePublicPath,
64
65
  history,
66
+ historyType,
65
67
  basename,
66
68
  callback: contextOpts.callback,
67
69
  };