Skip to content

Commit df163d2

Browse files
authored
fix: set $env and $app/environment variables before analysing server nodes (#13790)
* fix, test, and changeset * format * fix test * avoid analysing twice when building nodes * return cache and reuse it since analyse is a forked process
1 parent a14027c commit df163d2

File tree

9 files changed

+66
-33
lines changed

9 files changed

+66
-33
lines changed

.changeset/smooth-rockets-complain.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
fix: ensure `$env` and `$app/environment` are correctly set while analysing server nodes

packages/kit/src/core/postbuild/analyse.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { has_server_load, resolve_route } from '../../utils/routing.js';
1010
import { check_feature } from '../../utils/features.js';
1111
import { createReadableStream } from '@sveltejs/kit/node';
1212
import { PageNodes } from '../../utils/page_nodes.js';
13+
import { build_server_nodes } from '../../exports/vite/build/build_server.js';
1314

1415
export default forked(import.meta.url, analyse);
1516

@@ -20,7 +21,9 @@ export default forked(import.meta.url, analyse);
2021
* manifest_data: import('types').ManifestData;
2122
* server_manifest: import('vite').Manifest;
2223
* tracked_features: Record<string, string[]>;
23-
* env: Record<string, string>
24+
* env: Record<string, string>;
25+
* out: string;
26+
* output_config: import('types').RecursiveRequired<import('types').ValidatedConfig['kit']['output']>;
2427
* }} opts
2528
*/
2629
async function analyse({
@@ -29,7 +32,9 @@ async function analyse({
2932
manifest_data,
3033
server_manifest,
3134
tracked_features,
32-
env
35+
env,
36+
out,
37+
output_config
3338
}) {
3439
/** @type {import('@sveltejs/kit').SSRManifest} */
3540
const manifest = (await import(pathToFileURL(manifest_path).href)).manifest;
@@ -58,6 +63,20 @@ async function analyse({
5863
internal.set_manifest(manifest);
5964
internal.set_read_implementation((file) => createReadableStream(`${server_root}/server/${file}`));
6065

66+
const static_exports = new Map();
67+
68+
// first, build server nodes without the client manifest so we can analyse it
69+
await build_server_nodes(
70+
out,
71+
config,
72+
manifest_data,
73+
server_manifest,
74+
null,
75+
null,
76+
output_config,
77+
static_exports
78+
);
79+
6180
/** @type {import('types').ServerMetadata} */
6281
const metadata = {
6382
nodes: [],
@@ -143,7 +162,7 @@ async function analyse({
143162
});
144163
}
145164

146-
return metadata;
165+
return { metadata, static_exports };
147166
}
148167

149168
/**

packages/kit/src/exports/vite/build/build_server.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { filter_fonts, find_deps, resolve_symlinks } from './utils.js';
44
import { s } from '../../../utils/misc.js';
55
import { normalizePath } from 'vite';
66
import { basename, join } from 'node:path';
7-
import { create_static_analyser } from '../static_analysis/index.js';
7+
import { create_node_analyser } from '../static_analysis/index.js';
8+
89

910
/**
1011
* @param {string} out
@@ -14,8 +15,9 @@ import { create_static_analyser } from '../static_analysis/index.js';
1415
* @param {import('vite').Manifest | null} client_manifest
1516
* @param {import('vite').Rollup.OutputAsset[] | null} css
1617
* @param {import('types').RecursiveRequired<import('types').ValidatedConfig['kit']['output']>} output_config
18+
* @param {Map<string, Record<string, any> | null>} static_exports
1719
*/
18-
export async function build_server_nodes(out, kit, manifest_data, server_manifest, client_manifest, css, output_config) {
20+
export async function build_server_nodes(out, kit, manifest_data, server_manifest, client_manifest, css, output_config, static_exports) {
1921
mkdirp(`${out}/server/nodes`);
2022
mkdirp(`${out}/server/stylesheets`);
2123

@@ -74,9 +76,12 @@ export async function build_server_nodes(out, kit, manifest_data, server_manifes
7476
}
7577
}
7678

77-
const { get_page_options } = create_static_analyser(async (server_node) => {
78-
// Windows needs the file:// protocol for absolute path dynamic imports
79-
return import(`file://${join(out, 'server', resolve_symlinks(server_manifest, server_node).chunk.file)}`);
79+
const { get_page_options } = create_node_analyser({
80+
resolve: (server_node) => {
81+
// Windows needs the file:// protocol for absolute path dynamic imports
82+
return import(`file://${join(out, 'server', resolve_symlinks(server_manifest, server_node).chunk.file)}`);
83+
},
84+
static_exports
8085
});
8186

8287
for (let i = 0; i < manifest_data.nodes.length; i++) {

packages/kit/src/exports/vite/dev/index.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { not_found } from '../utils.js';
1919
import { SCHEME } from '../../../utils/url.js';
2020
import { check_feature } from '../../../utils/features.js';
2121
import { escape_html } from '../../../utils/escape.js';
22-
import { create_static_analyser } from '../static_analysis/index.js';
22+
import { create_node_analyser } from '../static_analysis/index.js';
2323

2424
const cwd = process.cwd();
2525
// vite-specifc queries that we should skip handling for css urls
@@ -128,11 +128,13 @@ export async function dev(vite, vite_config, svelte_config) {
128128
return;
129129
}
130130

131-
const static_analyser = create_static_analyser(async (server_node) => {
132-
const { module } = await resolve(server_node);
133-
return module;
131+
const node_analyser = create_node_analyser({
132+
resolve: async (server_node) => {
133+
const { module } = await resolve(server_node);
134+
return module;
135+
}
134136
});
135-
invalidate_page_options = static_analyser.invalidate_page_options;
137+
invalidate_page_options = node_analyser.invalidate_page_options;
136138

137139
manifest = {
138140
appDir: svelte_config.kit.appDir,
@@ -212,7 +214,7 @@ export async function dev(vite, vite_config, svelte_config) {
212214
}
213215

214216
if (node.universal) {
215-
const page_options = await static_analyser.get_page_options(node);
217+
const page_options = await node_analyser.get_page_options(node);
216218
if (page_options?.ssr === false) {
217219
result.universal = page_options;
218220
} else {

packages/kit/src/exports/vite/index.js

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -818,26 +818,17 @@ Tips:
818818
})};\n`
819819
);
820820

821-
// first, build server nodes without the client manifest so we can analyse it
822821
log.info('Analysing routes');
823822

824-
await build_server_nodes(
825-
out,
826-
kit,
827-
manifest_data,
828-
server_manifest,
829-
null,
830-
null,
831-
svelte_config.output
832-
);
833-
834-
const metadata = await analyse({
823+
const { metadata, static_exports } = await analyse({
835824
hash: kit.router.type === 'hash',
836825
manifest_path,
837826
manifest_data,
838827
server_manifest,
839828
tracked_features,
840-
env: { ...env.private, ...env.public }
829+
env: { ...env.private, ...env.public },
830+
out,
831+
output_config: svelte_config.output
841832
});
842833

843834
log.info('Building app');
@@ -990,7 +981,8 @@ Tips:
990981
server_manifest,
991982
client_manifest,
992983
css,
993-
svelte_config.kit.output
984+
svelte_config.kit.output,
985+
static_exports
994986
);
995987

996988
// ...and prerender

packages/kit/src/exports/vite/static_analysis/index.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,12 @@ export function get_name(node) {
181181
}
182182

183183
/**
184-
* @param {(server_node: string) => Promise<Record<string, any>>} resolve
184+
* @param {{
185+
* resolve: (file: string) => Promise<Record<string, any>>;
186+
* static_exports?: Map<string, Record<string, any> | null>;
187+
* }} opts
185188
*/
186-
export function create_static_analyser(resolve) {
187-
/** @type {Map<string, Record<string, any> | null>} */
188-
const static_exports = new Map();
189-
189+
export function create_node_analyser({ resolve, static_exports = new Map() }) {
190190
/**
191191
* Computes the final page options for a node (if possible). Otherwise, returns `null`.
192192
* @param {import('types').PageNode} node
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// this universal file causes the server node to be evaluated during static analysis
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// this module is evaluated when building the server nodes to determine its page options
2+
// Therefore, we need to ensure $env, etc. still works during this process so that it doesn't throw errors
3+
// when it's evaluated as `undefined`
4+
5+
import { env } from '$env/dynamic/public';
6+
7+
if (!env.PUBLIC_DYNAMIC) {
8+
throw Error('this should not happen');
9+
}

packages/kit/test/apps/basics/src/routes/node-analysis/+page.svelte

Whitespace-only changes.

0 commit comments

Comments
 (0)