@sveltejs/kit 3.0.0-next.11 → 3.0.0-next.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/cli.js +8 -8
- package/src/constants.js +1 -1
- package/src/core/config/options.js +43 -35
- package/src/core/env.js +25 -11
- package/src/core/sync/sync.js +11 -14
- package/src/core/sync/utils.js +21 -1
- package/src/core/sync/{write_non_ambient.js → write_app_types.js} +23 -21
- package/src/core/sync/write_client_manifest.js +4 -12
- package/src/core/sync/write_env.js +6 -4
- package/src/core/sync/write_server.js +10 -15
- package/src/core/sync/write_tsconfig/index.js +245 -0
- package/src/core/sync/write_tsconfig/utils.js +162 -0
- package/src/core/sync/write_types/index.js +80 -88
- package/src/exports/internal/server/index.js +3 -1
- package/src/exports/public.d.ts +28 -51
- package/src/exports/vite/dev/index.js +88 -76
- package/src/exports/vite/index.js +364 -144
- package/src/exports/vite/module_ids.js +3 -1
- package/src/exports/vite/utils.js +1 -10
- package/src/runner.js +13 -0
- package/src/runtime/app/forms.js +4 -0
- package/src/runtime/app/manifest/index.js +1 -0
- package/src/runtime/app/paths/client.js +30 -30
- package/src/runtime/app/paths/internal/client.js +26 -0
- package/src/runtime/app/paths/server.js +22 -9
- package/src/runtime/app/paths/types.d.ts +11 -19
- package/src/runtime/app/server/remote/command.js +12 -7
- package/src/runtime/app/server/remote/form.js +29 -26
- package/src/runtime/app/server/remote/prerender.js +9 -2
- package/src/runtime/app/server/remote/query.js +5 -4
- package/src/runtime/app/server/remote/shared.js +48 -30
- package/src/runtime/app/service-worker/index.js +24 -0
- package/src/runtime/app/state/index.js +1 -1
- package/src/runtime/client/client.js +46 -9
- package/src/runtime/client/remote-functions/form.svelte.js +43 -51
- package/src/runtime/client/remote-functions/query/index.js +2 -2
- package/src/runtime/client/remote-functions/query-batch.svelte.js +2 -3
- package/src/runtime/client/remote-functions/query-live/iterator.js +5 -2
- package/src/runtime/client/remote-functions/shared.svelte.js +4 -1
- package/src/runtime/client/state.svelte.js +54 -21
- package/src/runtime/form-utils.js +89 -54
- package/src/runtime/server/cookie.js +1 -1
- package/src/runtime/server/data/index.js +31 -28
- package/src/runtime/server/errors.js +1 -1
- package/src/runtime/server/page/actions.js +3 -3
- package/src/runtime/server/page/render.js +19 -28
- package/src/runtime/server/remote-functions.js +66 -35
- package/src/runtime/server/respond.js +56 -14
- package/src/runtime/server/utils.js +10 -0
- package/src/types/ambient-private.d.ts +8 -0
- package/src/types/ambient.d.ts +22 -27
- package/src/types/global-private.d.ts +12 -0
- package/src/types/internal.d.ts +13 -3
- package/src/utils/url.js +12 -0
- package/src/version.js +1 -1
- package/types/index.d.ts +80 -98
- package/types/index.d.ts.map +4 -1
- package/src/core/sync/write_ambient.js +0 -18
- package/src/core/sync/write_tsconfig.js +0 -258
- /package/src/core/sync/{write_tsconfig_test → write_tsconfig/test-app}/package.json +0 -0
|
@@ -7,11 +7,13 @@ import fs from 'node:fs';
|
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
import process from 'node:process';
|
|
9
9
|
import { styleText } from 'node:util';
|
|
10
|
+
import MagicString from 'magic-string';
|
|
10
11
|
import { loadEnv } from 'vite';
|
|
11
12
|
import { exactRegex, prefixRegex } from 'rolldown/filter';
|
|
12
13
|
|
|
13
14
|
import { copy, mkdirp, read, resolve_entry, rimraf } from '../../utils/filesystem.js';
|
|
14
15
|
import { posixify } from '../../utils/os.js';
|
|
16
|
+
import { to_fs } from '../../utils/vite.js';
|
|
15
17
|
import {
|
|
16
18
|
create_sveltekit_env,
|
|
17
19
|
create_sveltekit_env_public,
|
|
@@ -22,13 +24,12 @@ import {
|
|
|
22
24
|
create_exported_declarations
|
|
23
25
|
} from '../../core/env.js';
|
|
24
26
|
import * as sync from '../../core/sync/sync.js';
|
|
25
|
-
import { create_assets } from '../../core/sync/create_manifest_data/index.js';
|
|
26
27
|
import { load_and_validate_params } from '../../utils/params.js';
|
|
27
28
|
import { runtime_directory, logger } from '../../core/utils.js';
|
|
28
29
|
import { generate_manifest } from '../../core/generate_manifest/index.js';
|
|
29
30
|
import { build_server_nodes } from './build/build_server.js';
|
|
30
31
|
import { find_deps, resolve_symlinks } from './build/utils.js';
|
|
31
|
-
import { dev } from './dev/index.js';
|
|
32
|
+
import { dev, invalidate_module } from './dev/index.js';
|
|
32
33
|
import { preview } from './preview/index.js';
|
|
33
34
|
import {
|
|
34
35
|
error_for_missing_config,
|
|
@@ -36,8 +37,7 @@ import {
|
|
|
36
37
|
normalize_id,
|
|
37
38
|
remote_module_pattern,
|
|
38
39
|
server_only_directory_pattern,
|
|
39
|
-
server_only_module_pattern
|
|
40
|
-
strip_virtual_prefix
|
|
40
|
+
server_only_module_pattern
|
|
41
41
|
} from './utils.js';
|
|
42
42
|
import { stackless } from '../../utils/error.js';
|
|
43
43
|
import { write_client_manifest } from '../../core/sync/write_client_manifest.js';
|
|
@@ -50,10 +50,10 @@ import { get_import_aliases, get_hash_import_keys } from '../../utils/imports.js
|
|
|
50
50
|
import {
|
|
51
51
|
app_env_private,
|
|
52
52
|
app_server,
|
|
53
|
-
service_worker,
|
|
54
53
|
sveltekit_env,
|
|
55
54
|
sveltekit_env_private,
|
|
56
55
|
sveltekit_env_service_worker,
|
|
56
|
+
sveltekit_manifest_data,
|
|
57
57
|
sveltekit_env_public_client,
|
|
58
58
|
sveltekit_env_public_server
|
|
59
59
|
} from './module_ids.js';
|
|
@@ -62,6 +62,7 @@ import { compact } from '../../utils/array.js';
|
|
|
62
62
|
import { should_ignore, has_children } from './static_analysis/utils.js';
|
|
63
63
|
import { process_config, split_config, validate_config } from '../../core/config/index.js';
|
|
64
64
|
import { treeshake_prerendered_remotes } from './build/remote.js';
|
|
65
|
+
import { get_runner } from '../../runner.js';
|
|
65
66
|
|
|
66
67
|
/**
|
|
67
68
|
* The posix-ified root of the project based on the Vite configuration.
|
|
@@ -100,8 +101,7 @@ const enforced_config = {
|
|
|
100
101
|
resolve: {
|
|
101
102
|
alias: {
|
|
102
103
|
$app: true,
|
|
103
|
-
$env: true
|
|
104
|
-
'$service-worker': true
|
|
104
|
+
$env: true
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
};
|
|
@@ -301,9 +301,6 @@ function kit({ svelte_config }) {
|
|
|
301
301
|
|
|
302
302
|
/** @type {string | null} */
|
|
303
303
|
let service_worker_entry_file;
|
|
304
|
-
/** @type {import('node:path').ParsedPath} */
|
|
305
|
-
let parsed_service_worker;
|
|
306
|
-
|
|
307
304
|
/** @type {string} */
|
|
308
305
|
let normalized_cwd;
|
|
309
306
|
/** @type {Array<{ alias: string, path: string }>} */
|
|
@@ -472,27 +469,33 @@ function kit({ svelte_config }) {
|
|
|
472
469
|
}
|
|
473
470
|
};
|
|
474
471
|
|
|
475
|
-
//
|
|
472
|
+
// externalize .remote.js files to stop dependency tracing during prebundling
|
|
476
473
|
if (kit.experimental.remoteFunctions) {
|
|
477
474
|
// @ts-expect-error optimizeDeps is already set above
|
|
478
475
|
new_config.optimizeDeps.rolldownOptions ??= {};
|
|
479
476
|
// @ts-expect-error
|
|
480
477
|
new_config.optimizeDeps.rolldownOptions.plugins ??= [];
|
|
481
478
|
// @ts-expect-error
|
|
482
|
-
new_config.optimizeDeps.rolldownOptions.plugins.push(
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
479
|
+
new_config.optimizeDeps.rolldownOptions.plugins.push(
|
|
480
|
+
/** @type {Rolldown.Plugin} */ ({
|
|
481
|
+
name: 'vite-plugin-sveltekit-setup:optimize-remote-functions',
|
|
482
|
+
resolveId: {
|
|
483
|
+
filter: { id: remote_module_pattern },
|
|
484
|
+
async handler(id, importer) {
|
|
485
|
+
const resolved = await this.resolve(id, importer, { skipSelf: true });
|
|
486
|
+
if (!resolved) return { id, external: true };
|
|
487
|
+
// a servable /@fs url; 'absolute' stops rolldown relativizing it in the deps bundle
|
|
488
|
+
return { id: to_fs(resolved.id), external: 'absolute' };
|
|
489
|
+
}
|
|
488
490
|
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
+
})
|
|
492
|
+
);
|
|
491
493
|
}
|
|
492
494
|
|
|
493
495
|
const define = {
|
|
494
496
|
__SVELTEKIT_APP_DIR__: s(posixify(kit.appDir)),
|
|
495
497
|
__SVELTEKIT_APP_VERSION__: s(kit.version.name),
|
|
498
|
+
__SVELTEKIT_APP_VERSION_CHECKS_ENABLED__: s(kit.output.bundleStrategy !== 'inline'),
|
|
496
499
|
__SVELTEKIT_EMBEDDED__: s(kit.embedded),
|
|
497
500
|
__SVELTEKIT_FORK_PRELOADS__: s(kit.experimental.forkPreloads),
|
|
498
501
|
__SVELTEKIT_PATHS_ASSETS__: s(kit.paths.assets),
|
|
@@ -612,14 +615,10 @@ function kit({ svelte_config }) {
|
|
|
612
615
|
);
|
|
613
616
|
|
|
614
617
|
for (const id of [sveltekit_env, sveltekit_env_public_client]) {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
if (module) {
|
|
618
|
-
server.moduleGraph.invalidateModule(module);
|
|
619
|
-
}
|
|
618
|
+
invalidate_module(server, id);
|
|
620
619
|
}
|
|
621
620
|
|
|
622
|
-
server.
|
|
621
|
+
server.hot.send({ type: 'full-reload' });
|
|
623
622
|
}
|
|
624
623
|
});
|
|
625
624
|
},
|
|
@@ -630,18 +629,13 @@ function kit({ svelte_config }) {
|
|
|
630
629
|
|
|
631
630
|
resolveId: {
|
|
632
631
|
filter: {
|
|
633
|
-
id: [
|
|
632
|
+
id: [prefixRegex('__sveltekit/')]
|
|
634
633
|
},
|
|
635
634
|
handler(id) {
|
|
636
635
|
if (id === '__sveltekit/manifest') {
|
|
637
636
|
return `${out_dir}/generated/client-optimized/app.js`;
|
|
638
637
|
}
|
|
639
638
|
|
|
640
|
-
if (id === '$service-worker') {
|
|
641
|
-
// ids with :$ don't work with reverse proxies like nginx
|
|
642
|
-
return `\0virtual:${id.substring(1)}`;
|
|
643
|
-
}
|
|
644
|
-
|
|
645
639
|
if (id === '__sveltekit/remote') {
|
|
646
640
|
return `${runtime_directory}/client/remote-functions/index.js`;
|
|
647
641
|
}
|
|
@@ -653,18 +647,18 @@ function kit({ svelte_config }) {
|
|
|
653
647
|
load: {
|
|
654
648
|
filter: {
|
|
655
649
|
id: [
|
|
656
|
-
exactRegex(service_worker),
|
|
657
650
|
exactRegex(sveltekit_env),
|
|
658
651
|
exactRegex(sveltekit_env_private),
|
|
659
652
|
exactRegex(sveltekit_env_public_client),
|
|
660
653
|
exactRegex(sveltekit_env_public_server),
|
|
661
|
-
exactRegex(sveltekit_env_service_worker)
|
|
654
|
+
exactRegex(sveltekit_env_service_worker),
|
|
655
|
+
exactRegex(sveltekit_manifest_data)
|
|
662
656
|
]
|
|
663
657
|
},
|
|
664
658
|
handler(id) {
|
|
665
659
|
switch (id) {
|
|
666
|
-
case
|
|
667
|
-
return
|
|
660
|
+
case sveltekit_manifest_data:
|
|
661
|
+
return create_manifest_data_module(is_build, manifest_data);
|
|
668
662
|
|
|
669
663
|
case sveltekit_env:
|
|
670
664
|
return create_sveltekit_env(explicit_env_config, env, explicit_env_entry, !is_build);
|
|
@@ -691,11 +685,17 @@ function kit({ svelte_config }) {
|
|
|
691
685
|
? create_sveltekit_env_service_worker(
|
|
692
686
|
explicit_env_config,
|
|
693
687
|
env,
|
|
688
|
+
kit.version.name,
|
|
694
689
|
kit_global,
|
|
695
690
|
kit.paths.base,
|
|
696
691
|
kit.appDir
|
|
697
692
|
)
|
|
698
|
-
: create_sveltekit_env_service_worker_dev(
|
|
693
|
+
: create_sveltekit_env_service_worker_dev(
|
|
694
|
+
explicit_env_config,
|
|
695
|
+
env,
|
|
696
|
+
kit.version.name,
|
|
697
|
+
kit_global
|
|
698
|
+
);
|
|
699
699
|
}
|
|
700
700
|
}
|
|
701
701
|
}
|
|
@@ -718,7 +718,7 @@ function kit({ svelte_config }) {
|
|
|
718
718
|
|
|
719
719
|
applyToEnvironment(environment) {
|
|
720
720
|
// the import map is only read for client-side violations in `load`, so skip other environments
|
|
721
|
-
return environment.config.consumer === 'client'
|
|
721
|
+
return environment.config.consumer === 'client';
|
|
722
722
|
},
|
|
723
723
|
|
|
724
724
|
resolveId: {
|
|
@@ -789,6 +789,10 @@ function kit({ svelte_config }) {
|
|
|
789
789
|
if (manifest_data.hooks.client) entrypoints.add(manifest_data.hooks.client);
|
|
790
790
|
if (manifest_data.hooks.universal) entrypoints.add(manifest_data.hooks.universal);
|
|
791
791
|
|
|
792
|
+
if (service_worker_entry_file) {
|
|
793
|
+
entrypoints.add(posixify(path.relative(root, service_worker_entry_file)));
|
|
794
|
+
}
|
|
795
|
+
|
|
792
796
|
// Walk up the import graph from the server-only module, looking for a chain
|
|
793
797
|
// that leads back to a client entrypoint. We search all candidates (not just
|
|
794
798
|
// the first) because a module can be imported by both server and client code,
|
|
@@ -913,26 +917,28 @@ function kit({ svelte_config }) {
|
|
|
913
917
|
if (this.environment.config.consumer !== 'client') {
|
|
914
918
|
// we need to add an `await Promise.resolve()` because if the user imports this function
|
|
915
919
|
// on the client AND in a load function when loading the client module we will trigger
|
|
916
|
-
// an
|
|
920
|
+
// an import during dev. During a link preload, the module can be mistakenly
|
|
917
921
|
// loaded and transformed twice and the first time all its exports would be undefined
|
|
918
922
|
// triggering a dev server error. By adding a microtask we ensure that the module is fully loaded
|
|
923
|
+
const ms = new MagicString(code);
|
|
919
924
|
|
|
920
925
|
// Extra newlines to prevent syntax errors around missing semicolons or comments
|
|
921
|
-
|
|
926
|
+
ms.append(
|
|
922
927
|
'\n\n' +
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
928
|
+
dedent`
|
|
929
|
+
import * as $$_self_$$ from './${path.basename(id)}';
|
|
930
|
+
import { init_remote_functions as $$_init_$$ } from '@sveltejs/kit/internal/server';
|
|
926
931
|
|
|
927
|
-
|
|
932
|
+
${dev_server ? 'await Promise.resolve()' : ''}
|
|
928
933
|
|
|
929
|
-
|
|
934
|
+
$$_init_$$($$_self_$$, ${s(file)}, ${s(remote.hash)});
|
|
930
935
|
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
+
for (const [name, fn] of Object.entries($$_self_$$)) {
|
|
937
|
+
fn.__.id = ${s(remote.hash)} + '/' + name;
|
|
938
|
+
fn.__.name = name;
|
|
939
|
+
}
|
|
940
|
+
`
|
|
941
|
+
);
|
|
936
942
|
|
|
937
943
|
// Emit a dedicated entry chunk for this remote in SSR builds (prod only)
|
|
938
944
|
if (!dev_server) {
|
|
@@ -947,7 +953,10 @@ function kit({ svelte_config }) {
|
|
|
947
953
|
}
|
|
948
954
|
}
|
|
949
955
|
|
|
950
|
-
return
|
|
956
|
+
return {
|
|
957
|
+
code: ms.toString(),
|
|
958
|
+
map: ms.generateMap({ hires: 'boundary' })
|
|
959
|
+
};
|
|
951
960
|
}
|
|
952
961
|
|
|
953
962
|
// For the client, read the exports and create a new module that only contains fetch functions with the correct metadata
|
|
@@ -959,7 +968,7 @@ function kit({ svelte_config }) {
|
|
|
959
968
|
// being called again with `opts.ssr === true` if the module isn't
|
|
960
969
|
// already loaded) so we can determine what it exports
|
|
961
970
|
if (dev_server) {
|
|
962
|
-
const module = await dev_server.
|
|
971
|
+
const module = await get_runner(dev_server).import(id);
|
|
963
972
|
|
|
964
973
|
for (const [name, value] of Object.entries(module)) {
|
|
965
974
|
const type = value?.__?.type;
|
|
@@ -997,7 +1006,8 @@ function kit({ svelte_config }) {
|
|
|
997
1006
|
}
|
|
998
1007
|
|
|
999
1008
|
return {
|
|
1000
|
-
code: result
|
|
1009
|
+
code: result,
|
|
1010
|
+
map: null
|
|
1001
1011
|
};
|
|
1002
1012
|
}
|
|
1003
1013
|
}
|
|
@@ -1033,7 +1043,7 @@ function kit({ svelte_config }) {
|
|
|
1033
1043
|
/** @type {Set<string>} */
|
|
1034
1044
|
let build_files;
|
|
1035
1045
|
/** @type {string} */
|
|
1036
|
-
let
|
|
1046
|
+
let manifest_data_code;
|
|
1037
1047
|
|
|
1038
1048
|
/**
|
|
1039
1049
|
* Creates the service worker virtual modules
|
|
@@ -1044,7 +1054,6 @@ function kit({ svelte_config }) {
|
|
|
1044
1054
|
|
|
1045
1055
|
config(config) {
|
|
1046
1056
|
service_worker_entry_file = resolve_entry(kit.files.serviceWorker);
|
|
1047
|
-
parsed_service_worker = path.parse(kit.files.serviceWorker);
|
|
1048
1057
|
|
|
1049
1058
|
if (!service_worker_entry_file) return;
|
|
1050
1059
|
|
|
@@ -1099,46 +1108,23 @@ function kit({ svelte_config }) {
|
|
|
1099
1108
|
return environment.name === 'serviceWorker';
|
|
1100
1109
|
},
|
|
1101
1110
|
|
|
1102
|
-
resolveId
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
const parsed_importer = path.parse(importer);
|
|
1108
|
-
|
|
1109
|
-
const importer_is_service_worker =
|
|
1110
|
-
parsed_importer.dir === parsed_service_worker.dir &&
|
|
1111
|
-
parsed_importer.name === parsed_service_worker.name;
|
|
1112
|
-
|
|
1113
|
-
if (
|
|
1114
|
-
importer_is_service_worker &&
|
|
1115
|
-
id !== '$service-worker' &&
|
|
1116
|
-
id !== 'virtual:$app/env/public' &&
|
|
1117
|
-
id !== '__sveltekit/env/service-worker'
|
|
1118
|
-
) {
|
|
1119
|
-
throw new Error(
|
|
1120
|
-
`Cannot import ${normalize_id(
|
|
1121
|
-
id,
|
|
1122
|
-
normalized_aliases,
|
|
1123
|
-
normalized_cwd
|
|
1124
|
-
)} into service-worker code. Only the modules $service-worker and $app/env/public are available in service workers.`
|
|
1125
|
-
);
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
if (id.startsWith('$app/') || id === '$service-worker') {
|
|
1130
|
-
// ids with :$ don't work with reverse proxies like nginx
|
|
1131
|
-
return `\0virtual:${id.substring(1)}`;
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
if (id.startsWith('__sveltekit')) {
|
|
1111
|
+
resolveId: {
|
|
1112
|
+
filter: {
|
|
1113
|
+
id: [prefixRegex('__sveltekit/')]
|
|
1114
|
+
},
|
|
1115
|
+
handler(id) {
|
|
1135
1116
|
return `\0virtual:${id}`;
|
|
1136
1117
|
}
|
|
1137
1118
|
},
|
|
1138
1119
|
|
|
1139
1120
|
load: {
|
|
1140
1121
|
filter: {
|
|
1141
|
-
id: [
|
|
1122
|
+
id: [
|
|
1123
|
+
exactRegex('\0virtual:app/manifest'),
|
|
1124
|
+
exactRegex(sveltekit_manifest_data),
|
|
1125
|
+
exactRegex(sveltekit_env_service_worker),
|
|
1126
|
+
exactRegex(sveltekit_env_public_client)
|
|
1127
|
+
]
|
|
1142
1128
|
},
|
|
1143
1129
|
handler(id) {
|
|
1144
1130
|
if (!build_files) {
|
|
@@ -1161,36 +1147,33 @@ function kit({ svelte_config }) {
|
|
|
1161
1147
|
}
|
|
1162
1148
|
}
|
|
1163
1149
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
const base = "location.pathname.split('/').slice(0, -1).join('/')";
|
|
1167
|
-
|
|
1168
|
-
service_worker_code = dedent`
|
|
1169
|
-
export const base = /*@__PURE__*/ ${base};
|
|
1170
|
-
|
|
1171
|
-
export const build = [
|
|
1150
|
+
manifest_data_code = dedent`
|
|
1151
|
+
export const immutable = [
|
|
1172
1152
|
${Array.from(build_files)
|
|
1173
|
-
.map((file) =>
|
|
1153
|
+
.map((file) => s({ path: file }))
|
|
1174
1154
|
.join(',\n')}
|
|
1175
1155
|
];
|
|
1176
1156
|
|
|
1177
|
-
export const
|
|
1178
|
-
${manifest_data.assets
|
|
1179
|
-
.filter((asset) => kit.serviceWorker.files(asset.file))
|
|
1180
|
-
.map((asset) => `base + ${s(`/${asset.file}`)}`)
|
|
1181
|
-
.join(',\n')}
|
|
1157
|
+
export const assets = [
|
|
1158
|
+
${manifest_data.assets.map((asset) => s({ path: asset.file })).join(',\n')}
|
|
1182
1159
|
];
|
|
1183
1160
|
|
|
1184
1161
|
export const prerendered = [
|
|
1185
|
-
${prerendered.paths.map((path) =>
|
|
1162
|
+
${prerendered.paths.map((path) => s({ path: path.replace(kit.paths.base, '').slice(1) })).join(',\n')}
|
|
1186
1163
|
];
|
|
1187
1164
|
|
|
1188
|
-
export const
|
|
1165
|
+
export const routes = [
|
|
1166
|
+
${manifest_data.routes.map((route) => s({ id: route.id })).join(',\n')}
|
|
1167
|
+
];
|
|
1189
1168
|
`;
|
|
1190
1169
|
}
|
|
1191
1170
|
|
|
1192
|
-
if (id ===
|
|
1193
|
-
return
|
|
1171
|
+
if (id === '\0virtual:app/manifest') {
|
|
1172
|
+
return `export { immutable, assets, prerendered, routes } from '__sveltekit/manifest-data';`;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
if (id === sveltekit_manifest_data) {
|
|
1176
|
+
return manifest_data_code;
|
|
1194
1177
|
}
|
|
1195
1178
|
|
|
1196
1179
|
if (id === sveltekit_env_service_worker) {
|
|
@@ -1198,11 +1181,17 @@ function kit({ svelte_config }) {
|
|
|
1198
1181
|
? create_sveltekit_env_service_worker(
|
|
1199
1182
|
explicit_env_config,
|
|
1200
1183
|
env,
|
|
1184
|
+
kit.version.name,
|
|
1201
1185
|
kit_global,
|
|
1202
1186
|
kit.paths.base,
|
|
1203
1187
|
kit.appDir
|
|
1204
1188
|
)
|
|
1205
|
-
: create_sveltekit_env_service_worker_dev(
|
|
1189
|
+
: create_sveltekit_env_service_worker_dev(
|
|
1190
|
+
explicit_env_config,
|
|
1191
|
+
env,
|
|
1192
|
+
kit.version.name,
|
|
1193
|
+
kit_global
|
|
1194
|
+
);
|
|
1206
1195
|
}
|
|
1207
1196
|
|
|
1208
1197
|
if (id === sveltekit_env_public_client) {
|
|
@@ -1212,16 +1201,31 @@ function kit({ svelte_config }) {
|
|
|
1212
1201
|
`const env = ${kit_global}.env;`
|
|
1213
1202
|
);
|
|
1214
1203
|
}
|
|
1204
|
+
}
|
|
1205
|
+
},
|
|
1206
|
+
|
|
1207
|
+
generateBundle(_, bundle) {
|
|
1208
|
+
const invalid_modules = new Set();
|
|
1209
|
+
const modules = new Map([
|
|
1210
|
+
[`${runtime_directory}/app/forms.js`, '$app/forms'],
|
|
1211
|
+
[`${runtime_directory}/app/navigation.js`, '$app/navigation'],
|
|
1212
|
+
[`${runtime_directory}/app/state/index.js`, '$app/state']
|
|
1213
|
+
]);
|
|
1214
|
+
|
|
1215
|
+
for (const output of Object.values(bundle)) {
|
|
1216
|
+
if (output.type !== 'chunk') continue;
|
|
1217
|
+
|
|
1218
|
+
for (const id of output.moduleIds) {
|
|
1219
|
+
const module = modules.get(id);
|
|
1220
|
+
if (module) invalid_modules.add(module);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1215
1223
|
|
|
1216
|
-
|
|
1217
|
-
const sw_normalized_aliases = get_import_aliases(
|
|
1218
|
-
vite_config.root,
|
|
1219
|
-
vite.normalizePath.bind(vite)
|
|
1220
|
-
);
|
|
1221
|
-
const relative = normalize_id(id, sw_normalized_aliases, sw_normalized_cwd);
|
|
1222
|
-
const stripped = strip_virtual_prefix(relative);
|
|
1224
|
+
if (invalid_modules.size > 0) {
|
|
1223
1225
|
throw new Error(
|
|
1224
|
-
`Cannot import ${
|
|
1226
|
+
`Cannot import ${Array.from(modules.values())
|
|
1227
|
+
.filter((module) => invalid_modules.has(module))
|
|
1228
|
+
.join(', ')} into service-worker code.`
|
|
1225
1229
|
);
|
|
1226
1230
|
}
|
|
1227
1231
|
}
|
|
@@ -1233,17 +1237,19 @@ function kit({ svelte_config }) {
|
|
|
1233
1237
|
applyToEnvironment(environment) {
|
|
1234
1238
|
return !!service_worker_entry_file && environment.config.consumer === 'client';
|
|
1235
1239
|
},
|
|
1236
|
-
transform
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1240
|
+
transform: {
|
|
1241
|
+
handler(code, id) {
|
|
1242
|
+
if (id !== service_worker_entry_file) return;
|
|
1243
|
+
|
|
1244
|
+
// prepend the service worker with an import that configures
|
|
1245
|
+
// `env`, in case `$app/env/public` is imported. In production
|
|
1246
|
+
// this is required: dynamic public env vars aren't known at
|
|
1247
|
+
// build time, so `env.js` is loaded at runtime. In dev, the
|
|
1248
|
+
// imported module just inlines the current values instead.
|
|
1249
|
+
return {
|
|
1250
|
+
code: `import '__sveltekit/env/service-worker';\n${code}`
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1247
1253
|
}
|
|
1248
1254
|
};
|
|
1249
1255
|
|
|
@@ -1427,9 +1433,26 @@ function kit({ svelte_config }) {
|
|
|
1427
1433
|
output: {
|
|
1428
1434
|
format: inline ? 'iife' : 'esm',
|
|
1429
1435
|
entryFileNames: `${app_immutable}/[name].[hash].js`,
|
|
1430
|
-
chunkFileNames:
|
|
1436
|
+
chunkFileNames: (/** @type {Rolldown.PreRenderedChunk} */ chunk_info) => {
|
|
1437
|
+
// The manifest data chunk gets a fixed (non-hashed) filename so
|
|
1438
|
+
// that importers' content hashes are stable regardless of the
|
|
1439
|
+
// manifest content — this breaks the content-hash feedback loop
|
|
1440
|
+
if (chunk_info.name === 'sveltekit-manifest') {
|
|
1441
|
+
return `${kit.appDir}/manifest.js`;
|
|
1442
|
+
}
|
|
1443
|
+
return `${app_immutable}/chunks/[hash].js`;
|
|
1444
|
+
},
|
|
1431
1445
|
codeSplitting:
|
|
1432
|
-
svelte_config.kit.output.bundleStrategy === 'split'
|
|
1446
|
+
svelte_config.kit.output.bundleStrategy === 'split'
|
|
1447
|
+
? {
|
|
1448
|
+
groups: [
|
|
1449
|
+
{
|
|
1450
|
+
name: 'sveltekit-manifest',
|
|
1451
|
+
test: sveltekit_manifest_data
|
|
1452
|
+
}
|
|
1453
|
+
]
|
|
1454
|
+
}
|
|
1455
|
+
: false
|
|
1433
1456
|
},
|
|
1434
1457
|
// This silences Rolldown warnings about not supporting `import.meta`
|
|
1435
1458
|
// for the `iife` output format. We don't care because it's
|
|
@@ -1508,7 +1531,18 @@ function kit({ svelte_config }) {
|
|
|
1508
1531
|
* @see https://vitejs.dev/guide/api-plugin.html#configureserver
|
|
1509
1532
|
*/
|
|
1510
1533
|
async configureServer(server) {
|
|
1511
|
-
return await dev(
|
|
1534
|
+
return await dev(
|
|
1535
|
+
server,
|
|
1536
|
+
vite_config,
|
|
1537
|
+
svelte_config,
|
|
1538
|
+
() => remotes,
|
|
1539
|
+
root,
|
|
1540
|
+
(data) => {
|
|
1541
|
+
manifest_data = data;
|
|
1542
|
+
// Invalidate the manifest data module so it reloads with new routes/files
|
|
1543
|
+
invalidate_module(server, sveltekit_manifest_data);
|
|
1544
|
+
}
|
|
1545
|
+
);
|
|
1512
1546
|
},
|
|
1513
1547
|
|
|
1514
1548
|
/**
|
|
@@ -1564,6 +1598,15 @@ function kit({ svelte_config }) {
|
|
|
1564
1598
|
await builder.build(builder.environments.ssr)
|
|
1565
1599
|
);
|
|
1566
1600
|
|
|
1601
|
+
// Replace manifest placeholders in SSR output. `assets` and `routes`
|
|
1602
|
+
// are known from `manifest_data`. `immutable` and `prerendered` are not
|
|
1603
|
+
// known yet — they get sentinel strings that are replaced after
|
|
1604
|
+
// the client build and after prerendering respectively.
|
|
1605
|
+
replace_manifest_placeholder_variables(server_chunks, `${out}/server`, {
|
|
1606
|
+
assets: manifest_data.assets.map((asset) => ({ path: asset.file })),
|
|
1607
|
+
routes: manifest_data.routes.map((route) => ({ id: route.id }))
|
|
1608
|
+
});
|
|
1609
|
+
|
|
1567
1610
|
const verbose = builder.config.logLevel === 'info';
|
|
1568
1611
|
const log = logger({ verbose });
|
|
1569
1612
|
|
|
@@ -1688,6 +1731,42 @@ function kit({ svelte_config }) {
|
|
|
1688
1731
|
read(`${out}/client/.vite/manifest.json`)
|
|
1689
1732
|
));
|
|
1690
1733
|
|
|
1734
|
+
// Replace manifest placeholders in client output. `immutable` is
|
|
1735
|
+
// computed from the Vite client manifest, `assets` and `routes`
|
|
1736
|
+
// from `manifest_data`. `prerendered` is left as a placeholder
|
|
1737
|
+
// for now — it's replaced after prerendering completes.
|
|
1738
|
+
/** @type {Set<string>} */
|
|
1739
|
+
const immutable = new Set();
|
|
1740
|
+
|
|
1741
|
+
/** @param {string} file */
|
|
1742
|
+
const add_immutable = (file) => {
|
|
1743
|
+
if (
|
|
1744
|
+
file.startsWith(`${kit.appDir}/immutable`) &&
|
|
1745
|
+
fs.existsSync(`${out}/client/${file}`)
|
|
1746
|
+
) {
|
|
1747
|
+
immutable.add(file);
|
|
1748
|
+
}
|
|
1749
|
+
};
|
|
1750
|
+
|
|
1751
|
+
for (const key in vite_manifest) {
|
|
1752
|
+
const { file, css = [], assets = [] } = vite_manifest[key];
|
|
1753
|
+
add_immutable(file);
|
|
1754
|
+
css.forEach(add_immutable);
|
|
1755
|
+
assets.forEach(add_immutable);
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1758
|
+
replace_manifest_placeholder_variables(client_chunks, `${out}/client`, {
|
|
1759
|
+
immutable: Array.from(immutable).map((file) => ({ path: file })),
|
|
1760
|
+
assets: manifest_data.assets.map((asset) => ({ path: asset.file })),
|
|
1761
|
+
routes: manifest_data.routes.map((route) => ({ id: route.id }))
|
|
1762
|
+
});
|
|
1763
|
+
|
|
1764
|
+
// Now that the client build is done, replace the `build` sentinel
|
|
1765
|
+
// in the SSR output with the real build files
|
|
1766
|
+
replace_manifest_placeholder_strings(`${out}/server`, {
|
|
1767
|
+
immutable: Array.from(immutable).map((file) => ({ path: file }))
|
|
1768
|
+
});
|
|
1769
|
+
|
|
1691
1770
|
/**
|
|
1692
1771
|
* @param {string} entry
|
|
1693
1772
|
* @param {boolean} [add_dynamic_css]
|
|
@@ -1860,6 +1939,25 @@ function kit({ svelte_config }) {
|
|
|
1860
1939
|
|
|
1861
1940
|
prerendered = prerender_results.prerendered;
|
|
1862
1941
|
|
|
1942
|
+
// Replace the `prerendered` sentinel in both SSR and client output
|
|
1943
|
+
// with the real prerendered paths. The other sentinels (`build`)
|
|
1944
|
+
// were already replaced after the client build.
|
|
1945
|
+
const prerendered_paths = prerendered.paths.map((p) => {
|
|
1946
|
+
return { path: p.replace(kit.paths.base, '').slice(1) };
|
|
1947
|
+
});
|
|
1948
|
+
|
|
1949
|
+
replace_manifest_placeholder_strings(`${out}/server`, { prerendered: prerendered_paths });
|
|
1950
|
+
replace_manifest_placeholder_strings(`${out}/client`, { prerendered: prerendered_paths });
|
|
1951
|
+
|
|
1952
|
+
// For `inline` strategy, the entry file was deleted and read into
|
|
1953
|
+
// `build_data.client.inline.script` — replace the sentinel there too
|
|
1954
|
+
if (build_data.client?.inline?.script) {
|
|
1955
|
+
build_data.client.inline.script = build_data.client.inline.script.replaceAll(
|
|
1956
|
+
'"__sveltekit_manifest_prerendered__"',
|
|
1957
|
+
JSON.stringify(prerendered_paths)
|
|
1958
|
+
);
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1863
1961
|
await treeshake_prerendered_remotes(
|
|
1864
1962
|
vite,
|
|
1865
1963
|
out,
|
|
@@ -2020,21 +2118,143 @@ function find_overridden_config(config, resolved_config, enforced_config, path,
|
|
|
2020
2118
|
}
|
|
2021
2119
|
|
|
2022
2120
|
/**
|
|
2023
|
-
*
|
|
2121
|
+
* Creates the `$app/manifest` data module. During development, real values
|
|
2122
|
+
* are emitted for `assets` and `routes` (the only data known at that point).
|
|
2123
|
+
*
|
|
2124
|
+
* During build, bare identifier placeholders (fake globals) are emitted.
|
|
2125
|
+
* The bundler leaves these as unresolved global references in the output,
|
|
2126
|
+
* which are then replaced with real values by scanning the output chunks
|
|
2127
|
+
* after each build completes. This avoids the content-hash feedback loop:
|
|
2128
|
+
* the manifest data lives in its own chunk with a fixed filename, so
|
|
2129
|
+
* importers' hashes are stable regardless of the manifest content.
|
|
2130
|
+
*
|
|
2131
|
+
* @param {boolean} is_build
|
|
2132
|
+
* @param {ManifestData | undefined} manifest_data
|
|
2133
|
+
* @returns {string}
|
|
2024
2134
|
*/
|
|
2025
|
-
const
|
|
2026
|
-
if (
|
|
2027
|
-
|
|
2135
|
+
const create_manifest_data_module = (is_build, manifest_data) => {
|
|
2136
|
+
if (is_build) {
|
|
2137
|
+
// Bare identifiers (fake globals) — the bundler leaves these as
|
|
2138
|
+
// unresolved global references in the output. They are replaced
|
|
2139
|
+
// with real values by `replace_manifest_placeholder_variables`
|
|
2140
|
+
// after each build completes.
|
|
2141
|
+
return dedent`
|
|
2142
|
+
export const immutable = __SVELTEKIT_MANIFEST_IMMUTABLE__;
|
|
2143
|
+
export const assets = __SVELTEKIT_MANIFEST_ASSETS__;
|
|
2144
|
+
export const prerendered = __SVELTEKIT_MANIFEST_PRERENDERED__;
|
|
2145
|
+
export const routes = __SVELTEKIT_MANIFEST_ROUTES__;
|
|
2146
|
+
`;
|
|
2028
2147
|
}
|
|
2029
2148
|
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2149
|
+
// In dev, `manifest_data` may not be set yet on the very first load,
|
|
2150
|
+
// but `configureServer` (which calls `sync.create`) runs before any
|
|
2151
|
+
// module is served, so it will be set by the time this is called.
|
|
2152
|
+
const routes = manifest_data?.routes.map((route) => s({ id: route.id })).join(',\n') ?? '';
|
|
2153
|
+
const assets = manifest_data?.assets.map((asset) => s({ path: asset.file })).join(',\n') ?? '';
|
|
2154
|
+
|
|
2155
|
+
return dedent`
|
|
2156
|
+
// empty during dev
|
|
2157
|
+
export const immutable = [];
|
|
2158
|
+
export const prerendered = [];
|
|
2159
|
+
|
|
2160
|
+
export const assets = [
|
|
2161
|
+
${assets}
|
|
2162
|
+
];
|
|
2163
|
+
|
|
2164
|
+
export const routes = [
|
|
2165
|
+
${routes}
|
|
2166
|
+
];
|
|
2167
|
+
`;
|
|
2168
|
+
};
|
|
2169
|
+
|
|
2170
|
+
/**
|
|
2171
|
+
* Replaces manifest data placeholder identifiers in output chunks with real
|
|
2172
|
+
* values, or strings that are valid JS (so thecode doesn't crash during prerendering)
|
|
2173
|
+
* but findable on disk for later replacement by `replace_manifest_placeholder_strings`.
|
|
2174
|
+
*
|
|
2175
|
+
* @param {Rolldown.RolldownOutput['output']} chunks
|
|
2176
|
+
* @param {string} output_dir
|
|
2177
|
+
* @param {{
|
|
2178
|
+
* immutable?: Array<{ path: string }>;
|
|
2179
|
+
* assets?: Array<{ path: string }>;
|
|
2180
|
+
* prerendered?: Array<{ path: string }>;
|
|
2181
|
+
* routes?: Array<{ id: string }>;
|
|
2182
|
+
* }} values
|
|
2183
|
+
*/
|
|
2184
|
+
const replace_manifest_placeholder_variables = (chunks, output_dir, values) => {
|
|
2185
|
+
/** @type {Record<string, string>} */
|
|
2186
|
+
const replacements = {
|
|
2187
|
+
__SVELTEKIT_MANIFEST_IMMUTABLE__: JSON.stringify(
|
|
2188
|
+
values.immutable ?? '__sveltekit_manifest_build__'
|
|
2189
|
+
),
|
|
2190
|
+
__SVELTEKIT_MANIFEST_ASSETS__: JSON.stringify(values.assets ?? '__sveltekit_manifest_files__'),
|
|
2191
|
+
__SVELTEKIT_MANIFEST_PRERENDERED__: JSON.stringify(
|
|
2192
|
+
values.prerendered ?? '__sveltekit_manifest_prerendered__'
|
|
2193
|
+
),
|
|
2194
|
+
__SVELTEKIT_MANIFEST_ROUTES__: JSON.stringify(values.routes ?? '__sveltekit_manifest_routes__')
|
|
2195
|
+
};
|
|
2196
|
+
|
|
2197
|
+
for (const chunk of chunks) {
|
|
2198
|
+
if (chunk.type !== 'chunk') continue;
|
|
2199
|
+
if (!chunk.code.includes('__SVELTEKIT_MANIFEST_')) continue;
|
|
2200
|
+
|
|
2201
|
+
let code = chunk.code;
|
|
2202
|
+
|
|
2203
|
+
for (const [identifier, replacement] of Object.entries(replacements)) {
|
|
2204
|
+
code = code.replaceAll(identifier, replacement);
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
const file_path = `${output_dir}/${chunk.fileName}`;
|
|
2208
|
+
fs.writeFileSync(file_path, code);
|
|
2209
|
+
}
|
|
2210
|
+
};
|
|
2211
|
+
|
|
2212
|
+
/**
|
|
2213
|
+
* Replaces manifest sentinel strings in files on disk with real values.
|
|
2214
|
+
* This is used for values that weren't known when the first replacement
|
|
2215
|
+
* pass ran (e.g. `build` wasn't known until after the client build,
|
|
2216
|
+
* `prerendered` wasn't known until after prerendering).
|
|
2217
|
+
*
|
|
2218
|
+
* @param {string} dir Directory to scan for .js files
|
|
2219
|
+
* @param {{
|
|
2220
|
+
* immutable?: Array<{ path: string }>;
|
|
2221
|
+
* prerendered?: Array<{ path: string }>;
|
|
2222
|
+
* }} values
|
|
2223
|
+
*/
|
|
2224
|
+
const replace_manifest_placeholder_strings = (dir, values) => {
|
|
2225
|
+
/** @type {Record<string, string>} */
|
|
2226
|
+
const replacements = {};
|
|
2227
|
+
|
|
2228
|
+
if (values.immutable !== undefined) {
|
|
2229
|
+
replacements['__sveltekit_manifest_build__'] = JSON.stringify(values.immutable);
|
|
2230
|
+
}
|
|
2231
|
+
if (values.prerendered !== undefined) {
|
|
2232
|
+
replacements['__sveltekit_manifest_prerendered__'] = JSON.stringify(values.prerendered);
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2235
|
+
for (const file of fs.readdirSync(dir)) {
|
|
2236
|
+
const file_path = `${dir}/${file}`;
|
|
2237
|
+
const stat = fs.statSync(file_path);
|
|
2238
|
+
|
|
2239
|
+
if (stat.isDirectory()) {
|
|
2240
|
+
replace_manifest_placeholder_strings(file_path, values);
|
|
2241
|
+
continue;
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
if (!file.endsWith('.js')) continue;
|
|
2245
|
+
|
|
2246
|
+
let code = read(file_path);
|
|
2247
|
+
let changed = false;
|
|
2248
|
+
|
|
2249
|
+
for (const [sentinel, replacement] of Object.entries(replacements)) {
|
|
2250
|
+
if (code.includes(sentinel)) {
|
|
2251
|
+
code = code.replaceAll(`"${sentinel}"`, replacement);
|
|
2252
|
+
changed = true;
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
if (changed) {
|
|
2257
|
+
fs.writeFileSync(file_path, code);
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
};
|