From 678e80a4565c5e07e5fd2eec2dde3de31158667a Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Fri, 17 Mar 2023 10:26:22 +0100 Subject: [PATCH 1/2] fix: enhance and tighten up Vercel adapter warnings - warn when prerender setting makes isr config useless - don't show cron warning when everything's valid - allow to set isr to false to clear isr config in leafs (else it's impossible to do so because config is merged at the top level) - prefixed all warnings with "Warning:" which should help detect the Vercel log dashboard show these in condensed mode where only warnings/errors are shown --- .changeset/forty-suns-listen.md | 5 +++ .changeset/polite-islands-glow.md | 5 +++ .changeset/tasty-weeks-rush.md | 5 +++ packages/adapter-vercel/index.d.ts | 36 ++++++++++--------- packages/adapter-vercel/index.js | 58 +++++++++++++++++++++++------- packages/kit/types/index.d.ts | 2 +- 6 files changed, 80 insertions(+), 31 deletions(-) create mode 100644 .changeset/forty-suns-listen.md create mode 100644 .changeset/polite-islands-glow.md create mode 100644 .changeset/tasty-weeks-rush.md diff --git a/.changeset/forty-suns-listen.md b/.changeset/forty-suns-listen.md new file mode 100644 index 000000000000..1fc590514bf5 --- /dev/null +++ b/.changeset/forty-suns-listen.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/adapter-vercel': minor +--- + +feat: warn when prerender setting makes isr config useless diff --git a/.changeset/polite-islands-glow.md b/.changeset/polite-islands-glow.md new file mode 100644 index 000000000000..3cdfd433471e --- /dev/null +++ b/.changeset/polite-islands-glow.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/adapter-vercel': patch +--- + +fix: don't show cron warning when everything's valid diff --git a/.changeset/tasty-weeks-rush.md b/.changeset/tasty-weeks-rush.md new file mode 100644 index 000000000000..49ff12af80a3 --- /dev/null +++ b/.changeset/tasty-weeks-rush.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/adapter-vercel': patch +--- + +fix: allow to set isr to false to clear isr config in leafs diff --git a/packages/adapter-vercel/index.d.ts b/packages/adapter-vercel/index.d.ts index ea45bf4e0ac5..5b4a70b3fd51 100644 --- a/packages/adapter-vercel/index.d.ts +++ b/packages/adapter-vercel/index.d.ts @@ -32,23 +32,25 @@ export interface ServerlessConfig { * [Incremental Static Regeneration](https://vercel.com/docs/concepts/incremental-static-regeneration/overview) configuration. * Serverless only. */ - isr?: { - /** - * Expiration time (in seconds) before the cached asset will be re-generated by invoking the Serverless Function. Setting the value to `false` means it will never expire. - */ - expiration: number | false; - /** - * Random token that can be provided in the URL to bypass the cached version of the asset, by requesting the asset - * with a __prerender_bypass= cookie. - * - * Making a `GET` or `HEAD` request with `x-prerender-revalidate: ` will force the asset to be re-validated. - */ - bypassToken?: string; - /** - * List of query string parameter names that will be cached independently. If an empty array, query values are not considered for caching. If undefined each unique query value is cached independently - */ - allowQuery?: string[] | undefined; - }; + isr?: + | { + /** + * Expiration time (in seconds) before the cached asset will be re-generated by invoking the Serverless Function. Setting the value to `false` means it will never expire. + */ + expiration: number | false; + /** + * Random token that can be provided in the URL to bypass the cached version of the asset, by requesting the asset + * with a __prerender_bypass= cookie. + * + * Making a `GET` or `HEAD` request with `x-prerender-revalidate: ` will force the asset to be re-validated. + */ + bypassToken?: string; + /** + * List of query string parameter names that will be cached independently. If an empty array, query values are not considered for caching. If undefined each unique query value is cached independently + */ + allowQuery?: string[] | undefined; + } + | false; } export interface EdgeConfig { diff --git a/packages/adapter-vercel/index.js b/packages/adapter-vercel/index.js index 1685513284c3..4c2d195d4300 100644 --- a/packages/adapter-vercel/index.js +++ b/packages/adapter-vercel/index.js @@ -153,13 +153,21 @@ const plugin = function (defaults = {}) { /** @type {Map, { expiration: number | false, bypassToken: string | undefined, allowQuery: string[], group: number, passQuery: true }>} */ const isr_config = new Map(); + /** @type {Set} */ + const ignored_isr = new Set(); + // group routes by config for (const route of builder.routes) { - if (route.prerender === true) continue; + const runtime = route.config?.runtime ?? defaults?.runtime ?? get_default_runtime(); + const config = { runtime, ...defaults, ...route.config }; - const pattern = route.pattern.toString(); + if (is_prerendered(route)) { + if (config.isr) { + ignored_isr.add(route.id); + } + continue; + } - const runtime = route.config?.runtime ?? defaults?.runtime ?? get_default_runtime(); if (runtime && !VALID_RUNTIMES.includes(runtime)) { throw new Error( `Invalid runtime '${runtime}' for route ${ @@ -168,8 +176,6 @@ const plugin = function (defaults = {}) { ); } - const config = { runtime, ...defaults, ...route.config }; - if (config.isr) { const directory = path.relative('.', builder.config.kit.files.routes + route.id); @@ -197,6 +203,7 @@ const plugin = function (defaults = {}) { const hash = hash_config(config); // first, check there are no routes with incompatible configs that will be merged + const pattern = route.pattern.toString(); const existing = conflicts.get(pattern); if (existing) { if (existing.hash !== hash) { @@ -219,6 +226,20 @@ const plugin = function (defaults = {}) { group.routes.push(route); } + if (ignored_isr.size) { + builder.log.warn( + `\nWarning: The following routes have an ISR config which is ignored because the route is prerendered:` + ); + + for (const ignored of ignored_isr) { + console.log(` - ${ignored}`); + } + + console.log( + 'Either remove the "prerender" option from these routes to use ISR, or remove the ISR config.\n' + ); + } + const singular = groups.size === 1; for (const group of groups.values()) { @@ -240,7 +261,7 @@ const plugin = function (defaults = {}) { } for (const route of builder.routes) { - if (route.prerender === true) continue; + if (is_prerendered(route)) continue; const pattern = route.pattern.toString(); @@ -456,7 +477,7 @@ async function create_function_bundle(builder, entry, dir, config) { if (resolution_failures.size > 0) { const cwd = process.cwd(); builder.log.warn( - 'The following modules failed to locate dependencies that may (or may not) be required for your app to work:' + 'Warning: The following modules failed to locate dependencies that may (or may not) be required for your app to work:' ); for (const [importer, modules] of resolution_failures) { @@ -572,15 +593,26 @@ function validate_vercel_json(builder, vercel_config) { unmatched_paths.push(path); } - builder.log.warn( - `\nvercel.json defines cron tasks that use paths that do not correspond to an API route with a GET handler (ignore this if the request is handled in your \`handle\` hook):` - ); + if (unmatched_paths.length) { + builder.log.warn( + `\nWarning: vercel.json defines cron tasks that use paths that do not correspond to an API route with a GET handler (ignore this if the request is handled in your \`handle\` hook):` + ); + + for (const path of unmatched_paths) { + console.log(` - ${path}`); + } - for (const path of unmatched_paths) { - console.log(` - ${path}`); + console.log(''); } +} - console.log(''); +/** @param {import('@sveltejs/kit').RouteDefinition} route */ +function is_prerendered(route) { + return ( + route.prerender === true || + (route.prerender === 'auto' && + !route.segments.some((segment) => segment.dynamic || segment.rest)) + ); } export default plugin; diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index a5a0d2637dac..2bdfc685e200 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -87,7 +87,7 @@ export interface Builder { config: ValidatedConfig; /** Information about prerendered pages and assets, if any. */ prerendered: Prerendered; - /** An array of dynamic (not prerendered) routes */ + /** An array of all routes (including prerendered) */ routes: RouteDefinition[]; /** From afb36db6df1bb441e8cdf70901c573b5061fbffc Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Fri, 17 Mar 2023 16:28:28 +0100 Subject: [PATCH 2/2] Update packages/adapter-vercel/index.js Co-authored-by: Rich Harris --- packages/adapter-vercel/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adapter-vercel/index.js b/packages/adapter-vercel/index.js index 4c2d195d4300..9be89e3772b0 100644 --- a/packages/adapter-vercel/index.js +++ b/packages/adapter-vercel/index.js @@ -611,7 +611,7 @@ function is_prerendered(route) { return ( route.prerender === true || (route.prerender === 'auto' && - !route.segments.some((segment) => segment.dynamic || segment.rest)) + route.segments.every((segment) => !segment.dynamic)) ); }