@eggjs/utils
Advanced tools
+13
-1
@@ -267,2 +267,3 @@ import { __require } from "./_virtual/rolldown_runtime.js"; | ||
| } | ||
| const _inflightImports = /* @__PURE__ */ new Map(); | ||
| async function importModule(filepath, options) { | ||
@@ -301,3 +302,14 @@ const _bundleModuleLoader = globalThis.__EGG_BUNDLE_MODULE_LOADER__; | ||
| if (_bundleModuleLoader) obj = await getNativeDynamicImport()(fileUrl); | ||
| else obj = await import(fileUrl); | ||
| else { | ||
| let pending = _inflightImports.get(fileUrl); | ||
| if (pending === void 0) { | ||
| pending = import(fileUrl); | ||
| _inflightImports.set(fileUrl, pending); | ||
| const clearInflight = () => { | ||
| if (_inflightImports.get(fileUrl) === pending) _inflightImports.delete(fileUrl); | ||
| }; | ||
| pending.then(clearInflight, clearInflight); | ||
| } | ||
| obj = await pending; | ||
| } | ||
| debug("[importModule:success] await import %o", fileUrl); | ||
@@ -304,0 +316,0 @@ if (obj?.default?.__esModule === true && obj.default && "default" in obj.default) obj = obj.default; |
+2
-2
| { | ||
| "name": "@eggjs/utils", | ||
| "version": "5.0.2-beta.16", | ||
| "version": "5.0.2-beta.17", | ||
| "description": "Utils for all egg projects", | ||
@@ -32,3 +32,3 @@ "keywords": [ | ||
| "dependencies": { | ||
| "@eggjs/typings": "4.1.2-beta.16" | ||
| "@eggjs/typings": "4.1.2-beta.17" | ||
| }, | ||
@@ -35,0 +35,0 @@ "devDependencies": { |
+43
-0
@@ -61,2 +61,45 @@ # @eggjs/utils | ||
| ### Bundle / snapshot module-loading hooks | ||
| `importModule()` resolves a module through the following hooks, in order. The | ||
| first one that produces a value wins; otherwise it falls back to the native | ||
| `import()` / `require()` path: | ||
| 1. **`globalThis.__EGG_BUNDLE_MODULE_LOADER__`** — set via | ||
| `setBundleModuleLoader()`. Looks up a module already inlined into the bundle | ||
| (typically a static bundle map emitted by `egg-bundler`). Runs before on-disk | ||
| resolution and receives the POSIX-normalized `importModule()` filepath or a | ||
| virtual specifier. Return `undefined` to fall through. | ||
| 2. **Snapshot module loader** — set via `setSnapshotModuleLoader()`. This is a | ||
| module-local hook (not a `globalThis` global) used by the V8 snapshot entry | ||
| generator to serve pre-bundled modules synchronously, keyed by the resolved | ||
| path. Once registered it handles every load that reaches it, so the importer | ||
| below is not consulted while it is active. | ||
| 3. **`globalThis.__EGG_MODULE_IMPORTER__`** — an async (or sync, since the value | ||
| is awaited) importer that receives the resolved file path (the | ||
| `importResolve()` result, with OS-native separators — not normalized). When | ||
| set, and the two hooks above did not resolve the module, it replaces the | ||
| native `await import(filePath)`. | ||
| The bundle loader and importer globals are typed in `@eggjs/typings` | ||
| (`BundleModuleLoader` / `ModuleImporter`); import `@eggjs/typings/global` to pick | ||
| up the `declare global` augmentation. These hooks are the contract that | ||
| `egg-bundler`'s generated entry relies on. `@eggjs/core`'s `ManifestLoaderFS` | ||
| consults `__EGG_BUNDLE_MODULE_LOADER__` directly; its importer/native fallback is | ||
| reached through `@eggjs/loader-fs`, which calls back into `importModule()`. The | ||
| tegg loader (`LoaderUtil.loadFile`) consults both globals directly, passing the | ||
| loader filepath with separators normalized to POSIX. | ||
| `__EGG_MODULE_IMPORTER__` has two main uses: | ||
| - **Bundler-based test runners (e.g. Vitest):** route module loading through the | ||
| runner's own module graph so the loader and the test file share a single | ||
| module instance (otherwise `ctx.getEggObject(ClassRef)` fails with | ||
| "can not get proto"). | ||
| - **V8 startup-snapshot restore:** the deserialized main function runs without a | ||
| host dynamic-import callback, so native `import()` throws. The snapshot entry | ||
| installs a synchronous `require()`-based importer (`createRequire()` over the | ||
| bundle output dir); `require()` can load ESM on Node >= 22, so modules resolve | ||
| without dynamic import. | ||
| ## License | ||
@@ -63,0 +106,0 @@ |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
37914
8.35%752
1.62%113
61.43%7
16.67%+ Added
- Removed
Updated