Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5d6c85d
use an alias instead of a resolveId hook
Rich-Harris Aug 15, 2026
9c16022
WIP
Rich-Harris Aug 15, 2026
395bea7
Fix: `uses_env_dynamic_public` detection uses the old generated-env m…
vercel[bot] Aug 15, 2026
bf63fd2
replace payload in service worker
Rich-Harris Aug 15, 2026
47599cb
format
Rich-Harris Aug 15, 2026
934d927
use a define
Rich-Harris Aug 15, 2026
68ff4bc
Merge branch 'generated-alias' into more-generated-aliases
Rich-Harris Aug 17, 2026
f178f72
drive-by
Rich-Harris Aug 17, 2026
c188038
reduce indirection
Rich-Harris Aug 17, 2026
f9f84ee
update comment
Rich-Harris Aug 17, 2026
a38e4a1
merge version-3
Rich-Harris Aug 17, 2026
dfe66ba
fix merge
Rich-Harris Aug 17, 2026
ba53e7c
fix
Rich-Harris Aug 17, 2026
0142651
get rid of __sveltekit/server
Rich-Harris Aug 17, 2026
a185aaf
unused
Rich-Harris Aug 17, 2026
b5daa79
more
Rich-Harris Aug 18, 2026
37a6385
more
Rich-Harris Aug 18, 2026
caaccee
oops
Rich-Harris Aug 18, 2026
a3296b3
changeset
Rich-Harris Aug 18, 2026
7b1bfea
Fix: Dev file-watcher writes regenerated server module to `generated/…
vercel[bot] Aug 18, 2026
d46ba5d
fix
Rich-Harris Aug 18, 2026
2c62571
prevent race condition with dep scanning
Rich-Harris Aug 18, 2026
ab7fa01
unused
Rich-Harris Aug 18, 2026
f9d1bc8
these were accidentally removed
Rich-Harris Aug 18, 2026
f972dd5
Update .changeset/shy-squids-film.md
Rich-Harris Aug 18, 2026
9d410b4
Merge branch 'more-generated-aliases' of github.com:sveltejs/kit into…
Rich-Harris Aug 18, 2026
5c31079
merge
Rich-Harris Aug 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/shy-squids-film.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@sveltejs/kit": patch
---

chore: remove virtual modules

21 changes: 0 additions & 21 deletions packages/kit/src/core/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,27 +251,6 @@ export function create_sveltekit_env_public(variables, env, prelude) {
return `${prelude}\n\n${exports.join('')}`;
}

/**
* Creates the `<sveltekit:generated>/env/public/client.js` module used in development. The dynamic
* values are inlined as a fallback for contexts that render without the dev server, like vitest
* browser mode, where nothing sets the global
* @param {Record<string, EnvVarConfig<any>> | null} variables
* @param {Record<string, string>} env
*/
export function create_sveltekit_env_public_dev(variables, env) {
if (!variables) {
return '';
}

const dev_env = validate_public_env(variables, env, false);

return create_sveltekit_env_public(
variables,
env,
`const env = globalThis.__sveltekit_dev?.env ?? ${devalue.uneval(dev_env)};`
);
}

/**
* @param {Record<string, EnvVarConfig<any>> | null} variables
* @param {Record<string, string>} env
Expand Down
23 changes: 11 additions & 12 deletions packages/kit/src/core/sync/create_manifest_data/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** @import { ValidatedConfig } from 'types' */
import { lookup } from '../../../utils/mime.js';
import fs from 'node:fs';
import path from 'node:path';
Expand All @@ -20,22 +21,20 @@ const module_name_pattern =

/**
* Generates the manifest data used for the client-side manifest and types generation.
* @param {{
* config: import('types').ValidatedConfig;
* fallback?: string;
* cwd: string;
* }} opts
* @param {ValidatedConfig} config
* @param {string} root
* @param {string} [fallback] Where to look for fallback components
* @returns {import('types').ManifestData}
*/
export default function create_manifest_data({
export default function create_manifest_data(
config,
fallback = `${runtime_directory}/components`,
cwd
}) {
root,
fallback = `${runtime_directory}/components`
) {
const assets = create_assets(config);
const hooks = create_hooks(config, cwd);
const params = resolve_params(config, cwd);
const { nodes, routes } = create_routes_and_nodes(cwd, config, fallback);
const hooks = create_hooks(config, root);
const params = resolve_params(config, root);
const { nodes, routes } = create_routes_and_nodes(root, config, fallback);

return {
assets,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ const create = (dir, config = {}) => {
initial.files.params = path.resolve(cwd, 'params');
initial.files.routes = path.resolve(cwd, dir);

return create_manifest_data({
config: /** @type {import('types').ValidatedConfig} */ (initial),
fallback: cwd,
cwd
});
return create_manifest_data(initial, cwd, cwd);
};

const default_layout = {
Expand Down
54 changes: 19 additions & 35 deletions packages/kit/src/core/sync/sync.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** @import { ValidatedConfig, ManifestData } from 'types' */
import path from 'node:path';
import create_manifest_data from './create_manifest_data/index.js';
import { write_client_manifest } from './write_client_manifest.js';
Expand All @@ -11,39 +12,30 @@ import {
} from '../../exports/vite/static_analysis/index.js';
import { load_explicit_env } from '../env.js';
import { write_env } from './write_env.js';

/**
* Initialize SvelteKit's generated files that only depend on the config and mode.
* @param {import('types').ValidatedConfig} config
* @param {string} root The project root directory
*/
export function init(config, root) {
write_tsconfig(config, root);
}
import { write_app_manifest } from './write_app_manifest.js';

/**
* Update SvelteKit's generated files
* @param {import('types').ValidatedConfig} config
* @param {ValidatedConfig} config
* @param {string} root The project root directory
* @param {ManifestData} manifest_data
* @param {boolean} is_build
*/
export function create(config, root) {
const manifest_data = create_manifest_data({ config, cwd: root });

const output = path.join(config.outDir, 'generated');
export function create(config, root, manifest_data, is_build) {
const output = path.join(config.outDir, `generated/${is_build ? 'build' : 'dev'}`);

write_app_manifest(output, manifest_data, is_build);
write_client_manifest(config, manifest_data, `${output}/client`, root);
write_server(config, output, root);
write_all_types(config, manifest_data, root);
write_app_types(config, manifest_data, root);

return { manifest_data };
}

/**
* Update SvelteKit's generated files in response to a single file content update.
* Do not call this when the file in question was created/deleted.
*
* @param {import('types').ValidatedConfig} config
* @param {ValidatedConfig} config
* @param {import('types').ManifestData} manifest_data
* @param {string} file
* @param {string} root The project root directory
Expand Down Expand Up @@ -79,30 +71,31 @@ export function update(config, manifest_data, file, root) {
}

/**
* Run sync.init and sync.create in series, returning the result from sync.create.
* @param {import('types').ValidatedConfig} config
* Run write_tsconfig and sync.create in series during build
* @param {ValidatedConfig} config
* @param {string} root The project root directory
* @param {ManifestData} manifest_data
*/
export function all(config, root) {
init(config, root);
return create(config, root);
export function all(config, root, manifest_data) {
write_tsconfig(config, root);
create(config, root, manifest_data, true);
}

/**
* Run sync.init and then generate all type files.
* @param {import('types').ValidatedConfig} config
* @param {ValidatedConfig} config
* @param {string} root
*/
export function all_types(config, root) {
init(config, root);
const manifest_data = create_manifest_data({ config, cwd: root });
write_tsconfig(config, root);
const manifest_data = create_manifest_data(config, root);
write_all_types(config, manifest_data, root);
write_app_types(config, manifest_data, root);
}

/**
* Generate modules and types for explicit env vars
* @param {import('types').ValidatedConfig} kit
* @param {ValidatedConfig} kit
* @param {string | null} entry
* @param {string} root The Vite root
* @param {string} mode The Vite mode
Expand All @@ -114,12 +107,3 @@ export async function env(kit, entry, root, mode) {

return env_config;
}

/**
* Regenerate __SERVER__/internal.js in response to src/{app.html,error.html,service-worker.js} changing
* @param {import('types').ValidatedConfig} config
* @param {string} root The project root directory
*/
export function server(config, root) {
write_server(config, path.join(config.outDir, 'generated'), root);
}
6 changes: 4 additions & 2 deletions packages/kit/src/core/sync/sync.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { expect, test } from 'vitest';
import { process_config, validate_config } from '../config/index.js';
import { relative_path } from '../../utils/filesystem.js';
import { create, update } from './sync.js';
import create_manifest_data from './create_manifest_data/index.js';

test('generates client manifest imports relative to the project root', () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'svelte-kit-sync-'));
Expand All @@ -19,11 +20,12 @@ test('generates client manifest imports relative to the project root', () => {

try {
const config = process_config(validate_config({}), root);
const { manifest_data } = create(config, root);
const manifest_data = create_manifest_data(config, root);
create(config, root, manifest_data, true);
const index = manifest_data.nodes.findIndex(
(node) => node.component === 'src/routes/+page.svelte'
);
const output = path.join(config.outDir, 'generated/client');
const output = path.join(config.outDir, 'generated/build/client');
const generated = fs.readFileSync(path.join(output, `nodes/${index}.js`), 'utf8');

expect(generated).toBe(
Expand Down
83 changes: 83 additions & 0 deletions packages/kit/src/core/sync/write_app_manifest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/** @import { Asset, ManifestData, RouteData } from 'types' */

import { s } from '../../utils/misc.js';
import { is_app_route, is_endpoint_route, is_page_route } from './create_manifest_data/index.js';
import { dedent, write_if_changed } from './utils.js';

/**
* Creates the `$app/manifest` data module. During development, real values
* are emitted for `assets` and `routes` (the only data known at that point).
*
* During build, bare identifier placeholders (fake globals) are emitted.
* The bundler leaves these as unresolved global references in the output,
* which are then replaced with real values by scanning the output chunks
* after each build completes. This avoids the content-hash feedback loop:
* the manifest data lives in its own chunk with a fixed filename, so
* importers' hashes are stable regardless of the manifest content.
*
* @param {string} out
* @param {ManifestData | undefined} manifest_data
* @param {boolean} is_build
*/
export function write_app_manifest(out, manifest_data, is_build) {
const code = is_build
? // Bare identifiers (fake globals) — the bundler leaves these as
// unresolved global references in the output. They are replaced
// with real values by `replace_manifest_placeholder_variables`
// after each build completes.
dedent`
export const immutable = __SVELTEKIT_MANIFEST_IMMUTABLE__;
export const assets = __SVELTEKIT_MANIFEST_ASSETS__;
export const prerendered = __SVELTEKIT_MANIFEST_PRERENDERED__;
export const routes = __SVELTEKIT_MANIFEST_ROUTES__;
`
: // In dev, an empty manifest is written before dependency scanning starts.
// `configureServer` replaces it with the full manifest before modules are served.
dedent`
// empty during dev
export const immutable = [];
export const prerendered = [];

