From 6cdd26ae64c226b38fa9693a3b706a6a5bd9e356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Rialland?= Date: Mon, 4 Jul 2022 17:10:00 +0200 Subject: [PATCH] Rework PWA with injectManifest strategy --- site/netlify.base.toml | 7 ++++- site/package.json | 6 +++- site/source/sw.ts | 54 ++++++++++++++++++++++++++++++++++++ site/tsconfig.json | 1 + site/vite.config.ts | 63 +++++++----------------------------------- yarn.lock | 22 +++++++++------ 6 files changed, 89 insertions(+), 64 deletions(-) create mode 100644 site/source/sw.ts diff --git a/site/netlify.base.toml b/site/netlify.base.toml index 51bc118f4..21a0c222c 100644 --- a/site/netlify.base.toml +++ b/site/netlify.base.toml @@ -1,11 +1,16 @@ [[headers]] for = "/*" [headers.values] -Content-Security-Policy = "default-src 'self' mon-entreprise.fr; style-src 'self' 'unsafe-inline' mon-entreprise.zammad.com; connect-src 'self' *.incubateur.net raw.githubusercontent.com tm.urssaf.fr mon-entreprise.zammad.com api.recherche-entreprises.fabrique.social.gouv.fr geo.api.gouv.fr *.algolia.net *.algolianet.com; form-action 'self' *.sibforms.com *.incubateur.net mon-entreprise.zammad.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' tm.urssaf.fr *.incubateur.net stonly.com code.jquery.com mon-entreprise.zammad.com polyfill.io; img-src 'self' data: mon-entreprise.urssaf.fr tm.urssaf.fr user-images.githubusercontent.com jedonnemonavis.numerique.gouv.fr; frame-src 'self' https://www.youtube-nocookie.com https://codesandbox.io https://place-des-entreprises.beta.gouv.fr https://reso-staging.osc-fr1.scalingo.io https://stackblitz.com" +Content-Security-Policy = "default-src 'self' mon-entreprise.fr; style-src 'self' 'unsafe-inline' mon-entreprise.zammad.com; connect-src 'self' *.incubateur.net raw.githubusercontent.com tm.urssaf.fr mon-entreprise.zammad.com api.recherche-entreprises.fabrique.social.gouv.fr geo.api.gouv.fr *.algolia.net *.algolianet.com polyfill.io; form-action 'self' *.sibforms.com *.incubateur.net mon-entreprise.zammad.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' tm.urssaf.fr *.incubateur.net stonly.com code.jquery.com mon-entreprise.zammad.com polyfill.io; img-src 'self' data: mon-entreprise.urssaf.fr tm.urssaf.fr user-images.githubusercontent.com jedonnemonavis.numerique.gouv.fr; frame-src 'self' https://www.youtube-nocookie.com https://codesandbox.io https://place-des-entreprises.beta.gouv.fr https://reso-staging.osc-fr1.scalingo.io https://stackblitz.com" [dev] autoLaunch = false +[[headers]] + for = "/manifest.webmanifest" + [headers.values] + Content-Type = "application/manifest+json" + ## Scalingo proxy for API [[redirects]] from = "/api/*" diff --git a/site/package.json b/site/package.json index ccff7e18e..856a26156 100644 --- a/site/package.json +++ b/site/package.json @@ -143,9 +143,13 @@ "ts-node": "^10.8.0", "typescript": "^4.7.2", "vite": "^2.9.13", - "vite-plugin-pwa": "^0.12.1", + "vite-plugin-pwa": "^0.12.2", "vite-plugin-shim-react-pdf": "^1.0.5", "vitest": "^0.9.4", + "workbox-navigation-preload": "^6.5.3", + "workbox-precaching": "^6.5.3", + "workbox-routing": "^6.5.3", + "workbox-strategies": "^6.5.3", "workbox-window": "^6.5.3", "xml2js": "^0.4.23", "yaml": "^1.9.2" diff --git a/site/source/sw.ts b/site/source/sw.ts new file mode 100644 index 000000000..defa3f854 --- /dev/null +++ b/site/source/sw.ts @@ -0,0 +1,54 @@ +import { + cleanupOutdatedCaches, + createHandlerBoundToURL, + precacheAndRoute, +} from 'workbox-precaching' +import { NavigationRoute, registerRoute, Route } from 'workbox-routing' +import { NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies' + +declare let self: ServiceWorkerGlobalScope + +self.addEventListener('message', (event) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (event.data && event.data.type === 'SKIP_WAITING') { + void self.skipWaiting() + } +}) + +cleanupOutdatedCaches() + +precacheAndRoute(self.__WB_MANIFEST) + +// Allow work offline +registerRoute( + new NavigationRoute( + createHandlerBoundToURL( + location.href.startsWith(import.meta.env.VITE_FR_BASE_URL) + ? 'mon-entreprise.html' + : 'infrance.html' + ) + ) +) + +// StaleWhileRevalidate runtime cache +const staleWhileRevalidate = new Route(({ request, sameOrigin, url }) => { + return ( + sameOrigin && + (url.pathname.startsWith('/twemoji/') || request.destination === 'image') + ) +}, new StaleWhileRevalidate({ cacheName: 'images' })) + +registerRoute(staleWhileRevalidate) + +// NetworkFirst runtime cache +const networkFirst = new Route(({ sameOrigin, url }) => { + return ( + !sameOrigin && + [ + 'polyfill.io', + 'api.recherche-entreprises.fabrique.social.gouv.fr', + ].includes(url.hostname) + ) +}, new NetworkFirst({ cacheName: 'external' })) + +registerRoute(networkFirst) diff --git a/site/tsconfig.json b/site/tsconfig.json index 434a93e8a..95f294985 100644 --- a/site/tsconfig.json +++ b/site/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "lib": ["ESNext", "DOM", "WebWorker"], "baseUrl": "source", "moduleResolution": "node", "module": "esnext", diff --git a/site/vite.config.ts b/site/vite.config.ts index 15a7144e8..e9c1ea558 100644 --- a/site/vite.config.ts +++ b/site/vite.config.ts @@ -64,60 +64,17 @@ export default defineConfig(({ command, mode }) => ({ }), VitePWA({ registerType: 'prompt', - strategies: 'generateSW', - workbox: { - cleanupOutdatedCaches: true, - clientsClaim: true, - skipWaiting: true, - sourcemap: true, - runtimeCaching: [ - { - urlPattern: (options) => { - if ( - !( - options.sameOrigin && - options.url.pathname.startsWith('/twemoji/') - ) && - !(!options.sameOrigin && options.url.hostname === 'polyfill.io') - ) { - console.log('=>', options.url.pathname) - } - - return ( - options.sameOrigin && - options.url.pathname.startsWith('/twemoji/') - ) - }, - handler: 'StaleWhileRevalidate', - options: { - cacheName: 'twemoji-cache', - expiration: { - maxEntries: 10, - maxAgeSeconds: 1 * YEAR, - }, - cacheableResponse: { - statuses: [0, 200], - }, - }, - }, - { - urlPattern: (options) => - !options.sameOrigin && options.url.hostname === 'polyfill.io', - handler: 'NetworkFirst', - options: { - cacheName: 'external-cache', - expiration: { - maxEntries: 10, - maxAgeSeconds: 1 * DAY, - }, - cacheableResponse: { - statuses: [0, 200], - }, - }, - }, - ], + strategies: 'injectManifest', + srcDir: 'source', + filename: 'sw.ts', + injectManifest: { + maximumFileSizeToCacheInBytes: 3000000, }, - includeAssets: ['fonts/*.{woff,woff2}', 'favicon/*.{ico,png,svg,xml}'], + includeAssets: [ + 'logo-*.png', + 'fonts/*.{woff,woff2}', + 'références-images/*.{jpg,png,svg}', + ], manifest: { start_url: '/', name: 'Mon entreprise', diff --git a/yarn.lock b/yarn.lock index 0d664a0a2..fd9802a50 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25422,10 +25422,14 @@ __metadata: ts-node: ^10.8.0 typescript: ^4.7.2 vite: ^2.9.13 - vite-plugin-pwa: ^0.12.1 + vite-plugin-pwa: ^0.12.2 vite-plugin-shim-react-pdf: ^1.0.5 vitest: ^0.9.4 whatwg-fetch: ^3.0.0 + workbox-navigation-preload: ^6.5.3 + workbox-precaching: ^6.5.3 + workbox-routing: ^6.5.3 + workbox-strategies: ^6.5.3 workbox-window: ^6.5.3 xml2js: ^0.4.23 yaml: ^1.9.2 @@ -28089,9 +28093,9 @@ __metadata: languageName: node linkType: hard -"vite-plugin-pwa@npm:^0.12.1": - version: 0.12.1 - resolution: "vite-plugin-pwa@npm:0.12.1" +"vite-plugin-pwa@npm:^0.12.2": + version: 0.12.2 + resolution: "vite-plugin-pwa@npm:0.12.2" dependencies: debug: ^4.3.4 fast-glob: ^3.2.11 @@ -28103,7 +28107,7 @@ __metadata: vite: ^2.0.0 || ^3.0.0-0 workbox-build: ^6.4.0 workbox-window: ^6.4.0 - checksum: 5f1a60ed2a02f5aaeb7f7a130612e45585547d27aa0c51f484ccbca4b74a3392a6245f8bc6c735fecda4a759682b2bd7a846c4bf6a0febe2dfcdae6ec789318b + checksum: 4bddb8d9dff2ff777adeef864ea5f3145a9c14807a6912f1d6aaa17c785724f84100ec4a7a55c1e9bd8644d42b6707f49faa6c1070d47800e4383013cc34716f languageName: node linkType: hard @@ -28774,7 +28778,7 @@ __metadata: languageName: node linkType: hard -"workbox-navigation-preload@npm:6.5.3": +"workbox-navigation-preload@npm:6.5.3, workbox-navigation-preload@npm:^6.5.3": version: 6.5.3 resolution: "workbox-navigation-preload@npm:6.5.3" dependencies: @@ -28783,7 +28787,7 @@ __metadata: languageName: node linkType: hard -"workbox-precaching@npm:6.5.3": +"workbox-precaching@npm:6.5.3, workbox-precaching@npm:^6.5.3": version: 6.5.3 resolution: "workbox-precaching@npm:6.5.3" dependencies: @@ -28817,7 +28821,7 @@ __metadata: languageName: node linkType: hard -"workbox-routing@npm:6.5.3": +"workbox-routing@npm:6.5.3, workbox-routing@npm:^6.5.3": version: 6.5.3 resolution: "workbox-routing@npm:6.5.3" dependencies: @@ -28826,7 +28830,7 @@ __metadata: languageName: node linkType: hard -"workbox-strategies@npm:6.5.3": +"workbox-strategies@npm:6.5.3, workbox-strategies@npm:^6.5.3": version: 6.5.3 resolution: "workbox-strategies@npm:6.5.3" dependencies: