-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
Describe the bug
Hi,
Forgive me if I've missed something! I'd like to run SvelteKit as a SSR-and-CSR solution, with no build-time prerendering.
From the docs, I can disable prerendering routes by adding a export const prerender = false;
annotation to the top-level +layout.js
. This seems to work.
I can also prevent the build process from crawling for entries to prerender (svelte.config.js
):
// Disable prerendering, as this is a dynamic app
prerender: {
crawl: false,
entries: [],
},
However, despite these two settings, I am still seeing an attempt to prerender when I run vite build
:
#13 38.79 handleFeatureFlags (hooks/featureFlags.js) running for URL: http://sveltekit-prerender/[fallback]
...
#13 58.82 TypeError: Cannot destructure property 'CI_ENVIRONMENT_NAME' of 'env' as it is undefined.
#13 58.82 at reportError (file:///app/server/.svelte-kit/output/server/chunks/hooks.server.js:954:32)
#13 58.82 at Object.handleError (file:///app/server/.svelte-kit/output/server/chunks/hooks.server.js:1011:27)
#13 58.82 at Object.handle_error (file:///app/server/.svelte-kit/output/server/index.js:2369:35)
#13 58.82 at handle_error_and_jsonify (file:///app/server/.svelte-kit/output/server/index.js:243:20)
#13 58.82 at handle_fatal_error (file:///app/server/.svelte-kit/output/server/index.js:226:22)
#13 58.82 at respond (file:///app/server/.svelte-kit/output/server/index.js:2196:18)
#13 58.82 at async prerender (file:///app/server/node_modules/@sveltejs/kit/src/core/prerender/prerender.js:439:19)
...
#13 58.85 [vite-plugin-svelte-kit] Prerendering failed with code 1
#13 58.85 error during build:
#13 58.85 Error: Prerendering failed with code 1
#13 58.85 at ChildProcess.<anonymous> (file:///app/server/node_modules/@sveltejs/kit/src/exports/vite/index.js:462:15)
#13 58.85 at ChildProcess.emit (node:events:513:28)
#13 58.85 at ChildProcess.emit (node:domain:489:12)
#13 58.85 at Process.ChildProcess._handle.onexit (node:internal/child_process:293:12)
I've tracked this down to this code block:
const rendered = await server.respond(new Request(config.prerender.origin + '/[fallback]'), {
getClientAddress,
prerendering: {
fallback: true,
dependencies: new Map()
}
});
const file = `${config.outDir}/output/prerendered/fallback.html`;
mkdirp(dirname(file));
writeFileSync(file, await rendered.text());
Whereas prerendering known routes and other entries can be disabled with the above config, there doesn't seem to be a way to disable the rendering of the fallback.html
file. This is a problem for anyone who wants to ship code in server hooks which doesn't work in the environment in which vite build
is run.
Would it be possible to allow this fallback prerendering to be disabled? If not, it'd be great to understand why it's important (somewhere in the documentation), and I guess the only option is for the hooks to make use of $app/environment.building
or similar to only conditionally run their logic?
Reproduction
https://stackblitz.com/edit/sveltejs-kit-template-default-x9vwcp
This project adds the following changes to the default https://node.new/sveltekit
:
- adds
export const prerender = false;
tosrc/routes/+layout.js
- removes
export const prerender = true;
from all other routes - disables prerender crawling in
svelte.config.js
:
const config = {
kit: {
adapter: adapter(),
// Disable prerendering, as this is a dynamic app
prerender: {
crawl: false,
entries: []
}
}
};
- adds a
hooks.server.js
file which relies on environment variables:
export async function handle({ event, resolve }) {
const thisWillFail = new URL(process.env.UNDECLARED_ENV_VAR_DURING_BUILD);
const response = await resolve(event);
return response;
}
export async function handleError({ error, event }) {
const thisWillFail = new URL(process.env.UNDECLARED_ENV_VAR_DURING_BUILD);
return error;
}
- modifies the
npm run dev
script to be"UNDECLARED_ENV_VAR_DURING_BUILD='http://testing' vite dev"
so that local dev works
Running npm run build
shows that an attempt to prerender the URL http://sveltekit-prerender/[fallback]
is still made, and since the environment variable is not declared, the hooks cause the build to fail:
...
.svelte-kit/output/server/chunks/hooks.server.js 0.37 KiB
handle hook running for URL: http://sveltekit-prerender/[fallback]
TypeError [ERR_INVALID_URL]: Invalid URL
...
input: 'undefined',
code: 'ERR_INVALID_URL'
}
[vite-plugin-svelte-kit] Prerendering failed with code 1
error during build:
Error: Prerendering failed with code 1
...
One solution I've found for this is the following, in hooks.server.js
:
import {building} from '$app/environment';
export const handle = building
? sequence()
: sequence(
handleLoggingAndMonitoring,
handleCookieParsing,
handleFeatureFlags,
handleEnvVars,
handleImageUrls,
handleApiRequest,
handleApiServices,
handleSecurityHeaders
);
Is this the recommended approach? If so, it still seems odd to me that I'm unable to disable prerendering across the board.
Logs
No response
System Info
System:
OS: macOS 12.4
CPU: (8) arm64 Apple M1 Pro
Memory: 212.80 MB / 32.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 16.18.0 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 8.19.2 - /usr/local/bin/npm
Watchman: 2022.11.14.00 - /opt/homebrew/bin/watchman
Browsers:
Chrome: 107.0.5304.110
Chrome Canary: 110.0.5443.0
Firefox: 105.0.3
Safari: 15.5
npmPackages:
@sveltejs/adapter-node: ^1.0.0-next.101 => 1.0.0-next.101
@sveltejs/kit: ^1.0.0-next.570 => 1.0.0-next.570
svelte: ^3.53.1 => 3.53.1
Severity
blocking all usage of SvelteKit
Additional Information
No response