Repository navigation
Proposal: preImport loader hook #83
Description
Activity
- addedloaders-agendaIssues and PRs to discuss during the meetings of the Loaders teamIssues and PRs to discuss during the meetings of the Loaders team
on Jun 19, 2022 This is an interesting idea! I have a couple questions:
-
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.Is this effectively a
Promise.all()orPromise.race()? Also, why? I'm a little confused by why they should run in parallel. -
In your example, you have
if (context.topLevel), buttopLevelis not incontextcurrently or in your proposed additions. What does it mean? I presume top-level await, but that's whatdynamicintends to identify, no?
I'm a little concerned by the
preprefixes: I already findglobalPreloadconfusing (it's effectively a “setup” step). I think if we introduce this new hook, we should re-visit theglobalPreloadname (especially because it does not behave like the other hooks).P.S. Sorry for the delayed reply; I'm only just seeing this now.
-
Is this effectively a Promise.all() or Promise.race()? Also, why? I'm a little confused by why they should run in parallel.
It's a
Promise.all, the reason being that is the most performant design when we don't want to unnecessarily serialize to slow down imports. If two loaders both want to do fs / network / other async operations when a new import is initiated, there's no reason they need to block eachother.In your example, you have if (context.topLevel), but topLevel is not in context currently or in your proposed additions. What does it mean? I presume top-level await, but that's what dynamic intends to identify, no?
Ahh thanks for spotting the issue in the example, that should be
context.dynamicyes. I've gone back and fourth on the wording to get something clear. A top-level import is basically an import which will run the ECMA-262 top-levelEvaluationfunction - https://tc39.es/ecma262/#sec-moduleevaluation. Not all modules go through a whole graph execution operation (eg most dependencies).topLevelis perhaps more descriptive thandynamic, but both likely need clarification. I have a better definition in the current readme update I'll add to the PR now.I'm a little concerned by the pre prefixes: I already find globalPreload confusing (it's effectively a “setup” step). I think if we introduce this new hook, we should re-visit the globalPreload name (especially because it does not behave like the other hooks).
My preference would have been to just call it the
importhook, butexport function import()isn't supported in ECMA-262 unfortunately. I'm open to alternative names, egbeforeImportorimportHookorprepareImportetc.Yes, both
globalPreloadandpreImportare effectively non-chainable hooks which can run without blocking other hooks. They fall under a different parallel hook model. In the loader documentation it could be worth eg explicitly documenting the "hook type" of each hook something likeHook Type: Sync ChainedorHook Type: Async Parallel, and there may also be other variants in future.Reacted by Jacob Smith- removedloaders-agendaIssues and PRs to discuss during the meetings of the Loaders teamIssues and PRs to discuss during the meetings of the Loaders team
on Jul 1, 2022 Closing in favor of #89
A
preImporthook can take the place of the async use cases for having an async resolver hook by allowing any async work to be done upfront before triggering the further pipeline steps. For example, loading an import map could be an async operation prior to synchronously using that import map in resolution (which is exactly what the browser does).Ultimately, the goal would be that by covering these needs, this should allow for a synchronous core resolver which would enable unification with browser resolution.
The initial hook PR would not deprecate the resolver yet, and could be released to get feedback on this first, before following up with a subsequent async resolver deprecation.
There is a basic draft API in nodejs/node#43245, with the following documentation: