Context
Follow-up from PR #309. React (+ react-dom, scheduler) is currently externalized to esm.sh in production via an import map (vite-plugins/reactImportMapMode.ts), with SRI integrity. Because those URLs are absolute + cross-origin, they're excluded from the service worker's dist/-walking same-origin precache.
In #309 we closed the resulting offline gap with option A: the SW now precaches the exact import-map integrity set (the esm.sh React URLs) into its shared vendor cache at install, so a controlled offline load can resolve React. That makes offline work, but keeps the cross-origin dependency and a bespoke vendor-precache path.
This issue tracks option C: stop externalizing React and bundle it same-origin instead.
Why it might be worth doing
- Simpler offline story. Same-origin React would be emitted under
dist/ and covered automatically by the existing full-graph precache — no separate precacheVendor list, no import-map integrity plumbing, no cross-origin km-vendor cache.
- One fewer external dependency at boot. Today a cold first load reaches esm.sh for React; a same-origin bundle removes that third-party runtime dependency (availability, SRI-pinning, CDN policy).
- Generation consistency for React too. Same-origin React would live in each generation's namespaced asset cache like everything else, rather than a shared un-namespaced vendor cache.
Why we externalized in the first place (trade-offs to weigh)
- esm.sh gives a shared, immutable, cross-origin-cached React that multiple deploys/previews reuse without re-downloading.
- Externalizing keeps React out of the same-origin bundle, shrinking first-party JS.
- The import map lets user extensions import
react/react-dom by bare specifier at runtime and resolve to the same singleton React the app uses. Bundling must preserve this — extensions still need a single shared React instance (e.g. expose it on a same-origin module the import map points at, rather than an esm.sh URL). This is the load-bearing constraint and the main reason to think carefully before switching.
Scope
- Evaluate whether bundling React same-origin (while preserving the single-shared-instance guarantee for user extensions) is worth the bundle-size / CDN-cache trade.
- If yes: point the production import map at a same-origin React module, drop
productionReactIntegrity + the SW precacheVendor path (option A becomes unnecessary), and confirm extensions still resolve one shared React.
Not urgent — offline works today via option A. This is a simplification/robustness question, not a bug.
Context
Follow-up from PR #309. React (+ react-dom, scheduler) is currently externalized to esm.sh in production via an import map (
vite-plugins/reactImportMapMode.ts), with SRI integrity. Because those URLs are absolute + cross-origin, they're excluded from the service worker'sdist/-walking same-origin precache.In #309 we closed the resulting offline gap with option A: the SW now precaches the exact import-map integrity set (the esm.sh React URLs) into its shared vendor cache at install, so a controlled offline load can resolve React. That makes offline work, but keeps the cross-origin dependency and a bespoke vendor-precache path.
This issue tracks option C: stop externalizing React and bundle it same-origin instead.
Why it might be worth doing
dist/and covered automatically by the existing full-graph precache — no separateprecacheVendorlist, no import-map integrity plumbing, no cross-originkm-vendorcache.Why we externalized in the first place (trade-offs to weigh)
react/react-domby bare specifier at runtime and resolve to the same singleton React the app uses. Bundling must preserve this — extensions still need a single shared React instance (e.g. expose it on a same-origin module the import map points at, rather than an esm.sh URL). This is the load-bearing constraint and the main reason to think carefully before switching.Scope
productionReactIntegrity+ the SWprecacheVendorpath (option A becomes unnecessary), and confirm extensions still resolve one shared React.Not urgent — offline works today via option A. This is a simplification/robustness question, not a bug.