Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use import maps for bundle manifest #10073

Merged
merged 2 commits into from
Jan 20, 2025
Merged

Use import maps for bundle manifest #10073

merged 2 commits into from
Jan 20, 2025

Conversation

devongovett
Copy link
Member

This refactors Parcel's bundle manifest, which is used to avoid cascading cache invalidation, to use native HTML import maps when possible. This happens when using HTML entry points, ES module output format, and when import.meta.resolve is supported. In this case, a <script type="importmap"> is automatically injected into the HTML entry point. This means it won't invalidate the entry JS bundle when it otherwise doesn't change, which benefits many apps that have large entries. In addition, it is not a separate HTTP request to load the manifest since it is embedded in the HTML itself. It also removes additional runtime code to resolve the manifest, instead relying on import.meta.resolve.

For React Server Components, we cannot currently use native import maps because of client side navigations, where a new HTML file is not requested. Eventually, multiple <script type="importmap"> elements will be supported (whatwg/html#10528) (coming Chrome 133), at which point React could potentially inject them. In the meantime, this adds two new APIs: parcelRequire.extendImportMap registers mappings, and parcelRequire.resolve (and parcelRequire.load) resolves them. An import map is added as part of the RSC client reference, and registered prior to loading the client bundles. Dynamic imports, URL dependencies, workers, etc. then use this mapping. In effect, this is the same as native import maps (it is injected into the initial HTML), but the map can be extended during client side navigations (or whenever new RSCs are loaded) too.

@devongovett devongovett merged commit 1b46893 into v2 Jan 20, 2025
16 of 17 checks passed
@devongovett devongovett deleted the import-maps branch January 20, 2025 19:08
sebmarkbage pushed a commit to facebook/react that referenced this pull request Jan 27, 2025
Corresponding Parcel PR:
parcel-bundler/parcel#10073

Parcel avoids [cascading cache
invalidation](https://philipwalton.com/articles/cascading-cache-invalidation/)
by injecting a bundle manifest containing a mapping of stable bundle ids
to hashed URLs. When using an HTML entry point, this is done (as of the
above PR) via a native import map. This means that if a bundle's hash
changes, only that bundle will be invalidated (plus the HTML itself
which typically has a short caching policy), not any other bundles that
reference it.

For RSCs, we cannot currently use native import maps because of client
side navigations, where a new HTML file is not requested. Eventually,
multiple `<script type="importmap">` elements will be supported
(whatwg/html#10528) ([coming Chrome
133](https://chromestatus.com/feature/5121916248260608)), at which point
React could potentially inject them. In the meantime, I've added some
APIs to Parcel to polyfill this. With this change, an import map can be
sent along with a client reference, containing a mapping for any dynamic
imports and URL dependencies (e.g. images) that are referenced by the JS
bundles. On the client, the import map is extended with these new
mappings prior to executing the referenced bundles. This preserves the
caching advantages described above while supporting client navigations.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant