From c471c5e26e0aeec165113a08d5b0a0f8be162a23 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sun, 29 May 2022 15:58:48 -0700 Subject: [PATCH 1/2] module: add preImport loader hook --- doc/api/esm.md | 54 +++++- lib/internal/modules/cjs/loader.js | 10 +- lib/internal/modules/esm/loader.js | 248 ++++++++++-------------- lib/internal/modules/esm/translators.js | 2 +- lib/internal/process/esm_loader.js | 18 +- lib/internal/process/execution.js | 2 +- lib/repl.js | 4 +- 7 files changed, 176 insertions(+), 162 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index c5ef7eb863f6b7..d62ca92845ea17 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -734,6 +734,54 @@ A hook that returns without calling `next()` _and_ without returning `shortCircuit: true` also triggers an exception. These errors are to help prevent unintentional breaks in the chain. +#### `preImport(specifier, context)` + + + +> The loaders API is being redesigned. This hook may disappear or its +> signature may change. Do not rely on the API described below. + +* `specifier` {string} +* `context` {Object} + * `conditions` {string\[]} Resolution conditions of the current environment, + as defined for the `package.json` imports and exports fields + * `dynamic` {boolean} Whether this import is a dynamic `import()` (if *false*, + that means it is a host top-level import). + * `importAssertions` {Object} + * `parentURL` {string|undefined} The module importing this one, or undefined + if this is the Node.js entry point + +The `preImport` hook allows for tracking and asynchronous setup work for every +top-level import operation. It has no return value, although it can return +a promise to to delay the module pipeline operations. No further hooks will +be called on that module graph until this hook resolves successfully if present. + +The `preImport` hook is called for each top-level import operation by the module +loader, both for the host-called imports (ie for the main entry) and for dynamic +`import()` imports. These are distinguished by the `dynamic` context. + +All `preImport` hooks for all loaders are run asynchronously in parallel, and +block any further load operations (ie resolve and load) for the module graph +being imported until they all complete successfully. + +Multiple import calls to the same import specifier will re-call the hook +multiple times. The first error thrown by the `preImport` hooks will be directly +returned to the specific import operation as the load failure. + +```js +export async function preImport(specifier, context) { + if (context.topLevel) + console.log(`Top-level load of ${specifier}`); + else + console.log(`Dynamic import of ${specifier} in ${context.parentURL}`); +} +``` + #### `resolve(specifier, context, nextResolve)`