-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
fix: load env before prerender #14219
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
Conversation
🦋 Changeset detectedLatest commit: b2d1de4 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Isn't this somewhat by design? If you access
We mention it in the docs:
Feels like this would be a way to circumvent that restriction, which is there for a good reason. Can we error when accessing dynamic env vars in remote files during prerendering, same as we do otherwise? |
|
Uh i wasn't aware of this restriction...the problem is that since we are importing the remote files during prerendering even if there's no We should at least throw a more descriptive error but it also feels like kinda of an heavy restriction considering remotes are almost designed to access |
|
Ideally you wouldn't be initializing your db using dynamic env vars during analysis/prerendering — that would be gated on |
|
Maybe a change should be aimed at the sv cli instead (specifically drizzle)? |
|
What about wrapping the drizzle init code in a function and then calling it from the // src/hooks.server.ts
import { createPostgresClient } from '$lib/server/database';
import type { ServerInit } from '@sveltejs/kit';
export const init: ServerInit = async () => {
await initDatabase();
};// src/lib/server/database/index.ts
export let client;
export let db;
export function initDatabase() {
if (!env.DATABASE_URL) throw new Error('DATABASE_URL is not set');
client = neon(env.DATABASE_URL);
db = drizzle(client, { schema });
} |
|
Yeah I think we would also need to change that...but that's just generated code, you could write similar code yourself and it wouldn't feel weird to write. |
|
Thinking this through... the original prohibition on using dynamic env vars while prerendering was a response to #10008. There were two issues:
The first of these feels like a bit of a shrug to be honest. If you're prerendering then you're choosing to use build-time variables, and I'm not exactly sure what the risks of exposure are — if you render The second is a real thing. But it was fixed by populating public env from a generated endpoint in the case where the user lands on a prerendered page, instead of embedding vars in the HTML. That would continue to be the case if we allowed dynamic env var access when analysing/prerendering remote functions. So... maybe I take back what I said above and this is fine? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The presence of this file alone is the test for if this works or not, right? Can we add a comment to this file explaining that if that’s the case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Co-authored-by: Rich Harris <[email protected]>
Does setting the envs at the beginning of the prerender phase breaks this? I think the prerender function is also used to prerender prerendered pages no? Also would this break something or should we guard the code I added with |
Been digging into this and... not exactly. The error happens because of this — inside kit/packages/kit/src/runtime/server/index.js Lines 55 to 60 in d89d6e2
We don't call kit/packages/kit/src/core/postbuild/prerender.js Lines 497 to 501 in d89d6e2
...which is later than the kit/packages/kit/src/core/postbuild/prerender.js Lines 480 to 489 in d89d6e2
The end result is that if you have This troubles me a bit, because it means that these equivalent bits of code will behave very differently: let message = env.MESSAGE;
export const get_message = prerender(() => {
return message;
});export const get_message = prerender(() => {
return env.MESSAGE;
});It also means that some top-level occurrences will be fine, while others won't be, depending on which modules happened to be imported before the We really should have consistency here. And while we could presumably achieve that by putting the So I'm forced to conclude that we should just allow <script>
import { env } from '$env/dynamic/public';
</script>
<h1>{env.PUBLIC_MESSAGE}</h1>...the contents of the Another thing I noticed while looking into this — turns out we don't abort if a |
|
Opened #14243 |
|
Can't the pre-renderer just throw an error or skip pre-rendering of content that uses dynamic env? |
|
How? |
…prerender (#14464) fixes #14347 This PR reverts the fix from #14219 which caused the init hook to run even if there's nothing to prerender. Instead of running the init hook early, we just set the env variables when looking for prerendered remote functions. This avoids any errors for missing env variables when evaluating the user's remote function modules. We only run the init hook once we've found things we need to prerender.
If you access dynamic
envin a remote file (even through other meanings like importing the default generated db when you dosv create) the value will be empty during the prerendering of the remote functions...even worse if you have a situation like this (like the default generated db when you dosv create)it will throw even if
SOME_VARis set because in theprerenderfunction we don't set the environment line inanalyseThis PR fixes that. I would appreciate some pointer on where to write such test (I know we shouldn't add app like if they were free :D )
Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
Tests
pnpm testand lint the project withpnpm lintandpnpm checkChangesets
pnpm changesetand following the prompts. Changesets that add features should beminorand those that fix bugs should bepatch. Please prefix changeset messages withfeat:,fix:, orchore:.Edits