export const assets = [
${stringify_assets(manifest_data?.assets)}
];

export const routes = [
${stringify_routes(manifest_data?.routes)}
];
`;

write_if_changed(`${out}/app-manifest.js`, code);
}

/**
* @param {Asset[] | undefined} assets
* @returns {string}
*/
function stringify_assets(assets) {
return assets?.map((asset) => s({ path: asset.file })).join(',\n') ?? '';
}

/**
* @param {RouteData[] | undefined} routes
* @returns {Array<{ id: string; page: boolean; endpoint: boolean }>}
*/
export function get_manifest_routes(routes) {
return (
routes?.filter(is_app_route).map((route) => ({
id: route.id,
page: is_page_route(route),
endpoint: is_endpoint_route(route)
})) ?? []
);
}

/**
* @param {RouteData[] | undefined} routes
* @returns {string}
*/
function stringify_routes(routes) {
return get_manifest_routes(routes)
.map((route) => s(route))
.join(',\n');
}
14 changes: 9 additions & 5 deletions packages/kit/src/core/sync/write_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { s } from '../../utils/misc.js';
import { load_error_page, load_template } from '../config/index.js';
import { check_spelling, write_if_changed } from './utils.js';
import { escape_html } from '../../utils/escape.js';
import { runtime_directory } from '../utils.js';

/**
* @param {{
Expand All @@ -14,19 +15,21 @@ import { escape_html } from '../../utils/escape.js';
* config: import('types').ValidatedConfig;
* has_service_worker: boolean;
* template: string;
* runtime_directory: string;
* }} opts
*/
const server_template = ({
config,
server_hooks,
universal_hooks,
has_service_worker,
template
template,
runtime_directory
}) => `
import { set_building, set_prerendering } from '$app/env/server';
import { set_assets } from '$app/paths/internal/server';
import { set_fix_stack_trace, set_manifest, set_read_implementation, log_response } from '__sveltekit/server';
import error from '../shared/error-template.js';
import { set_fix_stack_trace, set_manifest, set_read_implementation, log_response } from '${runtime_directory}/server/internal.js';
import error from './shared/error-template.js';

