Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SW files exclusion support #1645

Merged
merged 12 commits into from
Jul 7, 2021
5 changes: 5 additions & 0 deletions .changeset/pink-poets-begin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

ServiceWorker files exclusion support available through svelte.config.js
2 changes: 1 addition & 1 deletion documentation/docs/05-modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,5 @@ import { build, files, timestamp } from '$service-worker';
```

- `build` is an array of URL strings representing the files generated by Vite, suitable for caching with `cache.addAll(build)`
- `files` is an array of URL strings representing the files in your `static` directory, or whatever directory is specified by [`config.kit.files.assets`](#configuration)
- `files` is an array of URL strings representing the files in your `static` directory, or whatever directory is specified by [`config.kit.files.assets`](#configuration). You can exclude certain files from `static` directory using [`config.kit.serviceWorker.exclude`](#configuration)
- `timestamp` is the result of calling `Date.now()` at build time. It's useful for generating unique cache names inside your service worker, so that a later deployment of your app can invalidate old caches
9 changes: 9 additions & 0 deletions documentation/docs/14-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ const config = {
serviceWorker: 'src/service-worker',
template: 'src/app.html'
},
serviceWorker: {
exclude: []
},
floc: false,
host: null,
hostHeader: null,
Expand Down Expand Up @@ -76,6 +79,12 @@ An object containing zero or more of the following `string` values:
- `hooks` — the location of your hooks module (see [Hooks](#hooks))
- `template` — the location of the template for HTML responses

### serviceWorker

An object containing zero or more of the following values:

- `exclude` - an array of glob patterns relative to `files.assets` dir. Files matching any of these would not be available in `$service-worker.files` e.g. if `files.assets` has value `static` then ['og-tags-images/**/*'] would match all files under `static/og-tags-images` dir.

### floc

Google's [FLoC](https://github.com/WICG/floc) is a technology for targeted advertising that the [Electronic Frontier Foundation](https://www.eff.org/) has deemed [harmful](https://www.eff.org/deeplinks/2021/03/googles-floc-terrible-idea) to user privacy. [Browsers other than Chrome](https://www.theverge.com/2021/4/16/22387492/google-floc-ad-tech-privacy-browsers-brave-vivaldi-edge-mozilla-chrome-safari) have declined to implement it.
Expand Down
6 changes: 6 additions & 0 deletions packages/kit/src/core/config/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ test('fills in defaults', () => {
exclude: []
}
},
serviceWorker: {
exclude: []
},
paths: {
base: '',
assets: '/.'
Expand Down Expand Up @@ -133,6 +136,9 @@ test('fills in partial blanks', () => {
exclude: []
}
},
serviceWorker: {
exclude: []
},
paths: {
base: '',
assets: '/.'
Expand Down
6 changes: 6 additions & 0 deletions packages/kit/src/core/config/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ const options = {
hostHeader: expect_string(null),

hydrate: expect_boolean(true),
serviceWorker: {
type: 'branch',
children: {
exclude: expect_array_of_strings([])
}
},

package: {
type: 'branch',
Expand Down
3 changes: 3 additions & 0 deletions packages/kit/src/core/config/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ async function testLoadDefaultConfig(path) {
exclude: []
}
},
serviceWorker: {
exclude: []
},
paths: { base: '', assets: '/.' },
prerender: { crawl: true, enabled: true, force: false, pages: ['*'] },
router: true,
Expand Down
52 changes: 46 additions & 6 deletions packages/kit/src/core/create_manifest_data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import fs from 'fs';
import path from 'path';
import mime from 'mime';
import { posixify } from '../utils.js';
import glob from 'tiny-glob/sync.js';

/** @typedef {{
* content: string;
Expand All @@ -22,6 +23,44 @@ import { posixify } from '../utils.js';

const specials = new Set(['__layout', '__layout.reset', '__error']);

/**
*
* @param {import('types/config').ValidatedConfig} config
* @returns {import('types/internal').ManifestData['assets']}
*/
function get_assets_list(config) {
const assets_dir = config.kit.files.assets;
/**
* @type {import('types/internal').Asset[]}
*/
let assets = [];
if (fs.existsSync(assets_dir)) {
/**
* @type {string[]}
*/
const exclusions = config.kit.serviceWorker.exclude || [];

exclusions.push('**/.DS_STORE');

/**
* @type {string[]}
*/
let excluded_paths = [];

exclusions.forEach((exclusion) => {
excluded_paths = [
...excluded_paths,
...glob(exclusion, {
cwd: assets_dir,
dot: true
})
];
});
assets = list_files(assets_dir, '', [], excluded_paths);
}
return assets;
}

/**
* @param {{
* config: import('types/config').ValidatedConfig;
Expand Down Expand Up @@ -237,10 +276,8 @@ export default function create_manifest_data({ config, output, cwd = process.cwd

walk(config.kit.files.routes, [], [], [layout], [error]);

const assets_dir = config.kit.files.assets;

return {
assets: fs.existsSync(assets_dir) ? list_files(assets_dir, '') : [],
assets: get_assets_list(config),
layout,
error,
components,
Expand Down Expand Up @@ -375,18 +412,21 @@ function get_pattern(segments, add_trailing_slash) {
* @param {string} dir
* @param {string} path
* @param {import('types/internal').Asset[]} files
* @param {string[]} excluded_paths Paths relative to dir which should be excluded from files list.
*/
function list_files(dir, path, files = []) {
function list_files(dir, path, files = [], excluded_paths = []) {
fs.readdirSync(dir).forEach((file) => {
const full = `${dir}/${file}`;

const stats = fs.statSync(full);
const joined = path ? `${path}/${file}` : file;

if (stats.isDirectory()) {
list_files(full, joined, files);
list_files(full, joined, files, excluded_paths);
} else {
if (file === '.DS_Store') return;
if (excluded_paths.includes(joined)) {
return;
}
files.push({
file: joined,
size: stats.size,
Expand Down
5 changes: 4 additions & 1 deletion packages/kit/src/core/create_manifest_data/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ const create = (dir, extensions = ['.svelte']) => {
assets: path.resolve(cwd, 'static'),
routes: path.resolve(cwd, dir)
},
appDir: '_app'
appDir: '_app',
serviceWorker: {
exclude: []
}
}
},
cwd,
Expand Down
6 changes: 6 additions & 0 deletions packages/kit/types/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export type Config = {
host?: string;
hostHeader?: string;
hydrate?: boolean;
serviceWorker?: {
exclude?: string[];
};
package?: {
dir?: string;
exports?: {
Expand Down Expand Up @@ -94,6 +97,9 @@ export type ValidatedConfig = {
host: string;
hostHeader: string;
hydrate: boolean;
serviceWorker: {
exclude: string[];
};
package: {
dir: string;
exports: {
Expand Down