From 446c6e657b6eb48f81e6c2a8cc42a8ca35ef021e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez=20Jim=C3=A9nez?= Date: Sun, 28 Nov 2021 20:38:34 +0100 Subject: [PATCH 01/29] feat: add sveltekit example --- docs/.vitepress/config.js | 10 +- docs/examples/index.md | 15 + docs/examples/sveltekit.md | 81 ++++ docs/frameworks/index.md | 3 + docs/frameworks/sveltekit.md | 143 +++++++ examples/preact-router/package.json | 7 + examples/preact-router/src/claims-sw.ts | 17 + .../preact-router/src/{sw.ts => prompt-sw.ts} | 0 examples/preact-router/vite.config.ts | 17 +- examples/react-router/package.json | 7 + examples/react-router/src/claims-sw.ts | 17 + .../react-router/src/{sw.ts => prompt-sw.ts} | 0 examples/react-router/vite.config.ts | 17 +- examples/solid-router/package.json | 7 + examples/solid-router/src/ReloadPrompt.tsx | 24 +- examples/solid-router/src/claims-sw.ts | 17 + .../solid-router/src/{sw.ts => prompt-sw.ts} | 0 examples/solid-router/vite.config.ts | 17 +- examples/svelte-routify/package.json | 7 + examples/svelte-routify/src/claims-sw.ts | 17 + .../src/lib/ReloadPrompt.svelte | 52 +-- .../src/{sw.ts => prompt-sw.ts} | 0 examples/svelte-routify/vite.config.js | 17 +- examples/sveltekit-pwa/.eslintrc.cjs | 20 + examples/sveltekit-pwa/.gitignore | 7 + examples/sveltekit-pwa/README.md | 38 ++ examples/sveltekit-pwa/package.json | 53 +++ examples/sveltekit-pwa/pwa-configuration.js | 93 +++++ examples/sveltekit-pwa/pwa.js | 57 +++ examples/sveltekit-pwa/src/app.html | 16 + examples/sveltekit-pwa/src/claims-sw.ts | 17 + examples/sveltekit-pwa/src/global.d.ts | 4 + .../src/lib/components/Counter.svelte | 34 ++ .../src/lib/components/Go.svelte | 55 +++ .../src/lib/components/ReloadPrompt.svelte | 88 ++++ examples/sveltekit-pwa/src/prompt-sw.ts | 18 + .../sveltekit-pwa/src/routes/__layout.svelte | 58 +++ .../sveltekit-pwa/src/routes/about.svelte | 8 + .../sveltekit-pwa/src/routes/hi/[name].svelte | 16 + .../sveltekit-pwa/src/routes/index.svelte | 16 + examples/sveltekit-pwa/static/favicon.svg | 130 ++++++ examples/sveltekit-pwa/static/pwa-192x192.png | Bin 0 -> 15230 bytes examples/sveltekit-pwa/static/pwa-512x512.png | Bin 0 -> 55738 bytes examples/sveltekit-pwa/svelte.config.js | 27 ++ examples/sveltekit-pwa/tsconfig.json | 31 ++ examples/vue-router/package.json | 7 + examples/vue-router/src/claims-sw.ts | 17 + .../vue-router/src/{sw.ts => prompt-sw.ts} | 0 examples/vue-router/vite.config.ts | 17 +- pnpm-lock.yaml | 378 +++++++++++++++++- scripts/run-examples.ts | 94 ++--- 51 files changed, 1660 insertions(+), 131 deletions(-) create mode 100644 docs/examples/sveltekit.md create mode 100644 docs/frameworks/sveltekit.md create mode 100644 examples/preact-router/src/claims-sw.ts rename examples/preact-router/src/{sw.ts => prompt-sw.ts} (100%) create mode 100644 examples/react-router/src/claims-sw.ts rename examples/react-router/src/{sw.ts => prompt-sw.ts} (100%) create mode 100644 examples/solid-router/src/claims-sw.ts rename examples/solid-router/src/{sw.ts => prompt-sw.ts} (100%) create mode 100644 examples/svelte-routify/src/claims-sw.ts rename examples/svelte-routify/src/{sw.ts => prompt-sw.ts} (100%) create mode 100644 examples/sveltekit-pwa/.eslintrc.cjs create mode 100644 examples/sveltekit-pwa/.gitignore create mode 100644 examples/sveltekit-pwa/README.md create mode 100644 examples/sveltekit-pwa/package.json create mode 100644 examples/sveltekit-pwa/pwa-configuration.js create mode 100644 examples/sveltekit-pwa/pwa.js create mode 100644 examples/sveltekit-pwa/src/app.html create mode 100644 examples/sveltekit-pwa/src/claims-sw.ts create mode 100644 examples/sveltekit-pwa/src/global.d.ts create mode 100644 examples/sveltekit-pwa/src/lib/components/Counter.svelte create mode 100644 examples/sveltekit-pwa/src/lib/components/Go.svelte create mode 100644 examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte create mode 100644 examples/sveltekit-pwa/src/prompt-sw.ts create mode 100644 examples/sveltekit-pwa/src/routes/__layout.svelte create mode 100644 examples/sveltekit-pwa/src/routes/about.svelte create mode 100644 examples/sveltekit-pwa/src/routes/hi/[name].svelte create mode 100644 examples/sveltekit-pwa/src/routes/index.svelte create mode 100644 examples/sveltekit-pwa/static/favicon.svg create mode 100644 examples/sveltekit-pwa/static/pwa-192x192.png create mode 100644 examples/sveltekit-pwa/static/pwa-512x512.png create mode 100644 examples/sveltekit-pwa/svelte.config.js create mode 100644 examples/sveltekit-pwa/tsconfig.json create mode 100644 examples/vue-router/src/claims-sw.ts rename examples/vue-router/src/{sw.ts => prompt-sw.ts} (100%) diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index 65c484af..aed54ce8 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -83,6 +83,10 @@ const Frameworks = [ text: 'Svelte', link: '/frameworks/svelte', }, + { + text: 'SvelteKit', + link: '/frameworks/sveltekit', + }, { text: 'SolidJS', link: '/frameworks/solidjs', @@ -114,6 +118,10 @@ const Examples = [ text: 'Svelte', link: '/examples/svelte', }, + { + text: 'SvelteKit', + link: '/examples/sveltekit', + }, { text: 'SolidJS', link: '/examples/solidjs', @@ -195,7 +203,7 @@ const config = { ['link', { rel: 'alternate icon', href: '/favicon.ico', type: 'image/png', sizes: '16x16' }], ['link', { rel: 'mask-icon', href: '/safari-pinned-tab.svg', color: '#ffffff' }], ['meta', { name: 'author', content: 'Anthony Fu' }], - ['meta', { name: 'keywords', content: 'pwa, workbox, vite, vite-plugin' }], + ['meta', { name: 'keywords', content: 'react, pwa, vue, preact, svelte, sveltekit, workbox, solidjs, vite, vite-plugin' }], ['meta', { property: 'og:title', content: 'Vite Plugin PWA' }], ['meta', { property: 'og:description', content: 'Zero-config PWA Framework-agnostic Plugin for Vite' }], ['meta', { name: 'twitter:card', content: 'summary_large_image' }], diff --git a/docs/examples/index.md b/docs/examples/index.md index bc2fdfc9..aca73b7f 100644 --- a/docs/examples/index.md +++ b/docs/examples/index.md @@ -137,6 +137,21 @@ We provide the following example projects: + + + + @@ -117,7 +117,7 @@ We provide the following example projects: - + @@ -132,7 +132,7 @@ We provide the following example projects: - + @@ -147,7 +147,7 @@ We provide the following example projects: - + @@ -162,7 +162,7 @@ We provide the following example projects: - + @@ -177,7 +177,7 @@ We provide the following example projects: - + diff --git a/docs/examples/preact.md b/docs/examples/preact.md index 2015d6cb..04f87cd7 100644 --- a/docs/examples/preact.md +++ b/docs/examples/preact.md @@ -37,31 +37,8 @@ If you are running an example with `Periodic SW updates`, you will need to wait ## generateSW -`generateSW` has the following behaviors: -- `Prompt for update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - -- `Auto update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - When new content available, the service worker will be updated automatically. - -- `Prompt for update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - - The example project will register a `Periodic service worker updates` - -- `Auto update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - The example project will register a `Periodic service worker updates` - - When new content available, the service worker will be updated automatically. + ## injectManifest -`injectManifest` has the following behavior: -- Custom `TypeScript Service Worker` with offline support. -- Show `Ready to work offlline` on first visit and once the `service worker` ready. -- Show `Prompt for update` when new `service worker` available. - - - + diff --git a/docs/examples/react.md b/docs/examples/react.md index 089048f3..3cbfa709 100644 --- a/docs/examples/react.md +++ b/docs/examples/react.md @@ -36,28 +36,8 @@ If you are running an example with `Periodic SW updates`, you will need to wait ## generateSW -`generateSW` has the following behaviors: -- `Prompt for update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - -- `Auto update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - When new content available, the service worker will be updated automatically. - -- `Prompt for update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - - The example project will register a `Periodic service worker updates` - -- `Auto update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - The example project will register a `Periodic service worker updates` - - When new content available, the service worker will be updated automatically. + ## injectManifest -`injectManifest` has the following behavior: -- Custom `TypeScript Service Worker` with offline support. -- Show `Ready to work offlline` on first visit and once the `service worker` ready. -- Show `Prompt for update` when new `service worker` available. + diff --git a/docs/examples/solidjs.md b/docs/examples/solidjs.md index 34e3aaa1..3bb52d66 100644 --- a/docs/examples/solidjs.md +++ b/docs/examples/solidjs.md @@ -25,28 +25,9 @@ If you are running an example with `Periodic SW updates`, you will need to wait ## generateSW -`generateSW` has the following behaviors: -- `Prompt for update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - -- `Auto update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - When new content available, the service worker will be updated automatically. - -- `Prompt for update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - - The example project will register a `Periodic service worker updates` - -- `Auto update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - The example project will register a `Periodic service worker updates` - - When new content available, the service worker will be updated automatically. + ## injectManifest -`injectManifest` has the following behavior: -- Custom `TypeScript Service Worker` with offline support. -- Show `Ready to work offlline` on first visit and once the `service worker` ready. -- Show `Prompt for update` when new `service worker` available. + + diff --git a/docs/examples/svelte.md b/docs/examples/svelte.md index 2600d9cd..8d4be186 100644 --- a/docs/examples/svelte.md +++ b/docs/examples/svelte.md @@ -36,28 +36,9 @@ If you are running an example with `Periodic SW updates`, you will need to wait ## generateSW -`generateSW` has the following behaviors: -- `Prompt for update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - -- `Auto update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - When new content available, the service worker will be updated automatically. - -- `Prompt for update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - - The example project will register a `Periodic service worker updates` - -- `Auto update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - The example project will register a `Periodic service worker updates` - - When new content available, the service worker will be updated automatically. + ## injectManifest -`injectManifest` has the following behavior: -- Custom `TypeScript Service Worker` with offline support. -- Show `Ready to work offlline` on first visit and once the `service worker` ready. -- Show `Prompt for update` when new `service worker` available. + + diff --git a/docs/examples/sveltekit.md b/docs/examples/sveltekit.md index 0300550b..6acb1e1f 100644 --- a/docs/examples/sveltekit.md +++ b/docs/examples/sveltekit.md @@ -54,28 +54,9 @@ If you are running an example with `Periodic SW updates`, you will need to wait ## generateSW -`generateSW` has the following behaviors: -- `Prompt for update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - -- `Auto update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - When new content available, the service worker will be updated automatically. - -- `Prompt for update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - - The example project will register a `Periodic service worker updates` - -- `Auto update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - The example project will register a `Periodic service worker updates` - - When new content available, the service worker will be updated automatically. + ## injectManifest -`injectManifest` has the following behavior: -- Custom `TypeScript Service Worker` with offline support. -- Show `Ready to work offlline` on first visit and once the `service worker` ready. -- Show `Prompt for update` when new `service worker` available. + + diff --git a/docs/examples/vue.md b/docs/examples/vue.md index d924a404..60b54d94 100644 --- a/docs/examples/vue.md +++ b/docs/examples/vue.md @@ -36,29 +36,9 @@ If you are running an example with `Periodic SW updates`, you will need to wait ## generateSW -`generateSW` has the following behaviors: -- `Prompt for update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - -- `Auto update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - When new content available, the service worker will be updated automatically. - -- `Prompt for update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - - The example project will register a `Periodic service worker updates` - -- `Auto update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - The example project will register a `Periodic service worker updates` - - When new content available, the service worker will be updated automatically. + ## injectManifest -`injectManifest` has the following behavior: -- Custom `TypeScript Service Worker` with offline support. -- Show `Ready to work offlline` on first visit and once the `service worker` ready. -- Show `Prompt for update` when new `service worker` available. -- + + From 2c05c8055b7171a6dc23cd4beb24e1f5938a332b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez=20Jim=C3=A9nez?= Date: Mon, 29 Nov 2021 20:17:16 +0100 Subject: [PATCH 08/29] docs: modify SvelteKit stuff to match code style (tabs) --- docs/examples/sveltekit.md | 4 +- docs/frameworks/sveltekit.md | 216 ++++++++---------- examples/sveltekit-pwa/pwa-configuration.js | 136 +++++------ examples/sveltekit-pwa/pwa.js | 70 +++--- examples/sveltekit-pwa/src/app.html | 10 +- .../src/lib/components/Counter.svelte | 48 ++-- .../src/lib/components/Go.svelte | 81 ++++--- .../src/lib/components/ReloadPrompt.svelte | 155 +++++++------ .../sveltekit-pwa/src/routes/__layout.svelte | 78 +++---- .../sveltekit-pwa/src/routes/about.svelte | 4 +- .../sveltekit-pwa/src/routes/hi/[name].svelte | 10 +- .../sveltekit-pwa/src/routes/index.svelte | 16 +- examples/sveltekit-pwa/tsconfig.json | 6 +- 13 files changed, 405 insertions(+), 429 deletions(-) diff --git a/docs/examples/sveltekit.md b/docs/examples/sveltekit.md index 6acb1e1f..72ceac44 100644 --- a/docs/examples/sveltekit.md +++ b/docs/examples/sveltekit.md @@ -4,8 +4,7 @@ title: SvelteKit | Examples # SvelteKit -The `SvelteKit` example project can be found on `examples/sveltekit-pwa` package/directory and it is configured -with `@sveltejs/adapter-static` adapter. +The `SvelteKit` example project can be found on `examples/sveltekit-pwa` package/directory and it is configured with `@sveltejs/adapter-static` adapter. The `SvelteKit` example has been created using `svelte@next` template with `PNPM`: ```shell @@ -46,6 +45,7 @@ Next steps: To test `new content available`, you should rerun the corresponding script, and then refresh the page. If you are running an example with `Periodic SW updates`, you will need to wait 1 minute: + ## Executing the examples diff --git a/docs/frameworks/sveltekit.md b/docs/frameworks/sveltekit.md index 1e6ccb43..ede9bce1 100644 --- a/docs/frameworks/sveltekit.md +++ b/docs/frameworks/sveltekit.md @@ -7,12 +7,9 @@ title: SvelteKit | Frameworks > For `Type declarations`, `Prompt for update` and `Periodic SW Updates` go to [Svelte](/frameworks/svelte.html) entry. > -You should remove all references to [SvelteKit service worker module](https://kit.svelte.dev/docs#modules-$service-worker) -to disable it on your application. +You should remove all references to [SvelteKit service worker module](https://kit.svelte.dev/docs#modules-$service-worker) to disable it on your application. -Since `SvelteKit` will use `SSR / SSG`, we need to add the `ReloadPrompt` component using `dynamic import`. `Vite Plugin PWA` -will only register the service worker on build, it is aligned with the current behavior of -[SvelteKit service worker module](https://kit.svelte.dev/docs#modules-$service-worker) . +Since `SvelteKit` will use `SSR / SSG`, we need to add the `ReloadPrompt` component using `dynamic import`. `Vite Plugin PWA` will only register the service worker on build, it is aligned with the current behavior of [SvelteKit service worker module](https://kit.svelte.dev/docs#modules-$service-worker) . The best place to include the `ReloadPrompt` is on the main layout of the application: @@ -21,19 +18,19 @@ The best place to include the `ReloadPrompt` is on the main layout of the applic ```html - {#if (!dev && browser)} - - {/if} + {#if (!dev && browser)} + + {/if}
@@ -41,34 +38,26 @@ The best place to include the `ReloadPrompt` is on the main layout of the applic
{#if ReloadPrompt} - + {/if} ``` ## SvelteKit Adapters -The main problem with the current implementation of the service worker module of `SvelteKit` is that you don't have access -to the result applied by any adapter you have configured on your application. +The main problem with the current implementation of the service worker module of `SvelteKit` is that you don't have access to the result applied by any adapter you have configured on your application. -The service worker module of `SvelteKit` will be called before the adapter logic is applied, and so, inside the service worker -module, you don't have access to those resources. +The service worker module of `SvelteKit` will be called before the adapter logic is applied, and so, inside the service worker module, you don't have access to those resources. -Your application will not work when the user is offline, since the pages will not be included on the service worker precache -manifest. +Your application will not work when the user is offline, since the pages will not be included on the service worker precache manifest. -When using `Vite PWA Plugin` with any `SvelteKit Adapter` you need to provide an additional script to rebuild your `pwa` -once `SvelteKit` finish building your application, that is, when the adapter configured finish its job. +When using `Vite PWA Plugin` with any `SvelteKit Adapter` you need to provide an additional script to rebuild your `pwa` once `SvelteKit` finish building your application, that is, when the adapter configured finish its job. -The biggest difference between this plugin and the SvelteKit service worker module is that this plugin does not require -integration into the application logic, just configuration. +The biggest difference between this plugin and the SvelteKit service worker module is that this plugin does not require integration into the application logic, just configuration. -You can take a look at [SvelteKit example](https://github.com/antfu/vite-plugin-pwa/tree/main/examples/sveltekit-pwa) -to configure the additional scripts on your application, it is quite complex since we use it for multiple behaviors -with the same codebase. +You can take a look at [SvelteKit example](https://github.com/antfu/vite-plugin-pwa/tree/main/examples/sveltekit-pwa) to configure the additional scripts on your application, it is quite complex since we use it for multiple behaviors with the same codebase. -As an example using [@sveltejs/adapter-static](https://github.com/sveltejs/kit/tree/master/packages/adapter-static) -with `generateSW` strategy and `Prompt for update` behavior, you will need: +As an example using [@sveltejs/adapter-static](https://github.com/sveltejs/kit/tree/master/packages/adapter-static) with `generateSW` strategy and `Prompt for update` behavior, you will need:
1) add pwa.js script @@ -80,31 +69,30 @@ import { pwaConfiguration } from './pwa-configuration.js'; import { copyFileSync } from 'fs'; const webmanifestDestinations = [ - './.svelte-kit/output/client/', - './build/', + './.svelte-kit/output/client/', + './build/', ] const swDestinations = [ - './build/', + './build/', ] const buildPwa = async() => { - // const pwaConfiguration = await buildPwaConfiguration() - const config = await resolveConfig({ plugins: [VitePWA({ ...pwaConfiguration })] }, 'build', 'production' ) - // when `vite-plugin-pwa` is presented, use it to regenerate SW after rendering - const pwaPlugin = config.plugins.find(i => i.name === 'vite-plugin-pwa')?.api - if (pwaPlugin?.generateSW) { - console.log('Generating PWA...') - await pwaPlugin.generateSW() - webmanifestDestinations.forEach(d => { - copyFileSync('./.svelte-kit/output/client/_app/manifest.webmanifest', `${d}/manifest.webmanifest`) - }) - // don't copy workbox, svelte kit will copy it - swDestinations.forEach(d => { - copyFileSync('./.svelte-kit/output/client/sw.js', `${d}/sw.js`) - }) - console.log('Generated PWA complete') - } + const config = await resolveConfig({ plugins: [VitePWA({ ...pwaConfiguration })] }, 'build', 'production' ) + // when `vite-plugin-pwa` is present, use it to regenerate SW after rendering + const pwaPlugin = config.plugins.find(i => i.name === 'vite-plugin-pwa')?.api + if (pwaPlugin?.generateSW) { + console.log('Generating PWA...') + await pwaPlugin.generateSW() + webmanifestDestinations.forEach(d => { + copyFileSync('./.svelte-kit/output/client/_app/manifest.webmanifest', `${d}/manifest.webmanifest`) + }) + // don't copy workbox, SvelteKit will copy it + swDestinations.forEach(d => { + copyFileSync('./.svelte-kit/output/client/sw.js', `${d}/sw.js`) + }) + console.log('Generation of PWA complete') + } } buildPwa() @@ -117,12 +105,12 @@ buildPwa() ```js const pwaConfiguration = { - srcDir: './build', - outDir: './.svelte-kit/output/client', - includeManifestIcons: false, - base: '/', - scope: '/', - manifest: { + srcDir: './build', + outDir: './.svelte-kit/output/client', + includeManifestIcons: false, + base: '/', + scope: '/', + manifest: { short_name: "", name: "", scope: "/", @@ -131,54 +119,54 @@ const pwaConfiguration = { theme_color: "#ffffff", background_color: "#ffffff", icons: [ - { - src: "/pwa-192x192.png", - sizes: "192x192", - type: "image/png" - }, - { - src: "/pwa-512x512.png", - "sizes": "512x512", - "type": "image/png" - }, - { - src: "/pwa-512x512.png", - "sizes": "512x512", - "type": "image/png", - purpose: 'any maskable' - } + { + src: "/pwa-192x192.png", + sizes: "192x192", + type: "image/png" + }, + { + src: "/pwa-512x512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + src: "/pwa-512x512.png", + "sizes": "512x512", + "type": "image/png", + purpose: 'any maskable' + } ] }, - workbox: { - // mode: 'development', - navigateFallback: '/', - // vite and sveltekit are not aligned: pwa plugin will use /\.[a-f0-9]{8}\./ by default: #164 optimize workbox work - dontCacheBustURLsMatching: /-[a-f0-9]{8}\./, - globDirectory: './build/', - globPatterns: ['robots.txt', '**/*.{js,css,html,ico,png,svg,webmanifest}'], - globIgnores: [ - '**/sw*', '**/workbox-*' - ], - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - manifestTransforms: [async(entries) => { - // manifest.webmanifest is added always by pwa plugin, so we remove it - // EXCLUDE from the sw precache sw and workbox-* - const manifest = entries.filter(({ url }) => - url !== 'manifest.webmanifest' && url !== 'sw.js' && !url.startsWith('workbox-') - ).map((e) => { - let url = e.url; - if (url && url.endsWith('.html')) { - if (url.startsWith('/')) - url = url.slice(1) - - e.url = url === 'index.html' ? '/' : `/${url.substring(0, url.lastIndexOf('/'))}` - } - - return e - }); - return { manifest } - }] - } + workbox: { + // mode: 'development', + navigateFallback: '/', + // vite and sveltekit are not aligned: pwa plugin will use /\.[a-f0-9]{8}\./ by default: #164 optimize workbox work + dontCacheBustURLsMatching: /-[a-f0-9]{8}\./, + globDirectory: './build/', + globPatterns: ['robots.txt', '**/*.{js,css,html,ico,png,svg,webmanifest}'], + globIgnores: [ + '**/sw*', '**/workbox-*' + ], + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + manifestTransforms: [async(entries) => { + // manifest.webmanifest is added always by pwa plugin, so we remove it + // EXCLUDE from the sw precache sw and workbox-* + const manifest = entries.filter(({ url }) => + url !== 'manifest.webmanifest' && url !== 'sw.js' && !url.startsWith('workbox-') + ).map((e) => { + let url = e.url; + if (url && url.endsWith('.html')) { + if (url.startsWith('/')) + url = url.slice(1) + + e.url = url === 'index.html' ? '/' : `/${url.substring(0, url.lastIndexOf('/'))}` + } + + return e + }); + return { manifest } + }] + } }; export { pwaConfiguration }; @@ -207,21 +195,19 @@ import { pwaConfiguration } from './pwa-configuration.js' /** @type {import('@sveltejs/kit').Config} */ const config = { - // Consult https://github.com/sveltejs/svelte-preprocess - // for more information about preprocessors - preprocess: preprocess(), - - kit: { - adapter: adapter(), - - // hydrate the
element in src/app.html - target: '#svelte', - vite: { - plugins: [ - VitePWA(pwaConfiguration) - ] + // Consult https://github.com/sveltejs/svelte-preprocess + // for more information about preprocessors + preprocess: preprocess(), + + kit: { + adapter: adapter(), + + // hydrate the
element in src/app.html + target: '#svelte', + vite: { + plugins: [VitePWA(pwaConfiguration)] + } } - } }; export default config; diff --git a/examples/sveltekit-pwa/pwa-configuration.js b/examples/sveltekit-pwa/pwa-configuration.js index 570e91aa..8f6c73ca 100644 --- a/examples/sveltekit-pwa/pwa-configuration.js +++ b/examples/sveltekit-pwa/pwa-configuration.js @@ -1,89 +1,89 @@ const pwaConfiguration = { - srcDir: './build', - outDir: './.svelte-kit/output/client', - mode: 'development', - includeManifestIcons: false, - scope: '/', - base: '/', - manifest: { - short_name: "PWA Router", - name: "PWA Router", - start_url: "/", - scope: "/", - display: "standalone", - theme_color: "#ffffff", - background_color: "#ffffff", - icons: [ - { - src: '/pwa-192x192.png', - sizes: '192x192', - type: 'image/png', - }, - { - src: '/pwa-512x512.png', - sizes: '512x512', - type: 'image/png', - }, - { - src: '/pwa-512x512.png', - sizes: '512x512', - type: 'image/png', - purpose: 'any maskable', - }, - ] - }, + srcDir: './build', + outDir: './.svelte-kit/output/client', + mode: 'development', + includeManifestIcons: false, + scope: '/', + base: '/', + manifest: { + short_name: "PWA Router", + name: "PWA Router", + start_url: "/", + scope: "/", + display: "standalone", + theme_color: "#ffffff", + background_color: "#ffffff", + icons: [ + { + src: '/pwa-192x192.png', + sizes: '192x192', + type: 'image/png', + }, + { + src: '/pwa-512x512.png', + sizes: '512x512', + type: 'image/png', + }, + { + src: '/pwa-512x512.png', + sizes: '512x512', + type: 'image/png', + purpose: 'any maskable', + }, + ] + }, } const claims = process.env.CLAIMS === 'true' const reload = process.env.RELOAD_SW === 'true' const sw = process.env.SW === 'true' const replaceOptions = { - __DATE__: new Date().toISOString(), - __RELOAD_SW__: reload ? 'true' : 'false', + __DATE__: new Date().toISOString(), + __RELOAD_SW__: reload ? 'true' : 'false', } const workboxOrInjectManifestEntry = { - // vite and sveltekit are not aligned: pwa plugin will use /\.[a-f0-9]{8}\./ by default: #164 optimize workbox work - dontCacheBustURLsMatching: /-[a-f0-9]{8}\./, - globDirectory: './build/', - globPatterns: ['**/*.{js,css,html,ico,png,svg,webmanifest}'], - globIgnores: sw ? (claims ? ['**/claims-sw*'] : ['**/prompt-sw*']) : ['**/sw*', '**/workbox-*'], - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - manifestTransforms: [async(entries) => { - // manifest.webmanifest is added always by pwa plugin, so we remove it - // EXCLUDE from the sw precache sw and workbox-* - const manifest = entries.filter(({ url }) => - url !== 'manifest.webmanifest' && !url.endsWith('sw.js') && !url.startsWith('workbox-') - ).map((e) => { - let url = e.url - if (url && url.endsWith('.html')) { - if (url.startsWith('/')) - url = url.slice(1) + // vite and sveltekit are not aligned: pwa plugin will use /\.[a-f0-9]{8}\./ by default: #164 optimize workbox work + dontCacheBustURLsMatching: /-[a-f0-9]{8}\./, + globDirectory: './build/', + globPatterns: ['**/*.{js,css,html,ico,png,svg,webmanifest}'], + globIgnores: sw ? (claims ? ['**/claims-sw*'] : ['**/prompt-sw*']) : ['**/sw*', '**/workbox-*'], + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + manifestTransforms: [async(entries) => { + // manifest.webmanifest is added always by pwa plugin, so we remove it + // EXCLUDE from the sw precache sw and workbox-* + const manifest = entries.filter(({ url }) => + url !== 'manifest.webmanifest' && !url.endsWith('sw.js') && !url.startsWith('workbox-') + ).map((e) => { + let url = e.url + if (url && url.endsWith('.html')) { + if (url.startsWith('/')) + url = url.slice(1) - e.url = url === 'index.html' ? '/' : `/${url.substring(0, url.lastIndexOf('/'))}` - console.log(`${url} => ${e.url}`) - } + e.url = url === 'index.html' ? '/' : `/${url.substring(0, url.lastIndexOf('/'))}` + console.log(`${url} => ${e.url}`) + } - return e - }) - return { manifest } - }] + return e + }) + return { manifest } + }] } if (sw) { - pwaConfiguration.srcDir = 'src' - pwaConfiguration.filename = claims ? 'claims-sw.ts' : 'prompt-sw.ts' - pwaConfiguration.strategies = 'injectManifest' - pwaConfiguration.manifest.name = 'PWA Inject Manifest' - pwaConfiguration.manifest.short_name = 'PWA Inject' - pwaConfiguration.injectManifest = workboxOrInjectManifestEntry + pwaConfiguration.srcDir = 'src' + pwaConfiguration.filename = claims ? 'claims-sw.ts' : 'prompt-sw.ts' + pwaConfiguration.strategies = 'injectManifest' + pwaConfiguration.manifest.name = 'PWA Inject Manifest' + pwaConfiguration.manifest.short_name = 'PWA Inject' + pwaConfiguration.injectManifest = workboxOrInjectManifestEntry } else { - workboxOrInjectManifestEntry.mode = 'development' - workboxOrInjectManifestEntry.navigateFallback = '/' - pwaConfiguration.workbox = workboxOrInjectManifestEntry + workboxOrInjectManifestEntry.mode = 'development' + workboxOrInjectManifestEntry.navigateFallback = '/' + pwaConfiguration.workbox = workboxOrInjectManifestEntry } if (claims) - pwaConfiguration.registerType = 'autoUpdate' + pwaConfiguration.registerType = 'autoUpdate' export { pwaConfiguration, replaceOptions } diff --git a/examples/sveltekit-pwa/pwa.js b/examples/sveltekit-pwa/pwa.js index 7c035be7..27bd0370 100644 --- a/examples/sveltekit-pwa/pwa.js +++ b/examples/sveltekit-pwa/pwa.js @@ -11,47 +11,47 @@ process.env.RELOAD_SW = `${args['RELOAD_SW'] === 'true'}` process.env.SW = `${args['SW'] === 'true'}` const webmanifestDestinations = [ - './.svelte-kit/output/client/', - './build/', + './.svelte-kit/output/client/', + './build/', ] const swDestinations = [ - './build/', + './build/', ] const buildPwa = async() => { - const { pwaConfiguration, replaceOptions } = await import('./pwa-configuration.js') - const config = await resolveConfig({ - plugins: [ - VitePWA(pwaConfiguration), - replace(replaceOptions), - ] - }, - 'build', - 'production' - ) - // when `vite-plugin-pwa` is presented, use it to regenerate SW after rendering - const pwaPlugin = config.plugins.find(i => i.name === 'vite-plugin-pwa')?.api - if (pwaPlugin?.generateSW) { - console.log('Generating PWA...') - await pwaPlugin.generateSW() - webmanifestDestinations.forEach(d => { - copyFileSync('./.svelte-kit/output/client/_app/manifest.webmanifest', `${d}/manifest.webmanifest`) - }) - // don't copy workbox, svelte kit will copy it - if (pwaConfiguration.strategies === 'injectManifest') { - const destName = pwaConfiguration.registerType === 'autoUpdate' ? 'claims-sw.js' : 'prompt-sw.js' - const name = `./.svelte-kit/output/client/${destName}` - swDestinations.forEach(d => { - copyFileSync(name, `${d}/${destName}`) - }) - } else { - swDestinations.forEach(d => { - copyFileSync('./.svelte-kit/output/client/sw.js', `${d}/sw.js`) - }) - } - console.log('Generated PWA complete') - } +const { pwaConfiguration, replaceOptions } = await import('./pwa-configuration.js') + const config = await resolveConfig({ + plugins: [ + VitePWA(pwaConfiguration), + replace(replaceOptions), + ] + }, + 'build', + 'production' + ) + // when `vite-plugin-pwa` is presented, use it to regenerate SW after rendering + const pwaPlugin = config.plugins.find(i => i.name === 'vite-plugin-pwa')?.api + if (pwaPlugin?.generateSW) { + console.log('Generating PWA...') + await pwaPlugin.generateSW() + webmanifestDestinations.forEach(d => { + copyFileSync('./.svelte-kit/output/client/_app/manifest.webmanifest', `${d}/manifest.webmanifest`) + }) + // don't copy workbox, svelte kit will copy it + if (pwaConfiguration.strategies === 'injectManifest') { + const destName = pwaConfiguration.registerType === 'autoUpdate' ? 'claims-sw.js' : 'prompt-sw.js' + const name = `./.svelte-kit/output/client/${destName}` + swDestinations.forEach(d => { + copyFileSync(name, `${d}/${destName}`) + }) + } else { + swDestinations.forEach(d => { + copyFileSync('./.svelte-kit/output/client/sw.js', `${d}/sw.js`) + }) + } + console.log('Generation of PWA complete') + } } buildPwa() diff --git a/examples/sveltekit-pwa/src/app.html b/examples/sveltekit-pwa/src/app.html index ffd2bd0e..2238847d 100644 --- a/examples/sveltekit-pwa/src/app.html +++ b/examples/sveltekit-pwa/src/app.html @@ -3,11 +3,11 @@ - - - - - + + + + + %svelte.head% diff --git a/examples/sveltekit-pwa/src/lib/components/Counter.svelte b/examples/sveltekit-pwa/src/lib/components/Counter.svelte index 210ee98e..e3cefc5f 100644 --- a/examples/sveltekit-pwa/src/lib/components/Counter.svelte +++ b/examples/sveltekit-pwa/src/lib/components/Counter.svelte @@ -1,34 +1,34 @@ diff --git a/examples/sveltekit-pwa/src/lib/components/Go.svelte b/examples/sveltekit-pwa/src/lib/components/Go.svelte index 113a793b..ce98478b 100644 --- a/examples/sveltekit-pwa/src/lib/components/Go.svelte +++ b/examples/sveltekit-pwa/src/lib/components/Go.svelte @@ -1,55 +1,52 @@
- - + +
- diff --git a/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte b/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte index 44734da8..7ddd07c3 100644 --- a/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte +++ b/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte @@ -1,88 +1,87 @@ {#if toast} - + {/if}
{buildDate}
diff --git a/examples/sveltekit-pwa/src/routes/__layout.svelte b/examples/sveltekit-pwa/src/routes/__layout.svelte index ac894e2a..f5391c6d 100644 --- a/examples/sveltekit-pwa/src/routes/__layout.svelte +++ b/examples/sveltekit-pwa/src/routes/__layout.svelte @@ -1,58 +1,58 @@ - {#if (!dev && browser)} - - {/if} + {#if (!dev && browser)} + + {/if}
- PWA Logo -

SvelteKit PWA!

+ PWA Logo +

SvelteKit PWA!

-
Built at: { date }
+
Built at: { date }
- +
{#if ReloadPrompt} - + {/if} diff --git a/examples/sveltekit-pwa/src/routes/about.svelte b/examples/sveltekit-pwa/src/routes/about.svelte index d5d9aea9..74dc1e48 100644 --- a/examples/sveltekit-pwa/src/routes/about.svelte +++ b/examples/sveltekit-pwa/src/routes/about.svelte @@ -1,6 +1,6 @@
/about route, built at: { date }
diff --git a/examples/sveltekit-pwa/src/routes/hi/[name].svelte b/examples/sveltekit-pwa/src/routes/hi/[name].svelte index 6a9b0856..27d68fb7 100644 --- a/examples/sveltekit-pwa/src/routes/hi/[name].svelte +++ b/examples/sveltekit-pwa/src/routes/hi/[name].svelte @@ -1,16 +1,16 @@
/hi route, built at: { date }

- Hi: { name } + Hi: { name }


Go Home diff --git a/examples/sveltekit-pwa/src/routes/index.svelte b/examples/sveltekit-pwa/src/routes/index.svelte index f033de33..30be4ee0 100644 --- a/examples/sveltekit-pwa/src/routes/index.svelte +++ b/examples/sveltekit-pwa/src/routes/index.svelte @@ -1,16 +1,10 @@ - +
-
+
- - -
- -About - -
+About
diff --git a/examples/sveltekit-pwa/tsconfig.json b/examples/sveltekit-pwa/tsconfig.json index ddf6e83b..4b9c71f8 100644 --- a/examples/sveltekit-pwa/tsconfig.json +++ b/examples/sveltekit-pwa/tsconfig.json @@ -12,9 +12,9 @@ "isolatedModules": true, "resolveJsonModule": true, /** - To have warnings/errors of the Svelte compiler at the correct position, - enable source maps by default. - */ + * To have warnings/errors of the Svelte compiler at the correct position, + * enable source maps by default. + */ "sourceMap": true, "esModuleInterop": true, "skipLibCheck": true, From aa5ac8a4ef97f59c07802b4a7c9c7802e88c03be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez=20Jim=C3=A9nez?= Date: Mon, 29 Nov 2021 20:20:12 +0100 Subject: [PATCH 09/29] docs: update SvelteKit SSR/SSG --- docs/frameworks/sveltekit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frameworks/sveltekit.md b/docs/frameworks/sveltekit.md index ede9bce1..45428187 100644 --- a/docs/frameworks/sveltekit.md +++ b/docs/frameworks/sveltekit.md @@ -9,7 +9,7 @@ title: SvelteKit | Frameworks You should remove all references to [SvelteKit service worker module](https://kit.svelte.dev/docs#modules-$service-worker) to disable it on your application. -Since `SvelteKit` will use `SSR / SSG`, we need to add the `ReloadPrompt` component using `dynamic import`. `Vite Plugin PWA` will only register the service worker on build, it is aligned with the current behavior of [SvelteKit service worker module](https://kit.svelte.dev/docs#modules-$service-worker) . +Since `SvelteKit` uses `SSR / SSG`, we need to add the `ReloadPrompt` component using `dynamic import`. `Vite Plugin PWA` will only register the service worker on build, it is aligned with the current behavior of [SvelteKit service worker module](https://kit.svelte.dev/docs#modules-$service-worker) . The best place to include the `ReloadPrompt` is on the main layout of the application: From 0550134bd7b68ee357cc6e4668538d20e86aca2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez=20Jim=C3=A9nez?= Date: Mon, 29 Nov 2021 21:25:27 +0100 Subject: [PATCH 10/29] docs: errata in the `ExamplesBehaviors.md` component --- docs/.vitepress/theme/components/ExamplesBehaviors.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/.vitepress/theme/components/ExamplesBehaviors.md b/docs/.vitepress/theme/components/ExamplesBehaviors.md index 8295179a..ad847517 100644 --- a/docs/.vitepress/theme/components/ExamplesBehaviors.md +++ b/docs/.vitepress/theme/components/ExamplesBehaviors.md @@ -1,17 +1,17 @@ - `Prompt for update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. + - Show `Ready to work offline` on first visit and once the `service worker` ready. - Show `Prompt for update` when new `service worker` available. - `Auto update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. + - Show `Ready to work offline` on first visit and once the `service worker` ready. - When new content available, the service worker will be updated automatically. - `Prompt for update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. + - Show `Ready to work offline` on first visit and once the `service worker` ready. - Show `Prompt for update` when new `service worker` available. - The example project will register a `Periodic service worker updates` - `Auto update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. + - Show `Ready to work offline` on first visit and once the `service worker` ready. - The example project will register a `Periodic service worker updates` - When new content available, the service worker will be updated automatically. From 9fbbddf69d36aad9ac9ac83c2b5b3218b878a71e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez=20Jim=C3=A9nez?= Date: Mon, 29 Nov 2021 21:57:04 +0100 Subject: [PATCH 11/29] docs: fix tab on `pwa.js` module --- examples/sveltekit-pwa/pwa.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/sveltekit-pwa/pwa.js b/examples/sveltekit-pwa/pwa.js index 27bd0370..68389161 100644 --- a/examples/sveltekit-pwa/pwa.js +++ b/examples/sveltekit-pwa/pwa.js @@ -20,7 +20,7 @@ const swDestinations = [ ] const buildPwa = async() => { -const { pwaConfiguration, replaceOptions } = await import('./pwa-configuration.js') + const { pwaConfiguration, replaceOptions } = await import('./pwa-configuration.js') const config = await resolveConfig({ plugins: [ VitePWA(pwaConfiguration), From d35221012e8ac2be33db495b3ef68dae6ac67d49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez=20Jim=C3=A9nez?= Date: Mon, 29 Nov 2021 21:58:09 +0100 Subject: [PATCH 12/29] docs: fix more tabs on `pwa.js` module --- examples/sveltekit-pwa/pwa.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/sveltekit-pwa/pwa.js b/examples/sveltekit-pwa/pwa.js index 68389161..ff4b347c 100644 --- a/examples/sveltekit-pwa/pwa.js +++ b/examples/sveltekit-pwa/pwa.js @@ -22,13 +22,13 @@ const swDestinations = [ const buildPwa = async() => { const { pwaConfiguration, replaceOptions } = await import('./pwa-configuration.js') const config = await resolveConfig({ - plugins: [ - VitePWA(pwaConfiguration), - replace(replaceOptions), - ] - }, - 'build', - 'production' + plugins: [ + VitePWA(pwaConfiguration), + replace(replaceOptions), + ] + }, + 'build', + 'production' ) // when `vite-plugin-pwa` is presented, use it to regenerate SW after rendering const pwaPlugin = config.plugins.find(i => i.name === 'vite-plugin-pwa')?.api From e7338738c7f80553afe516a71ed3a668d0b54b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez=20Jim=C3=A9nez?= Date: Mon, 29 Nov 2021 22:03:38 +0100 Subject: [PATCH 13/29] docs: fix more tabs on `ReloadPrompt` component --- .../src/lib/components/ReloadPrompt.svelte | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte b/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte index 7ddd07c3..9daac487 100644 --- a/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte +++ b/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte @@ -35,13 +35,13 @@
@@ -189,19 +190,19 @@ import { pwaConfiguration } from './pwa-configuration.js' /** @type {import('@sveltejs/kit').Config} */ const config = { - // Consult https://github.com/sveltejs/svelte-preprocess - // for more information about preprocessors - preprocess: preprocess(), - - kit: { - adapter: adapter(), - - // hydrate the
element in src/app.html - target: '#svelte', - vite: { - plugins: [VitePWA(pwaConfiguration)] - } - } + // Consult https://github.com/sveltejs/svelte-preprocess + // for more information about preprocessors + preprocess: preprocess(), + + kit: { + adapter: adapter(), + + // hydrate the
element in src/app.html + target: '#svelte', + vite: { + plugins: [VitePWA(pwaConfiguration)] + } + } }; export default config; diff --git a/examples/sveltekit-pwa/pwa-configuration.js b/examples/sveltekit-pwa/pwa-configuration.js index 8f6c73ca..e8edd70d 100644 --- a/examples/sveltekit-pwa/pwa-configuration.js +++ b/examples/sveltekit-pwa/pwa-configuration.js @@ -50,8 +50,10 @@ const workboxOrInjectManifestEntry = { globIgnores: sw ? (claims ? ['**/claims-sw*'] : ['**/prompt-sw*']) : ['**/sw*', '**/workbox-*'], // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types manifestTransforms: [async(entries) => { - // manifest.webmanifest is added always by pwa plugin, so we remove it - // EXCLUDE from the sw precache sw and workbox-* + /** + * manifest.webmanifest is added always by pwa plugin, so we remove it. + * EXCLUDE from the sw precache sw and workbox-* + */ const manifest = entries.filter(({ url }) => url !== 'manifest.webmanifest' && !url.endsWith('sw.js') && !url.startsWith('workbox-') ).map((e) => { From d65df1ef935822281f4d4a3c4d4db8d7d551ca22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez=20Jim=C3=A9nez?= Date: Tue, 30 Nov 2021 13:03:37 +0100 Subject: [PATCH 21/29] docs: add `manifestTransforms` hints --- docs/frameworks/sveltekit.md | 12 ++++++------ examples/sveltekit-pwa/pwa-configuration.js | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/frameworks/sveltekit.md b/docs/frameworks/sveltekit.md index 7aa28372..a86995e5 100644 --- a/docs/frameworks/sveltekit.md +++ b/docs/frameworks/sveltekit.md @@ -134,17 +134,17 @@ const pwaConfiguration = { workbox: { // mode: 'development', navigateFallback: '/', - // vite and sveltekit are not aligned: pwa plugin will use /\.[a-f0-9]{8}\./ by default: #164 optimize workbox work + // vite and SvelteKit are not aligned: pwa plugin will use /\.[a-f0-9]{8}\./ by default: #164 optimize workbox work dontCacheBustURLsMatching: /-[a-f0-9]{8}\./, globDirectory: './build/', globPatterns: ['robots.txt', '**/*.{js,css,html,ico,png,svg,webmanifest}'], globIgnores: ['**/sw*', '**/workbox-*'], - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + // Before generating the service worker, manifestTransforms entry will allow us to transform the resulting precache manifest. + // The entries received in the callback from workbox-build module, will contain all the assets specified on srcDir option with the url and its corresponding revision calculated (hash). + // Since SvelteKit uses the router name of the directory for all the generated pages, we add a callback to modify the url for all pages. manifestTransforms: [async(entries) => { - /** - * manifest.webmanifest is added always by pwa plugin, so we remove it. - * EXCLUDE from the sw precache sw and workbox-* - */ + // manifest.webmanifest is added always by pwa plugin, so we remove it. + // EXCLUDE from the sw precache sw and workbox-* const manifest = entries.filter(({ url }) => url !== 'manifest.webmanifest' && url !== 'sw.js' && !url.startsWith('workbox-') ).map((e) => { diff --git a/examples/sveltekit-pwa/pwa-configuration.js b/examples/sveltekit-pwa/pwa-configuration.js index e8edd70d..b730fc23 100644 --- a/examples/sveltekit-pwa/pwa-configuration.js +++ b/examples/sveltekit-pwa/pwa-configuration.js @@ -43,19 +43,19 @@ const replaceOptions = { } const workboxOrInjectManifestEntry = { - // vite and sveltekit are not aligned: pwa plugin will use /\.[a-f0-9]{8}\./ by default: #164 optimize workbox work + // vite and SvelteKit are not aligned: pwa plugin will use /\.[a-f0-9]{8}\./ by default: #164 optimize workbox work dontCacheBustURLsMatching: /-[a-f0-9]{8}\./, globDirectory: './build/', globPatterns: ['**/*.{js,css,html,ico,png,svg,webmanifest}'], globIgnores: sw ? (claims ? ['**/claims-sw*'] : ['**/prompt-sw*']) : ['**/sw*', '**/workbox-*'], - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + // Before generating the service worker, manifestTransforms entry will allow us to transform the resulting precache manifest. + // The entries received in the callback from workbox-build module, will contain all the assets specified on srcDir option with the url and its corresponding revision calculated (hash). + // Since SvelteKit uses the router name of the directory for all the generated pages, we add a callback to modify the url for all pages. manifestTransforms: [async(entries) => { - /** - * manifest.webmanifest is added always by pwa plugin, so we remove it. - * EXCLUDE from the sw precache sw and workbox-* - */ + // manifest.webmanifest is added always by pwa plugin, so we remove it. + // EXCLUDE from the sw precache sw and workbox-* const manifest = entries.filter(({ url }) => - url !== 'manifest.webmanifest' && !url.endsWith('sw.js') && !url.startsWith('workbox-') + url !== 'manifest.webmanifest' && !url.endsWith('sw.js') && !url.startsWith('workbox-') ).map((e) => { let url = e.url if (url && url.endsWith('.html')) { From 93369369a3da9fc7afdbd1fedca8572c60c82697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez=20Jim=C3=A9nez?= Date: Tue, 30 Nov 2021 17:24:30 +0100 Subject: [PATCH 22/29] docs: add `manifestTransforms` hints tod pwa docs --- docs/frameworks/sveltekit.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/frameworks/sveltekit.md b/docs/frameworks/sveltekit.md index a86995e5..08427d30 100644 --- a/docs/frameworks/sveltekit.md +++ b/docs/frameworks/sveltekit.md @@ -51,6 +51,18 @@ When using `Vite PWA Plugin` with any `SvelteKit Adapter` you need to provide an The biggest difference between this plugin and the SvelteKit service worker module is that this plugin does not require integration into the application logic - just configuration. You can take a look at [SvelteKit example](https://github.com/antfu/vite-plugin-pwa/tree/main/examples/sveltekit-pwa) to configure the additional scripts on your application, it is quite complex since we use it for multiple behaviors with the same codebase. +### Workbox manifestTransforms + +Before generating the service worker, `manifestTransforms` entry will allow us to transform the resulting precache manifest entries. + +The entries provided on `manifestTransforms` (on `workbox` or `injectManifest` pwa plugin option) entry callback from `workbox-build` node module, will contain all the assets specified on the `srcDir` pwa plugin option with the url and their corresponding revision calculated (hash). + +Since `SvelteKit` uses the router name of the directory (for simple cases) for all the generated pages, you can use `manifestTransforms` to modify the url for all pages generated. You must add the logic to do the right mapping using the corresponding adapter. + +Of course, a more complex page directories will force you to modify the `manifestTransforms` entry logic, see the `pwa-configuration.js` module in the next example using `@sveltejs/adapter-static`. + +### Static Adapter example + As an example, when using [@sveltejs/adapter-static](https://github.com/sveltejs/kit/tree/master/packages/adapter-static) with `generateSW` strategy and `Prompt for update` behavior, you will need:
@@ -139,9 +151,6 @@ const pwaConfiguration = { globDirectory: './build/', globPatterns: ['robots.txt', '**/*.{js,css,html,ico,png,svg,webmanifest}'], globIgnores: ['**/sw*', '**/workbox-*'], - // Before generating the service worker, manifestTransforms entry will allow us to transform the resulting precache manifest. - // The entries received in the callback from workbox-build module, will contain all the assets specified on srcDir option with the url and its corresponding revision calculated (hash). - // Since SvelteKit uses the router name of the directory for all the generated pages, we add a callback to modify the url for all pages. manifestTransforms: [async(entries) => { // manifest.webmanifest is added always by pwa plugin, so we remove it. // EXCLUDE from the sw precache sw and workbox-* From 7f05d9036e7eabbda0da4e208d8c82a02c2f60ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez=20Jim=C3=A9nez?= Date: Tue, 30 Nov 2021 18:48:34 +0100 Subject: [PATCH 23/29] docs: change `vitepress` configuration --- docs/.vitepress/{config.js => config.ts} | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) rename docs/.vitepress/{config.js => config.ts} (93%) diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.ts similarity index 93% rename from docs/.vitepress/config.js rename to docs/.vitepress/config.ts index a5b9ff2a..d486a4ed 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.ts @@ -1,4 +1,4 @@ -require('esbuild-register') +import type { UserConfig } from 'vitepress' const Guide = [ { @@ -155,45 +155,41 @@ const slidebars = [ { text: 'Guide', children: Guide.map((e) => { - e.useLinkText = `${e.text} | Guide` + (e as any).useLinkText = `${e.text} | Guide` return e }), }, { text: 'Frameworks', children: Frameworks.map((e) => { - e.useLinkText = `${e.text} | Frameworks` + (e as any).useLinkText = `${e.text} | Frameworks` return e }), }, { text: 'Examples', children: Examples.map((e) => { - e.useLinkText = `${e.text} | Examples` + (e as any).useLinkText = `${e.text} | Examples` return e }), }, { text: 'Deployment', children: Deployment.map((e) => { - e.useLinkText = `${e.text} | Deployment` + (e as any).useLinkText = `${e.text} | Deployment` return e }), }, { text: 'Workbox', children: Workbox.map((e) => { - e.useLinkText = `${e.text} | Workbox` + (e as any).useLinkText = `${e.text} | Workbox` return e }), }, ] - -/** - * @type {import('vitepress').UserConfig} - */ -const config = { +const config: UserConfig = { title: 'Vite Plugin PWA', description: 'Zero-config PWA Framework-agnostic Plugin for Vite', lang: 'en-US', @@ -260,4 +256,4 @@ const config = { }, } -module.exports = config +export default config From 41f62a684df23ba42ca281399f4f5289101a93eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez?= Date: Wed, 1 Dec 2021 00:28:03 +0100 Subject: [PATCH 24/29] Update docs/frameworks/sveltekit.md Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- docs/frameworks/sveltekit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frameworks/sveltekit.md b/docs/frameworks/sveltekit.md index 08427d30..9c1d4f86 100644 --- a/docs/frameworks/sveltekit.md +++ b/docs/frameworks/sveltekit.md @@ -55,7 +55,7 @@ The biggest difference between this plugin and the SvelteKit service worker modu Before generating the service worker, `manifestTransforms` entry will allow us to transform the resulting precache manifest entries. -The entries provided on `manifestTransforms` (on `workbox` or `injectManifest` pwa plugin option) entry callback from `workbox-build` node module, will contain all the assets specified on the `srcDir` pwa plugin option with the url and their corresponding revision calculated (hash). +The entries provided in the `manifestTransforms` option (under `workbox` or `injectManifest`) will contain all the assets specified in the `srcDir` option with the URL and their corresponding revision calculated (e.g. to include the hash). Since `SvelteKit` uses the router name of the directory (for simple cases) for all the generated pages, you can use `manifestTransforms` to modify the url for all pages generated. You must add the logic to do the right mapping using the corresponding adapter. From ee023a8d46d0a882f46a75b070cf944b08029310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez?= Date: Wed, 1 Dec 2021 00:28:38 +0100 Subject: [PATCH 25/29] Update examples/sveltekit-pwa/pwa-configuration.js Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- examples/sveltekit-pwa/pwa-configuration.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/sveltekit-pwa/pwa-configuration.js b/examples/sveltekit-pwa/pwa-configuration.js index b730fc23..f150c260 100644 --- a/examples/sveltekit-pwa/pwa-configuration.js +++ b/examples/sveltekit-pwa/pwa-configuration.js @@ -48,9 +48,7 @@ const workboxOrInjectManifestEntry = { globDirectory: './build/', globPatterns: ['**/*.{js,css,html,ico,png,svg,webmanifest}'], globIgnores: sw ? (claims ? ['**/claims-sw*'] : ['**/prompt-sw*']) : ['**/sw*', '**/workbox-*'], - // Before generating the service worker, manifestTransforms entry will allow us to transform the resulting precache manifest. - // The entries received in the callback from workbox-build module, will contain all the assets specified on srcDir option with the url and its corresponding revision calculated (hash). - // Since SvelteKit uses the router name of the directory for all the generated pages, we add a callback to modify the url for all pages. + // Before generating the service worker, manifestTransforms entry will allow us to transform the resulting precache manifest. See the manifestTransforms docs for mode details. manifestTransforms: [async(entries) => { // manifest.webmanifest is added always by pwa plugin, so we remove it. // EXCLUDE from the sw precache sw and workbox-* From bdc1a19f2c6e35f279365038b715dd0125b13454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez?= Date: Wed, 1 Dec 2021 00:29:19 +0100 Subject: [PATCH 26/29] Update docs/frameworks/sveltekit.md Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- docs/frameworks/sveltekit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frameworks/sveltekit.md b/docs/frameworks/sveltekit.md index 9c1d4f86..fc7e2e95 100644 --- a/docs/frameworks/sveltekit.md +++ b/docs/frameworks/sveltekit.md @@ -59,7 +59,7 @@ The entries provided in the `manifestTransforms` option (under `workbox` or `inj Since `SvelteKit` uses the router name of the directory (for simple cases) for all the generated pages, you can use `manifestTransforms` to modify the url for all pages generated. You must add the logic to do the right mapping using the corresponding adapter. -Of course, a more complex page directories will force you to modify the `manifestTransforms` entry logic, see the `pwa-configuration.js` module in the next example using `@sveltejs/adapter-static`. +Of course, more complex page directories will force you to modify the `manifestTransforms` entry logic. For an example, see the `pwa-configuration.js` module in the next example using `@sveltejs/adapter-static`. ### Static Adapter example From 148500d96d36d833552b7731ca4a668f838bfa1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez?= Date: Wed, 1 Dec 2021 00:33:00 +0100 Subject: [PATCH 27/29] Update docs/frameworks/sveltekit.md Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- docs/frameworks/sveltekit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frameworks/sveltekit.md b/docs/frameworks/sveltekit.md index fc7e2e95..261e4565 100644 --- a/docs/frameworks/sveltekit.md +++ b/docs/frameworks/sveltekit.md @@ -57,7 +57,7 @@ Before generating the service worker, `manifestTransforms` entry will allow us t The entries provided in the `manifestTransforms` option (under `workbox` or `injectManifest`) will contain all the assets specified in the `srcDir` option with the URL and their corresponding revision calculated (e.g. to include the hash). -Since `SvelteKit` uses the router name of the directory (for simple cases) for all the generated pages, you can use `manifestTransforms` to modify the url for all pages generated. You must add the logic to do the right mapping using the corresponding adapter. +Since `SvelteKit` uses the name of the directory (for simple cases) for all the generated pages, you can use `manifestTransforms` to modify the URL for all pages generated. You must add the logic to do the right mapping for the corresponding adapter. Of course, more complex page directories will force you to modify the `manifestTransforms` entry logic. For an example, see the `pwa-configuration.js` module in the next example using `@sveltejs/adapter-static`. From 61afed26acc82a097098ffd1f66d54d93a16d62e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez?= Date: Wed, 1 Dec 2021 01:24:40 +0100 Subject: [PATCH 28/29] docs: update manifest tranform for future-proof Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- docs/frameworks/sveltekit.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/frameworks/sveltekit.md b/docs/frameworks/sveltekit.md index 261e4565..e5831ab5 100644 --- a/docs/frameworks/sveltekit.md +++ b/docs/frameworks/sveltekit.md @@ -159,10 +159,16 @@ const pwaConfiguration = { ).map((e) => { let url = e.url; if (url && url.endsWith('.html')) { - if (url.startsWith('/')) + if (url.startsWith('/')) { url = url.slice(1) - - e.url = url === 'index.html' ? '/' : `/${url.substring(0, url.lastIndexOf('/'))}` + } + if (url === 'index.html') { + e.url = url === 'index.html' ? '/' + } else if (url.endsWith('index.html')) { + e.url = `/${url.substring(0, url.lastIndexOf('/'))}` + } else if (url.endsWith('.html')) { + e.url = `/${url.substring(0, url.length - '.html'.length)}` + } } return e From 0b1fbd1a6cc13db755affefed1be7fae01b53144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez?= Date: Wed, 1 Dec 2021 01:25:25 +0100 Subject: [PATCH 29/29] docs: update explanation for manifest transform Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- docs/frameworks/sveltekit.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/frameworks/sveltekit.md b/docs/frameworks/sveltekit.md index e5831ab5..0fac3a37 100644 --- a/docs/frameworks/sveltekit.md +++ b/docs/frameworks/sveltekit.md @@ -53,13 +53,11 @@ The biggest difference between this plugin and the SvelteKit service worker modu ### Workbox manifestTransforms -Before generating the service worker, `manifestTransforms` entry will allow us to transform the resulting precache manifest entries. +We must provide a list of URLs for the service worker to load and precache. We provide these to workbox using the [the `manifestTransforms` option](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.ManifestTransform) under `workbox` or [`injectManifest`](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.injectManifest). The [manifest entries](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.ManifestEntry) provided via this option will contain all the assets specified in the `srcDir` option. -The entries provided in the `manifestTransforms` option (under `workbox` or `injectManifest`) will contain all the assets specified in the `srcDir` option with the URL and their corresponding revision calculated (e.g. to include the hash). +Since `SvelteKit` outputs an `.html` page for each pre-rendered page, you can use `manifestTransforms` to generate the URL from the prerendered HTML file path. For an example, see the `pwa-configuration.js` module in the next example using `@sveltejs/adapter-static`. -Since `SvelteKit` uses the name of the directory (for simple cases) for all the generated pages, you can use `manifestTransforms` to modify the URL for all pages generated. You must add the logic to do the right mapping for the corresponding adapter. - -Of course, more complex page directories will force you to modify the `manifestTransforms` entry logic. For an example, see the `pwa-configuration.js` module in the next example using `@sveltejs/adapter-static`. +Pages which are not prerendered or are generated with a unique adapter will need to be handled separately and the `manifestTransforms` logic will need to be modified accordingly. ### Static Adapter example