@umijs/preset-umi 4.0.1 → 4.0.4
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/dev/dev.js +26 -2
- package/dist/commands/generators/jest.js +9 -1
- package/dist/commands/generators/tsconfig.js +2 -17
- package/dist/commands/lint.js +8 -3
- package/dist/commands/preview.js +3 -2
- package/dist/features/configPlugins/schema.d.ts +1 -1
- package/dist/features/configPlugins/schema.js +1 -0
- package/dist/features/ssr/ssr.js +2 -2
- package/dist/features/tmpFiles/configTypes.js +1 -1
- package/dist/features/tmpFiles/routes.d.ts +1 -1
- package/dist/features/tmpFiles/routes.js +14 -4
- package/dist/features/tmpFiles/tmpFiles.js +13 -10
- package/dist/libs/folderCache/AutoUpdateFolderCache.d.ts +32 -0
- package/dist/libs/folderCache/AutoUpdateFolderCache.js +106 -0
- package/dist/libs/folderCache/AutoUpdateSourceCodeCache.d.ts +27 -0
- package/dist/libs/folderCache/AutoUpdateSourceCodeCache.js +124 -0
- package/dist/registerMethods.js +5 -3
- package/package.json +15 -14
- package/templates/generate/api.ts.tpl +1 -1
- package/templates/route.tpl +2 -0
package/dist/commands/dev/dev.js
CHANGED
|
@@ -7,6 +7,7 @@ const utils_1 = require("@umijs/utils");
|
|
|
7
7
|
const fs_1 = require("fs");
|
|
8
8
|
const path_1 = require("path");
|
|
9
9
|
const constants_1 = require("../../constants");
|
|
10
|
+
const AutoUpdateSourceCodeCache_1 = require("../../libs/folderCache/AutoUpdateSourceCodeCache");
|
|
10
11
|
const lazyImportFromCurrentPkg_1 = require("../../utils/lazyImportFromCurrentPkg");
|
|
11
12
|
const createRouteMiddleware_1 = require("./createRouteMiddleware");
|
|
12
13
|
const faviconMiddleware_1 = require("./faviconMiddleware");
|
|
@@ -16,6 +17,12 @@ const printMemoryUsage_1 = require("./printMemoryUsage");
|
|
|
16
17
|
const watch_1 = require("./watch");
|
|
17
18
|
const bundlerWebpack = (0, lazyImportFromCurrentPkg_1.lazyImportFromCurrentPkg)('@umijs/bundler-webpack');
|
|
18
19
|
const bundlerVite = (0, lazyImportFromCurrentPkg_1.lazyImportFromCurrentPkg)('@umijs/bundler-vite');
|
|
20
|
+
const MFSU_EAGER_DEFAULT_INCLUDE = [
|
|
21
|
+
'react',
|
|
22
|
+
'react-error-overlay',
|
|
23
|
+
'react/jsx-dev-runtime',
|
|
24
|
+
'@umijs/utils/compiled/strip-ansi',
|
|
25
|
+
];
|
|
19
26
|
exports.default = (api) => {
|
|
20
27
|
api.describe({
|
|
21
28
|
enableBy() {
|
|
@@ -32,7 +39,7 @@ umi dev
|
|
|
32
39
|
PORT=8888 umi dev
|
|
33
40
|
`,
|
|
34
41
|
async fn() {
|
|
35
|
-
var _a, _b;
|
|
42
|
+
var _a, _b, _c, _d, _e;
|
|
36
43
|
utils_1.logger.info(utils_1.chalk.cyan.bold(`Umi v${api.appData.umi.version}`));
|
|
37
44
|
const enableVite = !!api.config.vite;
|
|
38
45
|
// clear tmp
|
|
@@ -199,6 +206,17 @@ PORT=8888 umi dev
|
|
|
199
206
|
});
|
|
200
207
|
};
|
|
201
208
|
const debouncedPrintMemoryUsage = utils_1.lodash.debounce(printMemoryUsage_1.printMemoryUsage, 5000);
|
|
209
|
+
let srcCodeCache;
|
|
210
|
+
if (((_b = api.config.mfsu) === null || _b === void 0 ? void 0 : _b.strategy) === 'eager') {
|
|
211
|
+
srcCodeCache = new AutoUpdateSourceCodeCache_1.AutoUpdateSrcCodeCache({
|
|
212
|
+
cwd: api.paths.absSrcPath,
|
|
213
|
+
cachePath: (0, path_1.join)(api.paths.absNodeModulesPath, '.cache', 'mfsu', 'v4'),
|
|
214
|
+
});
|
|
215
|
+
await srcCodeCache.init();
|
|
216
|
+
(0, watch_1.addUnWatch)(() => {
|
|
217
|
+
srcCodeCache.unwatch();
|
|
218
|
+
});
|
|
219
|
+
}
|
|
202
220
|
const opts = {
|
|
203
221
|
config: api.config,
|
|
204
222
|
cwd: api.cwd,
|
|
@@ -241,13 +259,19 @@ PORT=8888 umi dev
|
|
|
241
259
|
...opts,
|
|
242
260
|
};
|
|
243
261
|
},
|
|
244
|
-
mfsuWithESBuild: (
|
|
262
|
+
mfsuWithESBuild: (_c = api.config.mfsu) === null || _c === void 0 ? void 0 : _c.esbuild,
|
|
263
|
+
mfsuStrategy: (_d = api.config.mfsu) === null || _d === void 0 ? void 0 : _d.strategy,
|
|
245
264
|
cache: {
|
|
246
265
|
buildDependencies: [
|
|
247
266
|
api.pkgPath,
|
|
248
267
|
api.service.configManager.mainConfigFile || '',
|
|
249
268
|
].filter(Boolean),
|
|
250
269
|
},
|
|
270
|
+
srcCodeCache,
|
|
271
|
+
mfsuInclude: utils_1.lodash.union([
|
|
272
|
+
...MFSU_EAGER_DEFAULT_INCLUDE,
|
|
273
|
+
...(((_e = api.config.mfsu) === null || _e === void 0 ? void 0 : _e.include) || []),
|
|
274
|
+
]),
|
|
251
275
|
};
|
|
252
276
|
if (enableVite) {
|
|
253
277
|
await bundlerVite.dev(opts);
|
|
@@ -37,11 +37,18 @@ exports.default = (api) => {
|
|
|
37
37
|
const packageToInstall = res.willUseTLR
|
|
38
38
|
? {
|
|
39
39
|
...basicDeps,
|
|
40
|
-
'@testing-library/react': '^
|
|
40
|
+
'@testing-library/react': '^13',
|
|
41
|
+
'@testing-library/jest-dom': '^5.16.4',
|
|
42
|
+
'@types/testing-library__jest-dom': '^5.14.5',
|
|
41
43
|
}
|
|
42
44
|
: basicDeps;
|
|
43
45
|
h.addDevDeps(packageToInstall);
|
|
44
46
|
h.addScript('test', 'jest');
|
|
47
|
+
if (res.willUseTLR) {
|
|
48
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(api.cwd, 'jest-setup.ts'), `import '@testing-library/jest-dom';
|
|
49
|
+
`.trimLeft());
|
|
50
|
+
utils_1.logger.info('Write jest-setup.ts');
|
|
51
|
+
}
|
|
45
52
|
const importSource = api.appData.umi.importSource;
|
|
46
53
|
(0, fs_1.writeFileSync)((0, path_1.join)(api.cwd, 'jest.config.ts'), `
|
|
47
54
|
import { Config, configUmiAlias, createConfig } from '${importSource}/test';
|
|
@@ -51,6 +58,7 @@ export default async () => {
|
|
|
51
58
|
...createConfig({
|
|
52
59
|
target: 'browser',
|
|
53
60
|
}),
|
|
61
|
+
${res.willUseTLR ? `setupFilesAfterEnv: ['<rootDir>/jest-setup.ts'],` : ''}
|
|
54
62
|
// if you require some es-module npm package, please uncomment below line and insert your package name
|
|
55
63
|
// transformIgnorePatterns: ['node_modules/(?!.*(lodash-es|your-es-pkg-name)/)']
|
|
56
64
|
})) as Config.InitialOptions;
|
|
@@ -25,24 +25,9 @@ exports.default = (api) => {
|
|
|
25
25
|
});
|
|
26
26
|
(0, fs_1.writeFileSync)((0, path_1.join)(api.cwd, 'tsconfig.json'), `
|
|
27
27
|
{
|
|
28
|
-
"
|
|
29
|
-
"target": "esnext",
|
|
30
|
-
"module": "esnext",
|
|
31
|
-
"moduleResolution": "node",
|
|
32
|
-
"importHelpers": true,
|
|
33
|
-
"jsx": "react",
|
|
34
|
-
"esModuleInterop": true,
|
|
35
|
-
"sourceMap": true,
|
|
36
|
-
"baseUrl": ".",
|
|
37
|
-
"strict": true,
|
|
38
|
-
"paths": {
|
|
39
|
-
"@/*": ["*"],
|
|
40
|
-
"@@/*": [".umi/*"]
|
|
41
|
-
},
|
|
42
|
-
"allowSyntheticDefaultImports": true
|
|
43
|
-
}
|
|
28
|
+
"extends": "./${api.appData.hasSrcDir ? 'src/' : ''}.umi/tsconfig.json"
|
|
44
29
|
}
|
|
45
|
-
`.
|
|
30
|
+
`.trimStart());
|
|
46
31
|
utils_1.logger.info('Write tsconfig.json');
|
|
47
32
|
h.installDeps();
|
|
48
33
|
},
|
package/dist/commands/lint.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@umijs/utils");
|
|
3
4
|
exports.default = (api) => {
|
|
4
5
|
api.registerCommand({
|
|
5
6
|
name: 'lint',
|
|
@@ -18,17 +19,21 @@ umi lint --stylelint-only
|
|
|
18
19
|
umi lint --fix
|
|
19
20
|
`,
|
|
20
21
|
fn: async function () {
|
|
22
|
+
// re-parse cli args to process boolean flags, for get the lint-staged args
|
|
23
|
+
const args = (0, utils_1.yParser)(process.argv.slice(3), {
|
|
24
|
+
boolean: ['fix', 'eslint-only', 'stylelint-only'],
|
|
25
|
+
});
|
|
21
26
|
try {
|
|
22
27
|
require.resolve('@umijs/lint/package.json');
|
|
23
28
|
}
|
|
24
29
|
catch (err) {
|
|
25
30
|
throw new Error('@umijs/lint is not built-in, please install it manually before run umi lint.');
|
|
26
31
|
}
|
|
27
|
-
if (
|
|
28
|
-
|
|
32
|
+
if (args._.length === 0) {
|
|
33
|
+
args._.unshift('{src,test}/**/*.{js,jsx,ts,tsx,less,css}');
|
|
29
34
|
}
|
|
30
35
|
// lazy require for CLI performance
|
|
31
|
-
require('@umijs/lint').default({ cwd: api.cwd },
|
|
36
|
+
require('@umijs/lint').default({ cwd: api.cwd }, args);
|
|
32
37
|
},
|
|
33
38
|
});
|
|
34
39
|
};
|
package/dist/commands/preview.js
CHANGED
|
@@ -52,10 +52,11 @@ umi preview --port [port]
|
|
|
52
52
|
app.use(key, (0, http_proxy_middleware_1.createProxyMiddleware)(key, {
|
|
53
53
|
...proxy[key],
|
|
54
54
|
// Add x-real-url in response header
|
|
55
|
-
onProxyRes(proxyRes, req) {
|
|
56
|
-
var _a;
|
|
55
|
+
onProxyRes(proxyRes, req, res) {
|
|
56
|
+
var _a, _b;
|
|
57
57
|
proxyRes.headers['x-real-url'] =
|
|
58
58
|
((_a = new URL(req.url || '', target)) === null || _a === void 0 ? void 0 : _a.href) || '';
|
|
59
|
+
(_b = proxyConfig.onProxyRes) === null || _b === void 0 ? void 0 : _b.call(proxyConfig, proxyRes, req, res);
|
|
59
60
|
},
|
|
60
61
|
}));
|
|
61
62
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Root } from '@umijs/
|
|
1
|
+
import type { Root } from '@umijs/utils/compiled/@hapi/joi';
|
|
2
2
|
export declare function getSchemas(): Record<string, (Joi: Root) => any>;
|
package/dist/features/ssr/ssr.js
CHANGED
|
@@ -4,7 +4,6 @@ const types_1 = require("@umijs/core/dist/types");
|
|
|
4
4
|
const utils_1 = require("@umijs/utils");
|
|
5
5
|
const fs_1 = require("fs");
|
|
6
6
|
const path_1 = require("path");
|
|
7
|
-
const builder_1 = require("./builder/builder");
|
|
8
7
|
const utils_2 = require("./utils");
|
|
9
8
|
exports.default = (api) => {
|
|
10
9
|
api.describe({
|
|
@@ -52,7 +51,8 @@ export { React };
|
|
|
52
51
|
});
|
|
53
52
|
});
|
|
54
53
|
api.onBeforeCompiler(async () => {
|
|
55
|
-
|
|
54
|
+
const { build } = (0, utils_1.importLazy)(require.resolve('./builder/builder'));
|
|
55
|
+
await build({
|
|
56
56
|
api,
|
|
57
57
|
watch: api.env === 'development',
|
|
58
58
|
});
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const joi_1 = __importDefault(require("@umijs/
|
|
6
|
+
const joi_1 = __importDefault(require("@umijs/utils/compiled/@hapi/joi"));
|
|
7
7
|
// @ts-ignore
|
|
8
8
|
const joi2types_1 = __importDefault(require("../../../compiled/joi2types"));
|
|
9
9
|
exports.default = (api) => {
|
|
@@ -4,7 +4,7 @@ export declare function getApiRoutes(opts: {
|
|
|
4
4
|
}): Promise<any>;
|
|
5
5
|
export declare function getRoutes(opts: {
|
|
6
6
|
api: IApi;
|
|
7
|
-
}): Promise<any
|
|
7
|
+
}): Promise<Record<string, any>>;
|
|
8
8
|
export declare function getRouteComponents(opts: {
|
|
9
9
|
routes: Record<string, any>;
|
|
10
10
|
prefix: string;
|
|
@@ -50,7 +50,7 @@ async function getRoutes(opts) {
|
|
|
50
50
|
basedir: opts.api.paths.absPagesPath,
|
|
51
51
|
extensions: ['.js', '.jsx', '.tsx', '.ts', '.vue'],
|
|
52
52
|
}));
|
|
53
|
-
component = component.replace(`${opts.api.paths.absSrcPath}
|
|
53
|
+
component = component.replace((0, utils_1.winPath)(`${opts.api.paths.absSrcPath}/`), '@/');
|
|
54
54
|
return component;
|
|
55
55
|
},
|
|
56
56
|
});
|
|
@@ -112,6 +112,8 @@ async function getRoutes(opts) {
|
|
|
112
112
|
const absLayoutPath = (0, utils_1.tryPaths)([
|
|
113
113
|
(0, path_1.join)(opts.api.paths.absSrcPath, 'layouts/index.tsx'),
|
|
114
114
|
(0, path_1.join)(opts.api.paths.absSrcPath, 'layouts/index.vue'),
|
|
115
|
+
(0, path_1.join)(opts.api.paths.absSrcPath, 'layouts/index.jsx'),
|
|
116
|
+
(0, path_1.join)(opts.api.paths.absSrcPath, 'layouts/index.js'),
|
|
115
117
|
]);
|
|
116
118
|
const layouts = (await opts.api.applyPlugins({
|
|
117
119
|
key: 'addLayouts',
|
|
@@ -119,11 +121,14 @@ async function getRoutes(opts) {
|
|
|
119
121
|
absLayoutPath && {
|
|
120
122
|
id: '@@/global-layout',
|
|
121
123
|
file: (0, utils_1.winPath)(absLayoutPath),
|
|
124
|
+
test(route) {
|
|
125
|
+
return route.layout !== false;
|
|
126
|
+
},
|
|
122
127
|
},
|
|
123
128
|
].filter(Boolean),
|
|
124
129
|
})).map((layout) => {
|
|
125
130
|
// prune local path prefix, avoid mix in outputs
|
|
126
|
-
layout.file = layout.file.replace(new RegExp(`^${absSrcPath}`), '@');
|
|
131
|
+
layout.file = layout.file.replace(new RegExp(`^${(0, utils_1.winPath)(absSrcPath)}`), '@');
|
|
127
132
|
return layout;
|
|
128
133
|
});
|
|
129
134
|
for (const layout of layouts) {
|
|
@@ -135,6 +140,7 @@ async function getRoutes(opts) {
|
|
|
135
140
|
file: layout.file,
|
|
136
141
|
parentId: undefined,
|
|
137
142
|
absPath: '/',
|
|
143
|
+
isLayout: true,
|
|
138
144
|
},
|
|
139
145
|
routes,
|
|
140
146
|
test: layout.test,
|
|
@@ -159,7 +165,7 @@ exports.getRoutes = getRoutes;
|
|
|
159
165
|
async function getRouteComponents(opts) {
|
|
160
166
|
const imports = Object.keys(opts.routes)
|
|
161
167
|
.map((key) => {
|
|
162
|
-
const useSuspense = true; // opts.api.appData.react.version.startsWith('18.');
|
|
168
|
+
const useSuspense = opts.api.appData.framework === 'react' ? true : false; // opts.api.appData.react.version.startsWith('18.');
|
|
163
169
|
const route = opts.routes[key];
|
|
164
170
|
if (!route.file) {
|
|
165
171
|
return useSuspense
|
|
@@ -174,7 +180,11 @@ async function getRouteComponents(opts) {
|
|
|
174
180
|
// component: (() => () => <h1>foo</h1>)()
|
|
175
181
|
if (route.file.startsWith('(')) {
|
|
176
182
|
return useSuspense
|
|
177
|
-
?
|
|
183
|
+
? // Compatible with none default route exports
|
|
184
|
+
// e.g. https://github.com/umijs/umi/blob/0d40a07bf28b0760096cbe2f22da4d639645b937/packages/plugins/src/qiankun/master.ts#L55
|
|
185
|
+
`'${key}': React.lazy(
|
|
186
|
+
() => Promise.resolve(${route.file}).then(e => e?.default ? e : ({ default: e }))
|
|
187
|
+
),`
|
|
178
188
|
: `'${key}': () => Promise.resolve(${route.file}),`;
|
|
179
189
|
}
|
|
180
190
|
const path = (0, path_1.isAbsolute)(route.file) || route.file.startsWith('@/')
|
|
@@ -51,8 +51,6 @@ exports.default = (api) => {
|
|
|
51
51
|
strict: true,
|
|
52
52
|
resolveJsonModule: true,
|
|
53
53
|
allowSyntheticDefaultImports: true,
|
|
54
|
-
// Enforce using `import type` instead of `import` for types
|
|
55
|
-
importsNotUsedAsValues: 'error',
|
|
56
54
|
// Supported by vue only
|
|
57
55
|
...(api.appData.framework === 'vue'
|
|
58
56
|
? {
|
|
@@ -267,6 +265,7 @@ declare module '*.txt' {
|
|
|
267
265
|
noPluginDir: true,
|
|
268
266
|
path: 'core/EmptyRoute.tsx',
|
|
269
267
|
content: `
|
|
268
|
+
import React from 'react';
|
|
270
269
|
import { Outlet } from 'umi';
|
|
271
270
|
export default function EmptyRoute() {
|
|
272
271
|
return <Outlet />;
|
|
@@ -302,6 +301,7 @@ export default function EmptyRoute() {
|
|
|
302
301
|
path: 'core/route.tsx',
|
|
303
302
|
tplPath: (0, path_1.join)(constants_1.TEMPLATES_DIR, 'route.tpl'),
|
|
304
303
|
context: {
|
|
304
|
+
isReact: api.appData.framework === 'react',
|
|
305
305
|
isClientLoaderEnabled: !!api.config.clientLoader,
|
|
306
306
|
routes: JSON.stringify(clonedRoutes)
|
|
307
307
|
// "clientLoaders['foo']" > clientLoaders['foo']
|
|
@@ -379,14 +379,17 @@ export default function EmptyRoute() {
|
|
|
379
379
|
});
|
|
380
380
|
}
|
|
381
381
|
// history.ts
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
382
|
+
// only react generates because the preset-vue override causes vite hot updates to fail
|
|
383
|
+
if (api.appData.framework === 'react') {
|
|
384
|
+
api.writeTmpFile({
|
|
385
|
+
noPluginDir: true,
|
|
386
|
+
path: 'core/history.ts',
|
|
387
|
+
tplPath: (0, path_1.join)(constants_1.TEMPLATES_DIR, 'history.tpl'),
|
|
388
|
+
context: {
|
|
389
|
+
rendererPath,
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
}
|
|
390
393
|
});
|
|
391
394
|
function checkMembers(opts) {
|
|
392
395
|
const conflicts = utils_1.lodash.intersection(opts.exportMembers, opts.members);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
declare type AbsPath = string;
|
|
2
|
+
declare type FileContent = string;
|
|
3
|
+
declare type FileContentCache = Record<AbsPath, FileContent>;
|
|
4
|
+
export declare type FileChangeEvent = {
|
|
5
|
+
event: 'unlink' | 'change' | 'add';
|
|
6
|
+
path: string;
|
|
7
|
+
};
|
|
8
|
+
export declare class AutoUpdateFolderCache {
|
|
9
|
+
fileContentCache: FileContentCache;
|
|
10
|
+
private watcher;
|
|
11
|
+
private readonly readyPromise;
|
|
12
|
+
private readonly cwd;
|
|
13
|
+
pendingChanges: FileChangeEvent[];
|
|
14
|
+
private readonly debouchedHandleChanges;
|
|
15
|
+
private readonly onCacheUpdated;
|
|
16
|
+
private readonly filesLoader;
|
|
17
|
+
constructor(opts: {
|
|
18
|
+
cwd: string;
|
|
19
|
+
exts: string[];
|
|
20
|
+
onCacheUpdate: (cache: FileContentCache, events: FileChangeEvent[]) => void;
|
|
21
|
+
debouncedTimeout?: number;
|
|
22
|
+
ignored: string[];
|
|
23
|
+
filesLoader?: (files: string[]) => Promise<Record<string, string>>;
|
|
24
|
+
});
|
|
25
|
+
unwatch(): Promise<void>;
|
|
26
|
+
init(): Promise<void>;
|
|
27
|
+
private watchAll;
|
|
28
|
+
getFileCache(): FileContentCache;
|
|
29
|
+
loadFiles(files: string[]): Promise<void>;
|
|
30
|
+
private _defaultLoader;
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AutoUpdateFolderCache = void 0;
|
|
4
|
+
const utils_1 = require("@umijs/utils");
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const { watch } = utils_1.chokidar;
|
|
8
|
+
class AutoUpdateFolderCache {
|
|
9
|
+
constructor(opts) {
|
|
10
|
+
this.fileContentCache = {};
|
|
11
|
+
this.pendingChanges = [];
|
|
12
|
+
console.log('the path ', `./**/*.{${opts.exts.join(',')}}`);
|
|
13
|
+
this.cwd = opts.cwd;
|
|
14
|
+
this.onCacheUpdated = opts.onCacheUpdate;
|
|
15
|
+
this.filesLoader = opts.filesLoader || this._defaultLoader;
|
|
16
|
+
this.watcher = watch(`./**/*.{${opts.exts.join(',')}}`, {
|
|
17
|
+
ignored: opts.ignored || [],
|
|
18
|
+
cwd: opts.cwd,
|
|
19
|
+
ignorePermissionErrors: true,
|
|
20
|
+
ignoreInitial: true,
|
|
21
|
+
});
|
|
22
|
+
this.watchAll();
|
|
23
|
+
this.readyPromise = new Promise((resolve) => {
|
|
24
|
+
this.watcher.on('ready', () => {
|
|
25
|
+
resolve();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
this.debouchedHandleChanges = utils_1.lodash.debounce(async () => {
|
|
29
|
+
const modifiedFiles = [];
|
|
30
|
+
const events = this.pendingChanges.slice();
|
|
31
|
+
while (this.pendingChanges.length > 0) {
|
|
32
|
+
const c = this.pendingChanges.pop();
|
|
33
|
+
switch (c.event) {
|
|
34
|
+
case 'unlink':
|
|
35
|
+
delete this.fileContentCache[c.path];
|
|
36
|
+
break;
|
|
37
|
+
case 'change':
|
|
38
|
+
case 'add':
|
|
39
|
+
modifiedFiles.push(c.path);
|
|
40
|
+
break;
|
|
41
|
+
default:
|
|
42
|
+
((_n) => { })(c.event);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
await this.loadFiles(modifiedFiles);
|
|
46
|
+
await this.onCacheUpdated(this.fileContentCache, events);
|
|
47
|
+
}, opts.debouncedTimeout);
|
|
48
|
+
}
|
|
49
|
+
unwatch() {
|
|
50
|
+
return this.watcher.close();
|
|
51
|
+
}
|
|
52
|
+
async init() {
|
|
53
|
+
await this.readyPromise;
|
|
54
|
+
}
|
|
55
|
+
watchAll() {
|
|
56
|
+
this.watcher.on('all', (eventName, path) => {
|
|
57
|
+
switch (eventName) {
|
|
58
|
+
case 'change':
|
|
59
|
+
this.pendingChanges.push({
|
|
60
|
+
event: 'change',
|
|
61
|
+
path: (0, path_1.join)(this.cwd, path),
|
|
62
|
+
});
|
|
63
|
+
this.debouchedHandleChanges();
|
|
64
|
+
break;
|
|
65
|
+
case 'add':
|
|
66
|
+
this.pendingChanges.push({
|
|
67
|
+
event: 'add',
|
|
68
|
+
path: (0, path_1.join)(this.cwd, path),
|
|
69
|
+
});
|
|
70
|
+
this.debouchedHandleChanges();
|
|
71
|
+
break;
|
|
72
|
+
case 'unlink':
|
|
73
|
+
this.pendingChanges.push({
|
|
74
|
+
event: 'unlink',
|
|
75
|
+
path: (0, path_1.join)(this.cwd, path),
|
|
76
|
+
});
|
|
77
|
+
this.debouchedHandleChanges();
|
|
78
|
+
break;
|
|
79
|
+
default:
|
|
80
|
+
// ignore all others;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
getFileCache() {
|
|
85
|
+
return this.fileContentCache;
|
|
86
|
+
}
|
|
87
|
+
async loadFiles(files) {
|
|
88
|
+
const loaded = await this.filesLoader(files);
|
|
89
|
+
for (const f of Object.keys(loaded)) {
|
|
90
|
+
this.fileContentCache[f] = loaded[f];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async _defaultLoader(files) {
|
|
94
|
+
const loaded = {};
|
|
95
|
+
for (let file of files) {
|
|
96
|
+
try {
|
|
97
|
+
loaded[file] = (0, fs_1.readFileSync)(file, 'utf-8');
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
utils_1.logger.error('[fileCache] load file', (0, path_1.relative)(this.cwd, file), 'failed ', e);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return loaded;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.AutoUpdateFolderCache = AutoUpdateFolderCache;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ImportSpecifier } from '@umijs/bundler-utils/compiled/es-module-lexer';
|
|
2
|
+
import { AutoUpdateFolderCache, FileChangeEvent } from './AutoUpdateFolderCache';
|
|
3
|
+
export declare type MergedCodeInfo = {
|
|
4
|
+
code: string;
|
|
5
|
+
imports: readonly ImportSpecifier[];
|
|
6
|
+
events: FileChangeEvent[];
|
|
7
|
+
};
|
|
8
|
+
export declare type Listener = (info: MergedCodeInfo) => void;
|
|
9
|
+
export declare class AutoUpdateSrcCodeCache {
|
|
10
|
+
private readonly srcPath;
|
|
11
|
+
private readonly cachePath;
|
|
12
|
+
folderCache: AutoUpdateFolderCache;
|
|
13
|
+
private listeners;
|
|
14
|
+
constructor(opts: {
|
|
15
|
+
cwd: string;
|
|
16
|
+
cachePath: string;
|
|
17
|
+
});
|
|
18
|
+
init(): Promise<void>;
|
|
19
|
+
private initFileList;
|
|
20
|
+
batchProcess(files: string[]): Promise<void>;
|
|
21
|
+
getMergedCode(): {
|
|
22
|
+
code: string;
|
|
23
|
+
imports: readonly ImportSpecifier[];
|
|
24
|
+
};
|
|
25
|
+
register(l: Listener): () => void;
|
|
26
|
+
unwatch(): Promise<void>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AutoUpdateSrcCodeCache = void 0;
|
|
7
|
+
const es_module_lexer_1 = require("@umijs/bundler-utils/compiled/es-module-lexer");
|
|
8
|
+
const esbuild_1 = require("@umijs/bundler-utils/compiled/esbuild");
|
|
9
|
+
const utils_1 = require("@umijs/utils");
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
12
|
+
const fs_1 = require("fs");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
const AutoUpdateFolderCache_1 = require("./AutoUpdateFolderCache");
|
|
15
|
+
class AutoUpdateSrcCodeCache {
|
|
16
|
+
constructor(opts) {
|
|
17
|
+
this.listeners = [];
|
|
18
|
+
this.srcPath = opts.cwd;
|
|
19
|
+
this.cachePath = opts.cachePath;
|
|
20
|
+
this.folderCache = new AutoUpdateFolderCache_1.AutoUpdateFolderCache({
|
|
21
|
+
cwd: this.srcPath,
|
|
22
|
+
exts: ['ts', 'js', 'jsx', 'tsx'],
|
|
23
|
+
ignored: [
|
|
24
|
+
'**/*.d.ts',
|
|
25
|
+
'**/*.test.{js,ts,jsx,tsx}',
|
|
26
|
+
// fixme respect to environment
|
|
27
|
+
'**/.umi-production/**',
|
|
28
|
+
'**/node_modules/**',
|
|
29
|
+
'**/.git/**',
|
|
30
|
+
],
|
|
31
|
+
debouncedTimeout: 500,
|
|
32
|
+
filesLoader: async (files) => {
|
|
33
|
+
const loaded = {};
|
|
34
|
+
await this.batchProcess(files);
|
|
35
|
+
for (const f of files) {
|
|
36
|
+
let newFile = (0, path_1.join)(this.cachePath, (0, path_1.relative)(this.srcPath, f));
|
|
37
|
+
// fixme ensure the last one
|
|
38
|
+
newFile = newFile.replace((0, path_1.extname)(newFile), '.js');
|
|
39
|
+
loaded[f] = (0, fs_1.readFileSync)(newFile, 'utf-8');
|
|
40
|
+
}
|
|
41
|
+
return loaded;
|
|
42
|
+
},
|
|
43
|
+
onCacheUpdate: (_cache, events) => {
|
|
44
|
+
const merged = this.getMergedCode();
|
|
45
|
+
const info = { ...merged, events };
|
|
46
|
+
this.listeners.forEach((l) => l(info));
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async init() {
|
|
51
|
+
const [files] = await Promise.all([this.initFileList(), es_module_lexer_1.init]);
|
|
52
|
+
await this.folderCache.loadFiles(files);
|
|
53
|
+
}
|
|
54
|
+
async initFileList() {
|
|
55
|
+
const start = Date.now();
|
|
56
|
+
const files = await (0, fast_glob_1.default)((0, path_1.join)(this.srcPath, '**', '*.{ts,js,jsx,tsx}'), {
|
|
57
|
+
dot: true,
|
|
58
|
+
ignore: [
|
|
59
|
+
'**/*.d.ts',
|
|
60
|
+
'**/*.test.{js,ts,jsx,tsx}',
|
|
61
|
+
// fixme respect to environment
|
|
62
|
+
'**/.umi-production/**',
|
|
63
|
+
'**/node_modules/**',
|
|
64
|
+
'**/.git/**',
|
|
65
|
+
],
|
|
66
|
+
});
|
|
67
|
+
utils_1.logger.debug('[MFSU][eager] fast-glob costs', Date.now() - start);
|
|
68
|
+
return files;
|
|
69
|
+
}
|
|
70
|
+
async batchProcess(files) {
|
|
71
|
+
var _a, _b, _c, _d;
|
|
72
|
+
try {
|
|
73
|
+
await (0, esbuild_1.build)({
|
|
74
|
+
entryPoints: files,
|
|
75
|
+
bundle: false,
|
|
76
|
+
outdir: this.cachePath,
|
|
77
|
+
outbase: this.srcPath,
|
|
78
|
+
loader: {
|
|
79
|
+
// in case some js using some feature, eg: decorator
|
|
80
|
+
'.jsx': 'tsx',
|
|
81
|
+
},
|
|
82
|
+
logLevel: 'silent',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
// error ignored due to user have to update code to fix then trigger another batchProcess;
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
if (((_a = e.errors) === null || _a === void 0 ? void 0 : _a.length) || ((_b = e.warnings) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
89
|
+
utils_1.logger.warn('transpile code with esbuild got ',
|
|
90
|
+
// @ts-ignore
|
|
91
|
+
((_c = e.errors) === null || _c === void 0 ? void 0 : _c.lenght) || 0, 'errors,',
|
|
92
|
+
// @ts-ignore
|
|
93
|
+
((_d = e.warnings) === null || _d === void 0 ? void 0 : _d.length) || 0, 'warnings');
|
|
94
|
+
utils_1.logger.debug('esbuild transpile code with error', e);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
utils_1.logger.warn('transpile code with esbuild error', e);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
getMergedCode() {
|
|
102
|
+
const fileContentCache = this.folderCache.getFileCache();
|
|
103
|
+
const code = Object.values(fileContentCache).join('\n');
|
|
104
|
+
const [imports] = (0, es_module_lexer_1.parse)(code);
|
|
105
|
+
const merged = {
|
|
106
|
+
code,
|
|
107
|
+
imports,
|
|
108
|
+
};
|
|
109
|
+
return merged;
|
|
110
|
+
}
|
|
111
|
+
register(l) {
|
|
112
|
+
if (this.listeners.indexOf(l) < 0) {
|
|
113
|
+
this.listeners.push(l);
|
|
114
|
+
}
|
|
115
|
+
return () => {
|
|
116
|
+
const i = this.listeners.indexOf(l);
|
|
117
|
+
this.listeners.splice(i, 1);
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
unwatch() {
|
|
121
|
+
return this.folderCache.unwatch();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.AutoUpdateSrcCodeCache = AutoUpdateSrcCodeCache;
|
package/dist/registerMethods.js
CHANGED
|
@@ -83,17 +83,19 @@ exports.default = (api) => {
|
|
|
83
83
|
(0, assert_1.default)(utils_1.lodash.isPlainObject(opts.context), `opts.context must be plain object.`);
|
|
84
84
|
content = utils_1.Mustache.render(tpl, opts.context);
|
|
85
85
|
}
|
|
86
|
+
// Only js files generate comments
|
|
87
|
+
const isJsFile = /\.(t|j)sx?$/.test(absPath);
|
|
86
88
|
content = [
|
|
87
89
|
(0, isTypeScriptFile_1.isTypeScriptFile)(opts.path) && `// @ts-nocheck`,
|
|
88
|
-
'// This file is generated by Umi automatically',
|
|
89
|
-
'// DO NOT CHANGE IT MANUALLY!',
|
|
90
|
+
isJsFile && '// This file is generated by Umi automatically',
|
|
91
|
+
isJsFile && '// DO NOT CHANGE IT MANUALLY!',
|
|
90
92
|
content.trim(),
|
|
91
93
|
'',
|
|
92
94
|
]
|
|
93
95
|
.filter((text) => text !== false)
|
|
94
96
|
.join('\n');
|
|
95
97
|
// transform imports for all javascript-like files only vite mode enable
|
|
96
|
-
if (api.appData.vite &&
|
|
98
|
+
if (api.appData.vite && isJsFile) {
|
|
97
99
|
content = (0, transformIEAR_1.default)({ content, path: absPath }, api);
|
|
98
100
|
}
|
|
99
101
|
if (!(0, fs_1.existsSync)(absPath)) {
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umijs/preset-umi",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.4",
|
|
4
4
|
"description": "@umijs/preset-umi",
|
|
5
|
-
"homepage": "https://github.com/umijs/umi
|
|
6
|
-
"bugs": "https://github.com/umijs/umi
|
|
5
|
+
"homepage": "https://github.com/umijs/umi/tree/master/packages/preset-umi#readme",
|
|
6
|
+
"bugs": "https://github.com/umijs/umi/issues",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/umijs/umi
|
|
9
|
+
"url": "https://github.com/umijs/umi"
|
|
10
10
|
},
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"main": "dist/index.js",
|
|
@@ -21,23 +21,24 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "pnpm tsc",
|
|
23
23
|
"build:deps": "umi-scripts bundleDeps",
|
|
24
|
-
"dev": "pnpm build --
|
|
24
|
+
"dev": "pnpm build --watch",
|
|
25
25
|
"test": "umi-scripts jest-turbo"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@types/multer": "1.4.7",
|
|
29
|
-
"@umijs/ast": "4.0.
|
|
30
|
-
"@umijs/babel-preset-umi": "4.0.
|
|
31
|
-
"@umijs/bundler-utils": "4.0.
|
|
32
|
-
"@umijs/bundler-vite": "4.0.
|
|
33
|
-
"@umijs/bundler-webpack": "4.0.
|
|
34
|
-
"@umijs/core": "4.0.
|
|
35
|
-
"@umijs/renderer-react": "4.0.
|
|
36
|
-
"@umijs/server": "4.0.
|
|
37
|
-
"@umijs/utils": "4.0.
|
|
29
|
+
"@umijs/ast": "4.0.4",
|
|
30
|
+
"@umijs/babel-preset-umi": "4.0.4",
|
|
31
|
+
"@umijs/bundler-utils": "4.0.4",
|
|
32
|
+
"@umijs/bundler-vite": "4.0.4",
|
|
33
|
+
"@umijs/bundler-webpack": "4.0.4",
|
|
34
|
+
"@umijs/core": "4.0.4",
|
|
35
|
+
"@umijs/renderer-react": "4.0.4",
|
|
36
|
+
"@umijs/server": "4.0.4",
|
|
37
|
+
"@umijs/utils": "4.0.4",
|
|
38
38
|
"core-js": "3.22.4",
|
|
39
39
|
"current-script-polyfill": "1.0.0",
|
|
40
40
|
"enhanced-resolve": "5.9.3",
|
|
41
|
+
"fast-glob": "^3.2.11",
|
|
41
42
|
"magic-string": "0.26.2",
|
|
42
43
|
"path-to-regexp": "1.7.0",
|
|
43
44
|
"react": "18.1.0",
|