From f5634daab7102570a3e7003157a32b7b7b6b349f Mon Sep 17 00:00:00 2001 From: Lukas Welinder Date: Sun, 27 Jun 2021 15:30:52 -0700 Subject: [PATCH 1/4] chore: update cf-adapter to accept cache config options --- packages/adapter-cloudflare-workers/index.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/adapter-cloudflare-workers/index.js b/packages/adapter-cloudflare-workers/index.js index 856d162d3f27..4b57648153c2 100644 --- a/packages/adapter-cloudflare-workers/index.js +++ b/packages/adapter-cloudflare-workers/index.js @@ -4,7 +4,7 @@ import esbuild from 'esbuild'; import toml from '@iarna/toml'; import { fileURLToPath } from 'url'; -export default function () { +export default function (options = {}) { /** @type {import('@sveltejs/kit').Adapter} */ const adapter = { name: '@sveltejs/adapter-cloudflare-workers', @@ -29,12 +29,22 @@ export default function () { utils.log.minor('Generating worker...'); utils.copy(`${files}/entry.js`, '.svelte-kit/cloudflare-workers/entry.js'); + const { + pageCacheTTL = null, + staticCacheTTL = 60 * 60 * 24 * 90, // 90 days + edgeCacheTTL = 60 * 60 * 24 * 90 // 90 days + } = options; await esbuild.build({ entryPoints: ['.svelte-kit/cloudflare-workers/entry.js'], outfile: `${entrypoint}/index.js`, bundle: true, target: 'es2020', - platform: 'node' // TODO would be great if we could generate ESM and use type = "javascript" + platform: 'node', // TODO would be great if we could generate ESM and use type = "javascript" + define: { + PAGE_CACHE_TTL: pageCacheTTL, + STATIC_CACHE_TTL: staticCacheTTL, + EDGE_CACHE_TTL: edgeCacheTTL + } }); fs.writeFileSync(`${entrypoint}/package.json`, JSON.stringify({ main: 'index.js' })); From 4c8fa3449ffb27156b61e6f4917ab41b412bbd27 Mon Sep 17 00:00:00 2001 From: Lukas Welinder Date: Sun, 27 Jun 2021 15:33:30 -0700 Subject: [PATCH 2/4] BREAKING CHANGE(adapter-cloudflare-workers): add configurable cache --- .../adapter-cloudflare-workers/files/entry.js | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/packages/adapter-cloudflare-workers/files/entry.js b/packages/adapter-cloudflare-workers/files/entry.js index d5749d7f83cb..f5319f345c39 100644 --- a/packages/adapter-cloudflare-workers/files/entry.js +++ b/packages/adapter-cloudflare-workers/files/entry.js @@ -7,12 +7,26 @@ addEventListener('fetch', (event) => { }); async function handle(event) { + // fall back to an app route + const request = event.request; + const request_url = new URL(request.url); + // try static files first - if (event.request.method == 'GET') { + if (event.request.method == 'GET' && /\/.+\..+$/.test(request_url.pathname)) { try { + // TODO add per-asset/page options for cache + // use defaults for bot files (2d edge cache) + if (/sitemap.*\.xml$|robots.txt$/.test(request_url.pathname)) { + return await getAssetFromKV(event); + } // TODO rather than attempting to get an asset, // use the asset manifest to see if it exists - return await getAssetFromKV(event); + return await getAssetFromKV(event, { + cacheControl: { + browserTTL: STATIC_CACHE_TTL, + edgeTTL: EDGE_CACHE_TTL, + } + }); } catch (e) { if (!(e instanceof NotFoundError)) { return new Response('Error loading static asset:' + (e.message || e.toString()), { @@ -22,10 +36,6 @@ async function handle(event) { } } - // fall back to an app route - const request = event.request; - const request_url = new URL(request.url); - try { const rendered = await render({ host: request_url.host, @@ -37,6 +47,11 @@ async function handle(event) { }); if (rendered) { + const { headers } = rendered; + // inject cache-control header + if (!!PAGE_CACHE_TTL && !(headers['Cache-Control'] || headers['cache-control'])) { + rendered.headers['cache-control'] = `max-age=${PAGE_CACHE_TTL}`; + } return new Response(rendered.body, { status: rendered.status, headers: rendered.headers From de36a1e5c84fe0f2ec6a3c7457b8bdd2902d24d1 Mon Sep 17 00:00:00 2001 From: Lukas Welinder Date: Sun, 27 Jun 2021 15:34:21 -0700 Subject: [PATCH 3/4] docs: document options for cf-adapter --- packages/adapter-cloudflare-workers/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/adapter-cloudflare-workers/README.md b/packages/adapter-cloudflare-workers/README.md index 3b1820f4c521..bae025b869a5 100644 --- a/packages/adapter-cloudflare-workers/README.md +++ b/packages/adapter-cloudflare-workers/README.md @@ -22,6 +22,13 @@ bucket = "./build" entry-point = "./workers-site" ``` +The adapter accepts the following configuration properties: +| property | default | description | +|---|---|---| +| `pageCacheTTL` | `null` | Sets `cache-control` `max-age` for rendered responses if not defined. WARNING: this will apply to all page/request routes, disabled by default for security reasons. | +| `staticCacheTTL` | `60 * 60 * 24 * 90` (90 days) | Sets `cache-control` `max-age` for static assets. | +| `edgeCacheTTL` | `60 * 60 * 24 * 90` (90 days) | Sets CloudFlare Edge Cache TTL for static assets. | + It's recommended that you add the `build` and `workers-site` folders (or whichever other folders you specify) to your `.gitignore`. More info on configuring a cloudflare worker site can be found [here](https://developers.cloudflare.com/workers/platform/sites/start-from-existing) From 2c2e0835198f6ba73e6aa2032ec32f65db885371 Mon Sep 17 00:00:00 2001 From: Lukas Welinder Date: Tue, 29 Jun 2021 17:28:07 -0700 Subject: [PATCH 4/4] chore: resolve linting errors --- packages/adapter-cloudflare-workers/files/entry.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/adapter-cloudflare-workers/files/entry.js b/packages/adapter-cloudflare-workers/files/entry.js index f5319f345c39..fcd937dd209e 100644 --- a/packages/adapter-cloudflare-workers/files/entry.js +++ b/packages/adapter-cloudflare-workers/files/entry.js @@ -23,8 +23,10 @@ async function handle(event) { // use the asset manifest to see if it exists return await getAssetFromKV(event, { cacheControl: { + // eslint-disable-next-line no-undef browserTTL: STATIC_CACHE_TTL, - edgeTTL: EDGE_CACHE_TTL, + // eslint-disable-next-line no-undef + edgeTTL: EDGE_CACHE_TTL } }); } catch (e) { @@ -49,7 +51,9 @@ async function handle(event) { if (rendered) { const { headers } = rendered; // inject cache-control header + // eslint-disable-next-line no-undef if (!!PAGE_CACHE_TTL && !(headers['Cache-Control'] || headers['cache-control'])) { + // eslint-disable-next-line no-undef rendered.headers['cache-control'] = `max-age=${PAGE_CACHE_TTL}`; } return new Response(rendered.body, {