Skip to content

Commit

Permalink
feat: expose base via $service-worker, make paths relative (#9250)
Browse files Browse the repository at this point in the history
closes #4714

---------

Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
  • Loading branch information
3 people authored Mar 8, 2023
1 parent daad7e4 commit 78b4a1b
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/great-toes-wash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': minor
---

feat: expose `base` via `$service-worker`, make paths relative
2 changes: 1 addition & 1 deletion documentation/docs/30-advanced/40-service-workers.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ if ('serviceWorker' in navigator) {

## Inside the service worker

Inside the service worker you have access to the [`$service-worker` module](modules#$service-worker), which provides you with the paths to all static assets, build files and prerendered pages. You're also provided with an app version string which you can use for creating a unique cache name. If your Vite config specifies `define` (used for global variable replacements), this will be applied to service workers as well as your server/client builds.
Inside the service worker you have access to the [`$service-worker` module](modules#$service-worker), which provides you with the paths to all static assets, build files and prerendered pages. You're also provided with an app version string, which you can use for creating a unique cache name, and the deployment's `base` path. If your Vite config specifies `define` (used for global variable replacements), this will be applied to service workers as well as your server/client builds.

The following example caches the built app and any files in `static` eagerly, and caches all other requests as they happen. This would make each page work offline once visited.

Expand Down
12 changes: 9 additions & 3 deletions packages/kit/src/exports/vite/build/build_service_worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,30 @@ export async function build_service_worker(

const service_worker = `${kit.outDir}/generated/service-worker.js`;

// in a service worker, `location` is the location of the service worker itself,
// which is guaranteed to be `<base>/service-worker.js`
const base = `location.pathname.split('/').slice(0, -1).join('/')`;

fs.writeFileSync(
service_worker,
dedent`
export const base = /*@__PURE__*/ ${base};
export const build = [
${Array.from(build)
.map((file) => `${s(`${kit.paths.base}/${file}`)}`)
.map((file) => `base + ${s(`/${file}`)}`)
.join(',\n')}
];
export const files = [
${manifest_data.assets
.filter((asset) => kit.serviceWorker.files(asset.file))
.map((asset) => `${s(`${kit.paths.base}/${asset.file}`)}`)
.map((asset) => `base + ${s(`/${asset.file}`)}`)
.join(',\n')}
];
export const prerendered = [
${prerendered.paths.map((path) => s(path)).join(',\n')}
${prerendered.paths.map((path) => `base + ${s(path.replace(kit.paths.base, ''))}`).join(',\n')}
];
export const version = ${s(kit.version.name)};
Expand Down
1 change: 1 addition & 0 deletions packages/kit/test/apps/options-2/src/routes/hello/+page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const prerender = true;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Prerendered</h1>
5 changes: 4 additions & 1 deletion packages/kit/test/apps/options-2/src/service-worker.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { build, version } from '$service-worker';
import { base, build, files, prerendered, version } from '$service-worker';

self.base = base;
self.build = build;

const name = `cache-${version}`;

Expand Down
15 changes: 14 additions & 1 deletion packages/kit/test/apps/options-2/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,20 @@ test.describe('Service worker', () => {
const response = await request.get('/basepath/service-worker.js');
const content = await response.text();

expect(content).toMatch(/\/_app\/immutable\/entry\/start\.[a-z0-9]+\.js/);
const fn = new Function('self', 'location', content);

const self = {
addEventListener: () => {},
base: null,
build: null
};

fn(self, {
pathname: '/basepath/service-worker.js'
});

expect(self.base).toBe('/basepath');
expect(self.build[0]).toMatch(/\/basepath\/_app\/immutable\/entry\/start\.[a-z0-9]+\.js/);
});

test('does not register /basepath/service-worker.js', async ({ page }) => {
Expand Down
5 changes: 5 additions & 0 deletions packages/kit/types/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,11 @@ declare module '$app/stores' {
* This module is only available to [service workers](https://kit.svelte.dev/docs/service-workers).
*/
declare module '$service-worker' {
/**
* The `base` path of the deployment. Typically this is equivalent to `config.kit.paths.base`, but it is calculated from `location.pathname` meaning that it will continue to work correctly if the site is deployed to a subdirectory.
* Note that there is a `base` but no `assets`, since service workers cannot be used if `config.kit.paths.assets` is specified.
*/
export const base: string;
/**
* An array of URL strings representing the files generated by Vite, suitable for caching with `cache.addAll(build)`.
* During development, this is an empty array.
Expand Down

0 comments on commit 78b4a1b

Please sign in to comment.