feat(offline): app-shell precache service worker (vite-plugin-pwa)
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 18s
CI / ui (pull_request) Successful in 1m11s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m43s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 18s
CI / ui (pull_request) Successful in 1m11s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m43s
Migrate the former install-only public/sw.js to a custom (injectManifest)
service worker built from ui/src/sw.ts by vite-plugin-pwa. It precaches the
app shell + hashed assets (Workbox) so an installed web PWA cold-launches with
no network, and falls in-scope navigations back to the precached shell (the
hash router resolves the route client-side). This is the C1 prerequisite for a
usable offline mode: without it a cold offline launch cannot load the bundle.
- ui/src/sw.ts: skipWaiting + clientsClaim + cleanupOutdatedCaches +
precacheAndRoute(__WB_MANIFEST) + a NavigationRoute fallback to index.html,
deny-listing the RPC path and /_gm. The Connect stream and API POSTs are
never precached nor intercepted.
- vite.config.ts: VitePWA(injectManifest); manifest:false (we ship our own),
injectRegister:false (registration stays manual + web-only in pwa.svelte.ts),
disabled in the mock build (Playwright unperturbed); landing + polyfills
excluded from the precache.
- Removed public/sw.js; the registration path (dist/sw.js at /app/) is unchanged.
- New dev deps: vite-plugin-pwa + workbox-{core,precaching,routing}.
Docs: ARCHITECTURE + gateway/README. Offline cold-launch is contour-verified
(the mock e2e harness disables the SW).
This commit is contained in:
+27
-1
@@ -2,6 +2,7 @@ import { readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
import { defineConfig, type Plugin } from 'vite';
|
||||
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
||||
import { VitePWA } from 'vite-plugin-pwa';
|
||||
|
||||
/**
|
||||
* injectBootVersion stamps the app version into index.html's boot-capability guard, replacing its
|
||||
@@ -56,7 +57,32 @@ export default defineConfig(({ mode }) => ({
|
||||
},
|
||||
// emitPolyfills ships dist/polyfills.js (loaded only by old engines; see its docstring + the
|
||||
// index.html boot guard). injectBootVersion stamps the app version into that guard's diagnostic.
|
||||
plugins: [svelte(), emitPolyfills(), injectBootVersion()],
|
||||
plugins: [
|
||||
svelte(),
|
||||
emitPolyfills(),
|
||||
injectBootVersion(),
|
||||
// App-shell precache for the offline mode: a custom (injectManifest) service worker precaches
|
||||
// index.html + the hashed assets so the installed web PWA cold-launches with no network. It
|
||||
// supersedes the former install-only public/sw.js and outputs to dist/sw.js (same path, so the
|
||||
// existing /app/ registration is unchanged). Registration is manual + web-only (injectRegister
|
||||
// off; see pwa.svelte.ts) and the whole plugin is disabled in the mock build so Playwright is
|
||||
// never perturbed. manifest:false — we already ship public/manifest.webmanifest.
|
||||
VitePWA({
|
||||
strategies: 'injectManifest',
|
||||
srcDir: 'src',
|
||||
filename: 'sw.ts',
|
||||
injectRegister: false,
|
||||
manifest: false,
|
||||
disable: mode === 'mock',
|
||||
injectManifest: {
|
||||
// The app shell only: exclude the separate landing page and the conditional polyfill bundle
|
||||
// (loaded document.write-only on an old engine; never part of the offline shell).
|
||||
globPatterns: ['**/*.{js,css,html,svg,png,ico,woff,woff2}'],
|
||||
globIgnores: ['**/landing*', '**/polyfills.js'],
|
||||
},
|
||||
devOptions: { enabled: false },
|
||||
}),
|
||||
],
|
||||
server: {
|
||||
port: 5173,
|
||||
proxy:
|
||||
|
||||
Reference in New Issue
Block a user