export const options = {
app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')},
Expand Down Expand Up @@ -103,7 +106,7 @@ export function write_server(config, output, root) {

/** @param {string} file */
function relative(file) {
return posixify(path.relative(`${output}/server`, file));
return posixify(path.relative(output, file));
}

write_if_changed(
Expand All @@ -116,9 +119,10 @@ export function write_server(config, output, root) {
// Contains the stringified version of
/** @type {import('types').SSROptions} */
write_if_changed(
`${output}/server/internal.js`,
`${output}/server.js`,
server_template({
config,
runtime_directory: relative(runtime_directory),
server_hooks: server_hooks_file ? relative(server_hooks_file) : null,
universal_hooks: universal_hooks_file ? relative(universal_hooks_file) : null,
has_service_worker:
Expand Down
5 changes: 1 addition & 4 deletions packages/kit/src/core/sync/write_types/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ function run_test(dir) {

const root = path.join(cwd, dir);

const manifest = create_manifest_data({
config: /** @type {import('types').ValidatedConfig} */ (initial),
cwd: root
});
const manifest = create_manifest_data(initial, root);

write_all_types(initial, manifest, root);
write_app_types(initial, manifest, root);
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/exports/vite/build/build_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export function build_server_nodes(
}

if (client_manifest) {
const entry_path = `${out_dir}/generated/client-optimized/nodes/${i}.js`;
const entry_path = `${out_dir}/generated/build/client-optimized/nodes/${i}.js`;
const entry = find_deps(client_manifest, entry_path, true, root);

// Eagerly load client stylesheets and fonts imported by the SSR-ed page to avoid FOUC.
Expand Down
Loading
Loading