Skip to content

Commit

Permalink
module: add preImport loader hook
Browse files Browse the repository at this point in the history
  • Loading branch information
guybedford committed Jun 19, 2022
1 parent f209aee commit c471c5e
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 162 deletions.
54 changes: 52 additions & 2 deletions doc/api/esm.md
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,54 @@ A hook that returns without calling `next<hookName>()` _and_ without returning
`shortCircuit: true` also triggers an exception. These errors are to help
prevent unintentional breaks in the chain.
#### `preImport(specifier, context)`
<!-- YAML
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/43245
description: Add support for preImport hook.
-->
> 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)`
<!-- YAML
Expand All @@ -758,7 +806,8 @@ changes:
* `specifier` {string}
* `context` {Object}
* `conditions` {string\[]} Export conditions of the relevant `package.json`
* `conditions` {string\[]} Resolution conditions of the current environment,
as defined for the `package.json` imports and exports fields
* `importAssertions` {Object}
* `parentURL` {string|undefined} The module importing this one, or undefined
if this is the Node.js entry point
Expand Down Expand Up @@ -851,7 +900,8 @@ changes:
* `url` {string} The URL returned by the `resolve` chain
* `context` {Object}
* `conditions` {string\[]} Export conditions of the relevant `package.json`
* `conditions` {string\[]} Resolution conditions of the current environment,
as defined for the `package.json` imports and exports fields
* `format` {string|null|undefined} The format optionally supplied by the
`resolve` hook chain
* `importAssertions` {Object}
Expand Down
10 changes: 6 additions & 4 deletions lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -1036,8 +1036,9 @@ function wrapSafe(filename, content, cjsModuleInstance) {
displayErrors: true,
importModuleDynamically: async (specifier, _, importAssertions) => {
const loader = asyncESM.esmLoader;
return loader.import(specifier, normalizeReferrerURL(filename),
importAssertions);
return loader.import(specifier,
normalizeReferrerURL(filename),
importAssertions, true);
},
});
}
Expand All @@ -1052,8 +1053,9 @@ function wrapSafe(filename, content, cjsModuleInstance) {
filename,
importModuleDynamically(specifier, _, importAssertions) {
const loader = asyncESM.esmLoader;
return loader.import(specifier, normalizeReferrerURL(filename),
importAssertions);
return loader.import(specifier,
normalizeReferrerURL(filename),
importAssertions, true);
},
});
} catch (err) {
Expand Down
Loading

0 comments on commit c471c5e

Please sign in to comment.