Skip to content

Add moduleRequest to modulepreload fetch parameters#12223

Open
KurtCattiSchmidt wants to merge 7 commits intowhatwg:mainfrom
KurtCattiSchmidt:modulepreload-request
Open

Add moduleRequest to modulepreload fetch parameters#12223
KurtCattiSchmidt wants to merge 7 commits intowhatwg:mainfrom
KurtCattiSchmidt:modulepreload-request

Conversation

@KurtCattiSchmidt
Copy link
Contributor

@KurtCattiSchmidt KurtCattiSchmidt commented Mar 3, 2026

Fixes #12214

  • At least two implementers are interested (and none opposed):
  • Tests are written and can be reviewed and commented upon at:
  • Implementation bugs are filed:
    • Chromium: …
    • Gecko: …
    • WebKit: …
    • Deno (only for timers, structured clone, base64 utils, channel messaging, module resolution, web workers, and web storage): …
    • Node.js (only for timers, structured clone, base64 utils, channel messaging, and module resolution): …
  • Corresponding HTML AAM & ARIA in HTML issues & PRs:
  • MDN issue is filed: …
  • The top of this comment includes a clear commit message to use.

(See WHATWG Working Mode: Changes for more details.)


/webappapis.html ( diff )

@KurtCattiSchmidt KurtCattiSchmidt requested review from annevk and noamr March 3, 2026 17:13
@Gae24
Copy link

Gae24 commented Mar 3, 2026

I was thinking that module type from module request should be performed inside fetch a single imported module script and then optionally passing moduleType; I don't see a reason to have a ModuleRequest record when fetching a modulepreload.

@annevk
Copy link
Member

annevk commented Mar 3, 2026

cc @nicolo-ribaudo

@KurtCattiSchmidt
Copy link
Contributor Author

I was thinking that module type from module request should be performed inside fetch a single imported module script and then optionally passing moduleType; I don't see a reason to have a ModuleRequest record when fetching a modulepreload.

I may be misunderstanding - the original issue referenced #11981, which allows modulepreload to preload JSON and CSS module scripts. Module preloads never reach fetch a single imported module script - they go directly to fetch a single module script from fetch a modulepreload module script graph.

This approach came from @annevk's remark #12214 (comment) - since modulepreload doesn't have a request, it can't deduce the module type in fetch a single module script.

@Gae24
Copy link

Gae24 commented Mar 3, 2026

I was thinking that module type from module request should be performed inside fetch a single imported module script and then optionally passing moduleType; I don't see a reason to have a ModuleRequest record when fetching a modulepreload.

I may be misunderstanding - the original issue referenced #11981, which allows modulepreload to preload JSON and CSS module scripts. Module preloads never reach fetch a single imported module script - they go directly to fetch a single module script from fetch a modulepreload module script graph.

This approach came from @annevk's remark #12214 (comment) - since modulepreload doesn't have a request, it can't deduce the module type in fetch a single module script.

Sorry I was not clear, by running module type from module request inside fetch a single imported module script, fetch a single module script will optionally have a moduleType instead of a ModuleRequest record.
Instead fetch a modulepreload module script graph will obtain moduleType from module-type-from-fetch-destination added in this PR.

@KurtCattiSchmidt
Copy link
Contributor Author

Sorry I was not clear, by running module type from module request inside fetch a single imported module script, fetch a single module script will optionally have a moduleType instead of a ModuleRequest record.
Instead fetch a modulepreload module script graph will obtain moduleType from module-type-from-fetch-destination added in this PR.

Ok, I think I understand now. fetch a single imported module script already has module type from module request as step 2.

Are you suggesting adding moduleType as a parameter to fetch a single module script and passing that through in both places? The reason why I didn't do that initially is that fetch a single module script already has moduleRequest, which has the module type, so I didn't want to duplicate that.

@Gae24
Copy link

Gae24 commented Mar 4, 2026

Sorry I was not clear, by running module type from module request inside fetch a single imported module script, fetch a single module script will optionally have a moduleType instead of a ModuleRequest record.
Instead fetch a modulepreload module script graph will obtain moduleType from module-type-from-fetch-destination added in this PR.

Ok, I think I understand now. fetch a single imported module script already has module type from module request as step 2.

Are you suggesting adding moduleType as a parameter to fetch a single module script and passing that through in both places? The reason why I didn't do that initially is that fetch a single module script already has moduleRequest, which has the module type, so I didn't want to duplicate that.

My suggestion is to replace moduleRequest with moduleType

@KurtCattiSchmidt
Copy link
Contributor Author

My suggestion is to replace moduleRequest with moduleType

You're right, that is a lot better! Addressed in the latest version. I believe I got all of the entry points handled - let me know if there's anything I'm missing.

source Outdated
<li><p>If <var>moduleRequest</var> was given, then set <var>moduleType</var> to the result of
running the <span>module type from module request</span> steps given
<var>moduleRequest</var>.</p></li>
<li><p>If <var>moduleType</var> is null, set <var>moduleType</var> to "<code
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not fully familiar with all the syntax nuances of the spec yet, but I think since moduleType is an optional argument we should keep but rephrase If moduleType was given, then set moduleType to moduleType.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you get it from the destination parameter you already have rather than pass it as an additional parameter? You have to do that for modulepreload anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment implies that this approach won't work, but I think it covers it. @noamr, what do you think?

source Outdated
Comment on lines +28489 to +28490
<li><p>Let <var>moduleType</var> be the result of running
<span>module type from fetch destination</span> on <var>destination</var>.</p></li>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move this inside fetch a modulepreload module script graph.

source Outdated
<li><p>If <var>moduleRequest</var> was given, then set <var>moduleType</var> to the result of
running the <span>module type from module request</span> steps given
<var>moduleRequest</var>.</p></li>
<li><p>If <var>moduleType</var> is null, set <var>moduleType</var> to "<code
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you get it from the destination parameter you already have rather than pass it as an additional parameter? You have to do that for modulepreload anyway.

@KurtCattiSchmidt
Copy link
Contributor Author

Thanks for the suggestions @noamr and @Gae24! This is looking a lot cleaner. One weird part is that https://html.spec.whatwg.org/#fetch-a-single-imported-module-script gets moduleType, validates, and discards it, and it's queried again from https://html.spec.whatwg.org/#fetch-a-single-module-script. This seems preferable over an optional parameter and removes a lot of duplication, so it seems fine to me.

Comment on lines +117447 to +117448
<li><p>Let <var>moduleType</var> be the result of running
<span>module type from fetch destination</span> on <var>destination</var>.</p></li>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately this wont cover all the cases. When fetching a single imported module script, destination will either be script or the value stored inside LoadState (eg. worker, sharedworker).
We still need to resolve moduleType from moduleRequest record in this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

module type from fetch destination currently covers that, because the default case there is "javascript-or-wasm", which all of those request destinations are (worker, sharedworker), right?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, moduleType will be javascript-or-wasm even when fetching json or css modules. That's because moduleType is determined by the moduleRequest record not by the top-level destination.

@nicolo-ribaudo nicolo-ribaudo self-requested a review March 20, 2026 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

fetch a single module script always defaults to javascript modules for top level fetches

4 participants