@eggjs/utils 5.0.2-beta.1 → 5.0.2-beta.10
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/README.md +16 -0
- package/dist/import.d.ts +36 -1
- package/dist/import.js +79 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -42,6 +42,22 @@ npm i @eggjs/utils
|
|
|
42
42
|
- {String} baseDir - the current directory of application
|
|
43
43
|
- {String} framework - the directory of framework
|
|
44
44
|
|
|
45
|
+
### `setBundleModuleLoader(loader)`
|
|
46
|
+
|
|
47
|
+
Register a module loader hook for bundled Egg apps. The hook runs before the
|
|
48
|
+
normal `importModule()` resolution path.
|
|
49
|
+
|
|
50
|
+
- {Function | undefined} loader - a synchronous function that receives the
|
|
51
|
+
original `filepath` argument passed to `importModule()` after POSIX separator
|
|
52
|
+
normalization, or a virtual specifier. It does not receive the resolved
|
|
53
|
+
absolute file path from `importResolve()`. Return `undefined` to fall back to
|
|
54
|
+
the normal import path.
|
|
55
|
+
|
|
56
|
+
The bundle loader is stored on `globalThis`, so bundled and external copies of
|
|
57
|
+
`@eggjs/utils` share the same loader. Non-`undefined` results follow the same
|
|
58
|
+
default export unwrapping rules as `importModule()`, including
|
|
59
|
+
`importDefaultOnly`.
|
|
60
|
+
|
|
45
61
|
## License
|
|
46
62
|
|
|
47
63
|
[MIT](LICENSE)
|
package/dist/import.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { BundleModuleLoader, BundleModuleLoader as BundleModuleLoader$1 } from "@eggjs/typings";
|
|
2
|
+
|
|
1
3
|
//#region src/import.d.ts
|
|
2
4
|
interface ImportResolveOptions {
|
|
3
5
|
paths?: string[];
|
|
@@ -10,6 +12,39 @@ declare function getRequire(): NodeRequire;
|
|
|
10
12
|
declare function getExtensions(): NodeJS.RequireExtensions;
|
|
11
13
|
declare function isSupportTypeScript(): boolean;
|
|
12
14
|
declare function importResolve(filepath: string, options?: ImportResolveOptions): string;
|
|
15
|
+
/**
|
|
16
|
+
* Module loader function type for V8 snapshot support.
|
|
17
|
+
* Called with the resolved absolute file path, returns the module exports.
|
|
18
|
+
*/
|
|
19
|
+
type SnapshotModuleLoader = (resolvedPath: string) => any;
|
|
20
|
+
/**
|
|
21
|
+
* Register a snapshot module loader that intercepts `importModule()` calls.
|
|
22
|
+
*
|
|
23
|
+
* When set, `importModule()` delegates to this loader instead of calling
|
|
24
|
+
* `import()` or `require()`. This is used by the V8 snapshot entry generator
|
|
25
|
+
* to provide pre-bundled modules — the bundler generates a static module map
|
|
26
|
+
* from the egg manifest and registers it via this API.
|
|
27
|
+
*
|
|
28
|
+
* Also sets `isESM = false` because the snapshot bundle is CJS and
|
|
29
|
+
* esbuild's `import.meta` polyfill causes incorrect ESM detection.
|
|
30
|
+
*
|
|
31
|
+
* Pass `undefined` to clear the loader and restore the auto-detected `isESM`
|
|
32
|
+
* value. Always clear it once snapshot mode is no longer needed (e.g. in test
|
|
33
|
+
* teardown) so the module-level state does not leak into other files when
|
|
34
|
+
* vitest runs with `isolate: false`.
|
|
35
|
+
*/
|
|
36
|
+
declare function setSnapshotModuleLoader(loader: SnapshotModuleLoader | undefined): void;
|
|
37
|
+
/**
|
|
38
|
+
* Register a bundle module loader. Uses globalThis so that bundled and
|
|
39
|
+
* external copies of @eggjs/utils share the same loader.
|
|
40
|
+
*
|
|
41
|
+
* The loader receives a POSIX-normalized filepath or virtual specifier before
|
|
42
|
+
* normal resolution runs. Return `undefined` to fall through to the default
|
|
43
|
+
* import path. Non-undefined hits use the same default unwrapping semantics as
|
|
44
|
+
* normal imports, including `importDefaultOnly` and double-default `__esModule`
|
|
45
|
+
* compatibility.
|
|
46
|
+
*/
|
|
47
|
+
declare function setBundleModuleLoader(loader: BundleModuleLoader | undefined): void;
|
|
13
48
|
declare function importModule(filepath: string, options?: ImportModuleOptions): Promise<any>;
|
|
14
49
|
//#endregion
|
|
15
|
-
export { ImportModuleOptions, ImportResolveOptions, getExtensions, getRequire, importModule, importResolve, isESM, isSupportTypeScript };
|
|
50
|
+
export { type BundleModuleLoader$1 as BundleModuleLoader, ImportModuleOptions, ImportResolveOptions, SnapshotModuleLoader, getExtensions, getRequire, importModule, importResolve, isESM, isSupportTypeScript, setBundleModuleLoader, setSnapshotModuleLoader };
|
package/dist/import.js
CHANGED
|
@@ -8,17 +8,30 @@ import { debuglog } from "node:util";
|
|
|
8
8
|
|
|
9
9
|
//#region src/import.ts
|
|
10
10
|
const debug = debuglog("egg/utils/import");
|
|
11
|
+
let nativeDynamicImport;
|
|
12
|
+
/* v8 ignore next -- covered by the spawned Node fixture; Vitest cannot instrument this opaque import. */
|
|
13
|
+
function getNativeDynamicImport() {
|
|
14
|
+
if (!nativeDynamicImport) try {
|
|
15
|
+
nativeDynamicImport = new Function("specifier", "return import(specifier);");
|
|
16
|
+
} catch (err) {
|
|
17
|
+
const error = /* @__PURE__ */ new Error("Native dynamic import fallback for bundled module loader misses requires code generation from strings.");
|
|
18
|
+
error.cause = err;
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
return nativeDynamicImport;
|
|
22
|
+
}
|
|
11
23
|
let isESM = true;
|
|
12
24
|
try {
|
|
13
25
|
if (typeof import.meta !== "undefined") isESM = true;
|
|
14
26
|
} catch {
|
|
15
27
|
isESM = false;
|
|
16
28
|
}
|
|
29
|
+
const detectedIsESM = isESM;
|
|
17
30
|
const nodeMajorVersion = parseInt(process.versions.node.split(".", 1)[0], 10);
|
|
18
31
|
const supportImportMetaResolve = nodeMajorVersion >= 18;
|
|
19
32
|
let _customRequire;
|
|
20
33
|
function getRequire() {
|
|
21
|
-
if (!_customRequire) if (typeof __require !== "undefined") _customRequire = __require;
|
|
34
|
+
if (!_customRequire) if (typeof __require !== "undefined" && __require.extensions) _customRequire = __require;
|
|
22
35
|
else _customRequire = createRequire(process.cwd());
|
|
23
36
|
return _customRequire;
|
|
24
37
|
}
|
|
@@ -193,6 +206,11 @@ function importResolve(filepath, options) {
|
|
|
193
206
|
}
|
|
194
207
|
}
|
|
195
208
|
}
|
|
209
|
+
const bundleModuleLoader = globalThis.__EGG_BUNDLE_MODULE_LOADER__;
|
|
210
|
+
if (bundleModuleLoader && bundleModuleLoader(normalizeBundleModulePath(filepath)) !== void 0) {
|
|
211
|
+
debug("[importResolve:bundle] %o => %o", filepath, filepath);
|
|
212
|
+
return filepath;
|
|
213
|
+
}
|
|
196
214
|
const extname = path.extname(filepath);
|
|
197
215
|
if (!isAbsolute && extname === ".json" || !isESM) moduleFilePath = getRequire().resolve(filepath, { paths });
|
|
198
216
|
else if (supportImportMetaResolve) {
|
|
@@ -209,15 +227,72 @@ function importResolve(filepath, options) {
|
|
|
209
227
|
debug("[importResolve:success] %o, options: %o => %o, isESM: %s", filepath, options, moduleFilePath, isESM);
|
|
210
228
|
return moduleFilePath;
|
|
211
229
|
}
|
|
230
|
+
let _snapshotModuleLoader;
|
|
231
|
+
/**
|
|
232
|
+
* Register a snapshot module loader that intercepts `importModule()` calls.
|
|
233
|
+
*
|
|
234
|
+
* When set, `importModule()` delegates to this loader instead of calling
|
|
235
|
+
* `import()` or `require()`. This is used by the V8 snapshot entry generator
|
|
236
|
+
* to provide pre-bundled modules — the bundler generates a static module map
|
|
237
|
+
* from the egg manifest and registers it via this API.
|
|
238
|
+
*
|
|
239
|
+
* Also sets `isESM = false` because the snapshot bundle is CJS and
|
|
240
|
+
* esbuild's `import.meta` polyfill causes incorrect ESM detection.
|
|
241
|
+
*
|
|
242
|
+
* Pass `undefined` to clear the loader and restore the auto-detected `isESM`
|
|
243
|
+
* value. Always clear it once snapshot mode is no longer needed (e.g. in test
|
|
244
|
+
* teardown) so the module-level state does not leak into other files when
|
|
245
|
+
* vitest runs with `isolate: false`.
|
|
246
|
+
*/
|
|
247
|
+
function setSnapshotModuleLoader(loader) {
|
|
248
|
+
_snapshotModuleLoader = loader;
|
|
249
|
+
isESM = loader ? false : detectedIsESM;
|
|
250
|
+
}
|
|
251
|
+
function normalizeBundleModulePath(filepath) {
|
|
252
|
+
return filepath.split(path.win32.sep).join(path.posix.sep);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Register a bundle module loader. Uses globalThis so that bundled and
|
|
256
|
+
* external copies of @eggjs/utils share the same loader.
|
|
257
|
+
*
|
|
258
|
+
* The loader receives a POSIX-normalized filepath or virtual specifier before
|
|
259
|
+
* normal resolution runs. Return `undefined` to fall through to the default
|
|
260
|
+
* import path. Non-undefined hits use the same default unwrapping semantics as
|
|
261
|
+
* normal imports, including `importDefaultOnly` and double-default `__esModule`
|
|
262
|
+
* compatibility.
|
|
263
|
+
*/
|
|
264
|
+
function setBundleModuleLoader(loader) {
|
|
265
|
+
globalThis.__EGG_BUNDLE_MODULE_LOADER__ = loader;
|
|
266
|
+
}
|
|
212
267
|
async function importModule(filepath, options) {
|
|
268
|
+
const _bundleModuleLoader = globalThis.__EGG_BUNDLE_MODULE_LOADER__;
|
|
269
|
+
if (_bundleModuleLoader) {
|
|
270
|
+
const hit = _bundleModuleLoader(normalizeBundleModulePath(filepath));
|
|
271
|
+
if (hit !== void 0) {
|
|
272
|
+
let obj$1 = hit;
|
|
273
|
+
if (obj$1?.default?.__esModule === true && "default" in obj$1.default) obj$1 = obj$1.default;
|
|
274
|
+
if (options?.importDefaultOnly && obj$1 && typeof obj$1 === "object" && "default" in obj$1) obj$1 = obj$1.default;
|
|
275
|
+
return obj$1;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
213
278
|
const moduleFilePath = importResolve(filepath, options);
|
|
279
|
+
if (_snapshotModuleLoader) {
|
|
280
|
+
let obj$1 = _snapshotModuleLoader(moduleFilePath);
|
|
281
|
+
if (obj$1 && typeof obj$1 === "object" && obj$1.default?.__esModule === true && obj$1.default && "default" in obj$1.default) obj$1 = obj$1.default;
|
|
282
|
+
if (options?.importDefaultOnly) {
|
|
283
|
+
if (obj$1 && typeof obj$1 === "object" && "default" in obj$1) obj$1 = obj$1.default;
|
|
284
|
+
}
|
|
285
|
+
return obj$1;
|
|
286
|
+
}
|
|
214
287
|
let obj;
|
|
215
288
|
if (isESM) {
|
|
216
289
|
const fileUrl = pathToFileURL(moduleFilePath).toString();
|
|
217
290
|
debug("[importModule:start] await import fileUrl: %s, isESM: %s", fileUrl, isESM);
|
|
218
|
-
|
|
291
|
+
/* v8 ignore if -- covered by the spawned Node fixture; Vitest cannot instrument this opaque import. */
|
|
292
|
+
if (_bundleModuleLoader) obj = await getNativeDynamicImport()(fileUrl);
|
|
293
|
+
else obj = await import(fileUrl);
|
|
219
294
|
debug("[importModule:success] await import %o", fileUrl);
|
|
220
|
-
if (obj?.default?.__esModule === true && "default" in obj
|
|
295
|
+
if (obj?.default?.__esModule === true && obj.default && "default" in obj.default) obj = obj.default;
|
|
221
296
|
if (options?.importDefaultOnly) {
|
|
222
297
|
if ("default" in obj) obj = obj.default;
|
|
223
298
|
}
|
|
@@ -231,4 +306,4 @@ async function importModule(filepath, options) {
|
|
|
231
306
|
}
|
|
232
307
|
|
|
233
308
|
//#endregion
|
|
234
|
-
export { getExtensions, getRequire, importModule, importResolve, isESM, isSupportTypeScript };
|
|
309
|
+
export { getExtensions, getRequire, importModule, importResolve, isESM, isSupportTypeScript, setBundleModuleLoader, setSnapshotModuleLoader };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getFrameworkOrEggPath } from "./deprecated.js";
|
|
2
2
|
import { getFrameworkPath } from "./framework.js";
|
|
3
3
|
import { findEggCore, getConfig, getLoadUnits, getLoader, getPlugins } from "./plugin.js";
|
|
4
|
-
import { ImportModuleOptions, ImportResolveOptions, getExtensions, getRequire, importModule, importResolve, isESM, isSupportTypeScript } from "./import.js";
|
|
4
|
+
import { BundleModuleLoader, ImportModuleOptions, ImportResolveOptions, SnapshotModuleLoader, getExtensions, getRequire, importModule, importResolve, isESM, isSupportTypeScript, setBundleModuleLoader, setSnapshotModuleLoader } from "./import.js";
|
|
5
5
|
import { ImportResolveError } from "./error/ImportResolveError.js";
|
|
6
6
|
|
|
7
7
|
//#region src/index.d.ts
|
|
@@ -25,4 +25,4 @@ type EggType = (typeof EggType)[keyof typeof EggType];
|
|
|
25
25
|
*/
|
|
26
26
|
declare function detectType(baseDir: string): Promise<keyof typeof EggType>;
|
|
27
27
|
//#endregion
|
|
28
|
-
export { EggType, ImportModuleOptions, ImportResolveError, ImportResolveOptions, _default as default, detectType, findEggCore, getConfig, getExtensions, getFrameworkOrEggPath, getFrameworkPath, getLoadUnits, getLoader, getPlugins, getRequire, importModule, importResolve, isESM, isSupportTypeScript };
|
|
28
|
+
export { BundleModuleLoader, EggType, ImportModuleOptions, ImportResolveError, ImportResolveOptions, SnapshotModuleLoader, _default as default, detectType, findEggCore, getConfig, getExtensions, getFrameworkOrEggPath, getFrameworkPath, getLoadUnits, getLoader, getPlugins, getRequire, importModule, importResolve, isESM, isSupportTypeScript, setBundleModuleLoader, setSnapshotModuleLoader };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getFrameworkOrEggPath } from "./deprecated.js";
|
|
2
2
|
import { ImportResolveError } from "./error/ImportResolveError.js";
|
|
3
|
-
import { getExtensions, getRequire, importModule, importResolve, isESM, isSupportTypeScript } from "./import.js";
|
|
3
|
+
import { getExtensions, getRequire, importModule, importResolve, isESM, isSupportTypeScript, setBundleModuleLoader, setSnapshotModuleLoader } from "./import.js";
|
|
4
4
|
import { getFrameworkPath } from "./framework.js";
|
|
5
5
|
import { findEggCore, getConfig, getLoadUnits, getLoader, getPlugins } from "./plugin.js";
|
|
6
6
|
import fs from "node:fs/promises";
|
|
@@ -42,4 +42,4 @@ async function detectType(baseDir) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
//#endregion
|
|
45
|
-
export { EggType, ImportResolveError, src_default as default, detectType, findEggCore, getConfig, getExtensions, getFrameworkOrEggPath, getFrameworkPath, getLoadUnits, getLoader, getPlugins, getRequire, importModule, importResolve, isESM, isSupportTypeScript };
|
|
45
|
+
export { EggType, ImportResolveError, src_default as default, detectType, findEggCore, getConfig, getExtensions, getFrameworkOrEggPath, getFrameworkPath, getLoadUnits, getLoader, getPlugins, getRequire, importModule, importResolve, isESM, isSupportTypeScript, setBundleModuleLoader, setSnapshotModuleLoader };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eggjs/utils",
|
|
3
|
-
"version": "5.0.2-beta.
|
|
3
|
+
"version": "5.0.2-beta.10",
|
|
4
4
|
"description": "Utils for all egg projects",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"egg",
|
|
@@ -28,7 +28,9 @@
|
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public"
|
|
30
30
|
},
|
|
31
|
-
"dependencies": {
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@eggjs/typings": "4.1.2-beta.10"
|
|
33
|
+
},
|
|
32
34
|
"devDependencies": {
|
|
33
35
|
"coffee": "5",
|
|
34
36
|
"mm": "^4.0.2",
|