@sveltejs/kit 3.0.0-next.11 → 3.0.0-next.13
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 +10 -10
- 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/postbuild/prerender.js +3 -3
- 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} +24 -23
- 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 +257 -0
- package/src/core/sync/write_tsconfig/utils.js +162 -0
- package/src/core/sync/write_types/index.js +80 -88
- package/src/exports/index.js +23 -12
- package/src/exports/internal/server/index.js +3 -1
- package/src/exports/internal/shared.js +4 -12
- package/src/exports/public.d.ts +87 -62
- package/src/exports/vite/build/remote.js +10 -12
- package/src/exports/vite/dev/index.js +113 -88
- package/src/exports/vite/index.js +452 -237
- 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 +37 -26
- package/src/runtime/app/server/remote/prerender.js +22 -11
- package/src/runtime/app/server/remote/query.js +5 -4
- package/src/runtime/app/server/remote/requested.js +4 -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/client.js +3 -0
- package/src/runtime/app/state/index.js +3 -3
- package/src/runtime/app/state/server.js +3 -0
- package/src/runtime/client/client.js +627 -311
- package/src/runtime/client/constants.js +2 -6
- package/src/runtime/client/fetcher.js +27 -17
- package/src/runtime/client/remote-functions/form.svelte.js +82 -58
- package/src/runtime/client/remote-functions/prerender.svelte.js +1 -1
- package/src/runtime/client/remote-functions/query/index.js +2 -2
- package/src/runtime/client/remote-functions/query/instance.svelte.js +2 -2
- package/src/runtime/client/remote-functions/query-batch.svelte.js +3 -4
- package/src/runtime/client/remote-functions/query-live/instance.svelte.js +2 -2
- package/src/runtime/client/remote-functions/query-live/iterator.js +15 -10
- package/src/runtime/client/remote-functions/shared.svelte.js +15 -11
- package/src/runtime/client/state.svelte.js +54 -33
- package/src/runtime/client/types.d.ts +1 -2
- package/src/runtime/client/utils.js +21 -14
- package/src/runtime/components/root.svelte +4 -14
- package/src/runtime/form-utils.js +89 -54
- package/src/runtime/props.svelte.js +71 -0
- 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/fetch.js +4 -6
- package/src/runtime/server/page/actions.js +3 -3
- package/src/runtime/server/page/csp.js +86 -103
- package/src/runtime/server/page/index.js +1 -2
- package/src/runtime/server/page/load_data.js +15 -5
- package/src/runtime/server/page/render.js +46 -52
- package/src/runtime/server/page/respond_with_error.js +1 -3
- package/src/runtime/server/remote-functions.js +66 -35
- package/src/runtime/server/respond.js +56 -16
- package/src/runtime/server/utils.js +10 -0
- package/src/types/ambient-private.d.ts +9 -1
- package/src/types/ambient.d.ts +23 -28
- package/src/types/global-private.d.ts +12 -0
- package/src/types/internal.d.ts +15 -10
- package/src/types/private.d.ts +3 -12
- package/src/utils/url.js +12 -0
- package/src/version.js +1 -1
- package/types/index.d.ts +172 -155
- package/types/index.d.ts.map +5 -1
- package/src/core/sync/write_ambient.js +0 -18
- package/src/core/sync/write_tsconfig.js +0 -258
- package/src/runtime/types.d.ts +0 -8
- /package/src/core/sync/{write_tsconfig_test → write_tsconfig/test-app}/package.json +0 -0
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
/** @import { EnvVarConfig, KitConfig } from '@sveltejs/kit' */
|
|
2
2
|
/** @import { Options, SvelteConfig } from '@sveltejs/vite-plugin-svelte' */
|
|
3
3
|
/** @import { PreprocessorGroup } from 'svelte/compiler' */
|
|
4
|
-
/** @import { BuildData, ManifestData, Prerendered,
|
|
4
|
+
/** @import { BuildData, ManifestData, Prerendered, RemoteChunk, RemoteInternals, ServerMetadata, ValidatedConfig, ValidatedKitConfig } from 'types' */
|
|
5
5
|
/** @import { Manifest, Plugin, ResolvedConfig, Rolldown, UserConfig, ViteDevServer } from 'vite' */
|
|
6
6
|
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,13 +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
|
-
|
|
66
|
-
/**
|
|
67
|
-
* The posix-ified root of the project based on the Vite configuration.
|
|
68
|
-
* Populated after Vite plugins' `config` hooks run
|
|
69
|
-
* @type {string}
|
|
70
|
-
*/
|
|
71
|
-
let root;
|
|
65
|
+
import { get_runner } from '../../runner.js';
|
|
72
66
|
|
|
73
67
|
/** @type {import('./types.js').EnforcedConfig} */
|
|
74
68
|
const enforced_config = {
|
|
@@ -100,8 +94,7 @@ const enforced_config = {
|
|
|
100
94
|
resolve: {
|
|
101
95
|
alias: {
|
|
102
96
|
$app: true,
|
|
103
|
-
$env: true
|
|
104
|
-
'$service-worker': true
|
|
97
|
+
$env: true
|
|
105
98
|
}
|
|
106
99
|
}
|
|
107
100
|
};
|
|
@@ -123,7 +116,7 @@ const warning_preprocessor = {
|
|
|
123
116
|
const fixed = basename.replace('.svelte', '(.server).js/ts');
|
|
124
117
|
|
|
125
118
|
const message =
|
|
126
|
-
`\n${styleText(['bold', 'red'], path.relative(
|
|
119
|
+
`\n${styleText(['bold', 'red'], path.relative(process.cwd(), filename))}\n` +
|
|
127
120
|
`\`${match[1]}\` will be ignored — move it to ${fixed} instead. See https://svelte.dev/docs/kit/page-options for more information.`;
|
|
128
121
|
|
|
129
122
|
if (!warned.has(message)) {
|
|
@@ -140,7 +133,7 @@ const warning_preprocessor = {
|
|
|
140
133
|
|
|
141
134
|
if (basename.startsWith('+layout.') && !has_children(content, true)) {
|
|
142
135
|
const message =
|
|
143
|
-
`\n${styleText(['bold', 'red'], path.relative(
|
|
136
|
+
`\n${styleText(['bold', 'red'], path.relative(process.cwd(), filename))}\n` +
|
|
144
137
|
'`<slot />` or `{@render ...}` tag' +
|
|
145
138
|
' missing — inner content will not be rendered';
|
|
146
139
|
|
|
@@ -206,13 +199,7 @@ export async function sveltekit(config) {
|
|
|
206
199
|
inline_vps_config.compilerOptions = svelte_config.compilerOptions;
|
|
207
200
|
}
|
|
208
201
|
|
|
209
|
-
return [
|
|
210
|
-
plugin_root(),
|
|
211
|
-
...vite_plugin_svelte.svelte(inline_vps_config),
|
|
212
|
-
...kit({
|
|
213
|
-
svelte_config
|
|
214
|
-
})
|
|
215
|
-
];
|
|
202
|
+
return [...vite_plugin_svelte.svelte(inline_vps_config), ...kit({ svelte_config })];
|
|
216
203
|
}
|
|
217
204
|
|
|
218
205
|
/** @param {UserConfig | ResolvedConfig} vite_config */
|
|
@@ -220,39 +207,6 @@ function resolve_root(vite_config) {
|
|
|
220
207
|
return posixify(vite_config.root ? path.resolve(vite_config.root) : process.cwd());
|
|
221
208
|
}
|
|
222
209
|
|
|
223
|
-
/**
|
|
224
|
-
* @return {Plugin}
|
|
225
|
-
*/
|
|
226
|
-
function plugin_root() {
|
|
227
|
-
return {
|
|
228
|
-
name: 'vite-plugin-sveltekit-resolve-svelte-config',
|
|
229
|
-
// make sure it runs first
|
|
230
|
-
enforce: 'pre',
|
|
231
|
-
config: {
|
|
232
|
-
order: 'pre',
|
|
233
|
-
handler(config) {
|
|
234
|
-
root = resolve_root(config);
|
|
235
|
-
|
|
236
|
-
const config_file = ['svelte.config.js', 'svelte.config.ts'].find((file) =>
|
|
237
|
-
fs.existsSync(path.join(root, file))
|
|
238
|
-
);
|
|
239
|
-
if (config_file) {
|
|
240
|
-
throw new Error(
|
|
241
|
-
`${config_file} is no longer used. Please pass configuration via the \`sveltekit(...)\` plugin in your Vite config.`
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
},
|
|
246
|
-
// TODO: do we even need to set `root` based on the final Vite config?
|
|
247
|
-
configResolved: {
|
|
248
|
-
order: 'pre',
|
|
249
|
-
handler(config) {
|
|
250
|
-
root = resolve_root(config);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
|
|
256
210
|
/**
|
|
257
211
|
* Returns the SvelteKit Vite plugin. Vite executes Rolldown hooks as well as some of its own.
|
|
258
212
|
* Background reading is available at:
|
|
@@ -271,6 +225,12 @@ function kit({ svelte_config }) {
|
|
|
271
225
|
/** @type {typeof import('vite')} */
|
|
272
226
|
let vite;
|
|
273
227
|
|
|
228
|
+
/**
|
|
229
|
+
* The posix-ified root of the project based on the Vite configuration.
|
|
230
|
+
* @type {string}
|
|
231
|
+
*/
|
|
232
|
+
let root;
|
|
233
|
+
|
|
274
234
|
/** @type {ValidatedKitConfig} */
|
|
275
235
|
let kit;
|
|
276
236
|
/** @type {string} `kit.outDir` but posix-ified */
|
|
@@ -301,9 +261,6 @@ function kit({ svelte_config }) {
|
|
|
301
261
|
|
|
302
262
|
/** @type {string | null} */
|
|
303
263
|
let service_worker_entry_file;
|
|
304
|
-
/** @type {import('node:path').ParsedPath} */
|
|
305
|
-
let parsed_service_worker;
|
|
306
|
-
|
|
307
264
|
/** @type {string} */
|
|
308
265
|
let normalized_cwd;
|
|
309
266
|
/** @type {Array<{ alias: string, path: string }>} */
|
|
@@ -327,6 +284,27 @@ function kit({ svelte_config }) {
|
|
|
327
284
|
/** @type {string} name for `globalThis.__sveltekit_xxx` */
|
|
328
285
|
let kit_global;
|
|
329
286
|
|
|
287
|
+
/** @type {Plugin} */
|
|
288
|
+
const plugin_resolve_root = {
|
|
289
|
+
name: 'vite-plugin-sveltekit-resolve-root',
|
|
290
|
+
// make sure it runs first
|
|
291
|
+
enforce: 'pre',
|
|
292
|
+
config: {
|
|
293
|
+
order: 'pre',
|
|
294
|
+
handler(config) {
|
|
295
|
+
root = resolve_root(config);
|
|
296
|
+
|
|
297
|
+
for (const file of ['svelte.config.js', 'svelte.config.ts']) {
|
|
298
|
+
if (fs.existsSync(path.join(root, file))) {
|
|
299
|
+
throw new Error(
|
|
300
|
+
`${file} is no longer used. Please pass configuration via the \`sveltekit(...)\` plugin in your Vite config.`
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
|
|
330
308
|
/** @type {Plugin} */
|
|
331
309
|
const plugin_setup = {
|
|
332
310
|
name: 'vite-plugin-sveltekit-setup',
|
|
@@ -453,7 +431,9 @@ function kit({ svelte_config }) {
|
|
|
453
431
|
// this does not affect app code, just handling of imported libraries that use $app or $env
|
|
454
432
|
'$app',
|
|
455
433
|
'$env'
|
|
456
|
-
]
|
|
434
|
+
],
|
|
435
|
+
// avoid Vite dev server reloading the first time a page is requested
|
|
436
|
+
include: ['@sveltejs/kit > devalue', '@sveltejs/kit > esm-env']
|
|
457
437
|
},
|
|
458
438
|
ssr: {
|
|
459
439
|
noExternal: [
|
|
@@ -472,27 +452,33 @@ function kit({ svelte_config }) {
|
|
|
472
452
|
}
|
|
473
453
|
};
|
|
474
454
|
|
|
475
|
-
//
|
|
455
|
+
// externalize .remote.js files to stop dependency tracing during prebundling
|
|
476
456
|
if (kit.experimental.remoteFunctions) {
|
|
477
457
|
// @ts-expect-error optimizeDeps is already set above
|
|
478
458
|
new_config.optimizeDeps.rolldownOptions ??= {};
|
|
479
459
|
// @ts-expect-error
|
|
480
460
|
new_config.optimizeDeps.rolldownOptions.plugins ??= [];
|
|
481
461
|
// @ts-expect-error
|
|
482
|
-
new_config.optimizeDeps.rolldownOptions.plugins.push(
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
462
|
+
new_config.optimizeDeps.rolldownOptions.plugins.push(
|
|
463
|
+
/** @type {Rolldown.Plugin} */ ({
|
|
464
|
+
name: 'vite-plugin-sveltekit-setup:optimize-remote-functions',
|
|
465
|
+
resolveId: {
|
|
466
|
+
filter: { id: remote_module_pattern },
|
|
467
|
+
async handler(id, importer) {
|
|
468
|
+
const resolved = await this.resolve(id, importer, { skipSelf: true });
|
|
469
|
+
if (!resolved) return { id, external: true };
|
|
470
|
+
// a servable /@fs url; 'absolute' stops rolldown relativizing it in the deps bundle
|
|
471
|
+
return { id: to_fs(resolved.id), external: 'absolute' };
|
|
472
|
+
}
|
|
488
473
|
}
|
|
489
|
-
}
|
|
490
|
-
|
|
474
|
+
})
|
|
475
|
+
);
|
|
491
476
|
}
|
|
492
477
|
|
|
493
478
|
const define = {
|
|
494
479
|
__SVELTEKIT_APP_DIR__: s(posixify(kit.appDir)),
|
|
495
480
|
__SVELTEKIT_APP_VERSION__: s(kit.version.name),
|
|
481
|
+
__SVELTEKIT_APP_VERSION_CHECKS_ENABLED__: s(kit.output.bundleStrategy !== 'inline'),
|
|
496
482
|
__SVELTEKIT_EMBEDDED__: s(kit.embedded),
|
|
497
483
|
__SVELTEKIT_FORK_PRELOADS__: s(kit.experimental.forkPreloads),
|
|
498
484
|
__SVELTEKIT_PATHS_ASSETS__: s(kit.paths.assets),
|
|
@@ -612,14 +598,10 @@ function kit({ svelte_config }) {
|
|
|
612
598
|
);
|
|
613
599
|
|
|
614
600
|
for (const id of [sveltekit_env, sveltekit_env_public_client]) {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
if (module) {
|
|
618
|
-
server.moduleGraph.invalidateModule(module);
|
|
619
|
-
}
|
|
601
|
+
invalidate_module(server, id);
|
|
620
602
|
}
|
|
621
603
|
|
|
622
|
-
server.
|
|
604
|
+
server.hot.send({ type: 'full-reload' });
|
|
623
605
|
}
|
|
624
606
|
});
|
|
625
607
|
},
|
|
@@ -630,18 +612,13 @@ function kit({ svelte_config }) {
|
|
|
630
612
|
|
|
631
613
|
resolveId: {
|
|
632
614
|
filter: {
|
|
633
|
-
id: [
|
|
615
|
+
id: [prefixRegex('__sveltekit/')]
|
|
634
616
|
},
|
|
635
617
|
handler(id) {
|
|
636
618
|
if (id === '__sveltekit/manifest') {
|
|
637
619
|
return `${out_dir}/generated/client-optimized/app.js`;
|
|
638
620
|
}
|
|
639
621
|
|
|
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
622
|
if (id === '__sveltekit/remote') {
|
|
646
623
|
return `${runtime_directory}/client/remote-functions/index.js`;
|
|
647
624
|
}
|
|
@@ -653,18 +630,18 @@ function kit({ svelte_config }) {
|
|
|
653
630
|
load: {
|
|
654
631
|
filter: {
|
|
655
632
|
id: [
|
|
656
|
-
exactRegex(service_worker),
|
|
657
633
|
exactRegex(sveltekit_env),
|
|
658
634
|
exactRegex(sveltekit_env_private),
|
|
659
635
|
exactRegex(sveltekit_env_public_client),
|
|
660
636
|
exactRegex(sveltekit_env_public_server),
|
|
661
|
-
exactRegex(sveltekit_env_service_worker)
|
|
637
|
+
exactRegex(sveltekit_env_service_worker),
|
|
638
|
+
exactRegex(sveltekit_manifest_data)
|
|
662
639
|
]
|
|
663
640
|
},
|
|
664
641
|
handler(id) {
|
|
665
642
|
switch (id) {
|
|
666
|
-
case
|
|
667
|
-
return
|
|
643
|
+
case sveltekit_manifest_data:
|
|
644
|
+
return create_manifest_data_module(is_build, manifest_data);
|
|
668
645
|
|
|
669
646
|
case sveltekit_env:
|
|
670
647
|
return create_sveltekit_env(explicit_env_config, env, explicit_env_entry, !is_build);
|
|
@@ -691,11 +668,17 @@ function kit({ svelte_config }) {
|
|
|
691
668
|
? create_sveltekit_env_service_worker(
|
|
692
669
|
explicit_env_config,
|
|
693
670
|
env,
|
|
671
|
+
kit.version.name,
|
|
694
672
|
kit_global,
|
|
695
673
|
kit.paths.base,
|
|
696
674
|
kit.appDir
|
|
697
675
|
)
|
|
698
|
-
: create_sveltekit_env_service_worker_dev(
|
|
676
|
+
: create_sveltekit_env_service_worker_dev(
|
|
677
|
+
explicit_env_config,
|
|
678
|
+
env,
|
|
679
|
+
kit.version.name,
|
|
680
|
+
kit_global
|
|
681
|
+
);
|
|
699
682
|
}
|
|
700
683
|
}
|
|
701
684
|
}
|
|
@@ -718,7 +701,7 @@ function kit({ svelte_config }) {
|
|
|
718
701
|
|
|
719
702
|
applyToEnvironment(environment) {
|
|
720
703
|
// the import map is only read for client-side violations in `load`, so skip other environments
|
|
721
|
-
return environment.config.consumer === 'client'
|
|
704
|
+
return environment.config.consumer === 'client';
|
|
722
705
|
},
|
|
723
706
|
|
|
724
707
|
resolveId: {
|
|
@@ -789,6 +772,10 @@ function kit({ svelte_config }) {
|
|
|
789
772
|
if (manifest_data.hooks.client) entrypoints.add(manifest_data.hooks.client);
|
|
790
773
|
if (manifest_data.hooks.universal) entrypoints.add(manifest_data.hooks.universal);
|
|
791
774
|
|
|
775
|
+
if (service_worker_entry_file) {
|
|
776
|
+
entrypoints.add(posixify(path.relative(root, service_worker_entry_file)));
|
|
777
|
+
}
|
|
778
|
+
|
|
792
779
|
// Walk up the import graph from the server-only module, looking for a chain
|
|
793
780
|
// that leads back to a client entrypoint. We search all candidates (not just
|
|
794
781
|
// the first) because a module can be imported by both server and client code,
|
|
@@ -850,7 +837,7 @@ function kit({ svelte_config }) {
|
|
|
850
837
|
/** @type {ViteDevServer} */
|
|
851
838
|
let dev_server;
|
|
852
839
|
|
|
853
|
-
/** @type {
|
|
840
|
+
/** @type {RemoteChunk[]} */
|
|
854
841
|
const remotes = [];
|
|
855
842
|
|
|
856
843
|
/** @type {Map<string, string>} Maps remote hash -> original module id */
|
|
@@ -908,31 +895,33 @@ function kit({ svelte_config }) {
|
|
|
908
895
|
file
|
|
909
896
|
};
|
|
910
897
|
|
|
911
|
-
remotes.push(remote);
|
|
898
|
+
if (this.environment.name === 'ssr') remotes.push(remote);
|
|
912
899
|
|
|
913
900
|
if (this.environment.config.consumer !== 'client') {
|
|
914
901
|
// we need to add an `await Promise.resolve()` because if the user imports this function
|
|
915
902
|
// on the client AND in a load function when loading the client module we will trigger
|
|
916
|
-
// an
|
|
903
|
+
// an import during dev. During a link preload, the module can be mistakenly
|
|
917
904
|
// loaded and transformed twice and the first time all its exports would be undefined
|
|
918
905
|
// triggering a dev server error. By adding a microtask we ensure that the module is fully loaded
|
|
906
|
+
const ms = new MagicString(code);
|
|
919
907
|
|
|
920
908
|
// Extra newlines to prevent syntax errors around missing semicolons or comments
|
|
921
|
-
|
|
909
|
+
ms.append(
|
|
922
910
|
'\n\n' +
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
911
|
+
dedent`
|
|
912
|
+
import * as $$_self_$$ from './${path.basename(id)}';
|
|
913
|
+
import { init_remote_functions as $$_init_$$ } from '@sveltejs/kit/internal/server';
|
|
926
914
|
|
|
927
|
-
|
|
915
|
+
${dev_server ? 'await Promise.resolve()' : ''}
|
|
928
916
|
|
|
929
|
-
|
|
917
|
+
$$_init_$$($$_self_$$, ${s(file)}, ${s(remote.hash)});
|
|
930
918
|
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
919
|
+
for (const [name, fn] of Object.entries($$_self_$$)) {
|
|
920
|
+
fn.__.id = ${s(remote.hash)} + '/' + name;
|
|
921
|
+
fn.__.name = name;
|
|
922
|
+
}
|
|
923
|
+
`
|
|
924
|
+
);
|
|
936
925
|
|
|
937
926
|
// Emit a dedicated entry chunk for this remote in SSR builds (prod only)
|
|
938
927
|
if (!dev_server) {
|
|
@@ -947,7 +936,10 @@ function kit({ svelte_config }) {
|
|
|
947
936
|
}
|
|
948
937
|
}
|
|
949
938
|
|
|
950
|
-
return
|
|
939
|
+
return {
|
|
940
|
+
code: ms.toString(),
|
|
941
|
+
map: ms.generateMap({ hires: 'boundary' })
|
|
942
|
+
};
|
|
951
943
|
}
|
|
952
944
|
|
|
953
945
|
// For the client, read the exports and create a new module that only contains fetch functions with the correct metadata
|
|
@@ -959,7 +951,7 @@ function kit({ svelte_config }) {
|
|
|
959
951
|
// being called again with `opts.ssr === true` if the module isn't
|
|
960
952
|
// already loaded) so we can determine what it exports
|
|
961
953
|
if (dev_server) {
|
|
962
|
-
const module = await dev_server.
|
|
954
|
+
const module = await get_runner(dev_server).import(id);
|
|
963
955
|
|
|
964
956
|
for (const [name, value] of Object.entries(module)) {
|
|
965
957
|
const type = value?.__?.type;
|
|
@@ -997,7 +989,8 @@ function kit({ svelte_config }) {
|
|
|
997
989
|
}
|
|
998
990
|
|
|
999
991
|
return {
|
|
1000
|
-
code: result
|
|
992
|
+
code: result,
|
|
993
|
+
map: null
|
|
1001
994
|
};
|
|
1002
995
|
}
|
|
1003
996
|
}
|
|
@@ -1030,10 +1023,10 @@ function kit({ svelte_config }) {
|
|
|
1030
1023
|
/** @type {Prerendered} */
|
|
1031
1024
|
let prerendered;
|
|
1032
1025
|
|
|
1033
|
-
/** @type {
|
|
1034
|
-
let
|
|
1026
|
+
/** @type {Array<{ path: string }>} */
|
|
1027
|
+
let immutable;
|
|
1035
1028
|
/** @type {string} */
|
|
1036
|
-
let
|
|
1029
|
+
let manifest_data_code;
|
|
1037
1030
|
|
|
1038
1031
|
/**
|
|
1039
1032
|
* Creates the service worker virtual modules
|
|
@@ -1044,7 +1037,6 @@ function kit({ svelte_config }) {
|
|
|
1044
1037
|
|
|
1045
1038
|
config(config) {
|
|
1046
1039
|
service_worker_entry_file = resolve_entry(kit.files.serviceWorker);
|
|
1047
|
-
parsed_service_worker = path.parse(kit.files.serviceWorker);
|
|
1048
1040
|
|
|
1049
1041
|
if (!service_worker_entry_file) return;
|
|
1050
1042
|
|
|
@@ -1099,98 +1091,55 @@ function kit({ svelte_config }) {
|
|
|
1099
1091
|
return environment.name === 'serviceWorker';
|
|
1100
1092
|
},
|
|
1101
1093
|
|
|
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')) {
|
|
1094
|
+
resolveId: {
|
|
1095
|
+
filter: {
|
|
1096
|
+
id: [prefixRegex('__sveltekit/')]
|
|
1097
|
+
},
|
|
1098
|
+
handler(id) {
|
|
1135
1099
|
return `\0virtual:${id}`;
|
|
1136
1100
|
}
|
|
1137
1101
|
},
|
|
1138
1102
|
|
|
1139
1103
|
load: {
|
|
1140
1104
|
filter: {
|
|
1141
|
-
id: [
|
|
1105
|
+
id: [
|
|
1106
|
+
exactRegex('\0virtual:app/manifest'),
|
|
1107
|
+
exactRegex(sveltekit_manifest_data),
|
|
1108
|
+
exactRegex(sveltekit_env_service_worker),
|
|
1109
|
+
exactRegex(sveltekit_env_public_client)
|
|
1110
|
+
]
|
|
1142
1111
|
},
|
|
1143
1112
|
handler(id) {
|
|
1144
|
-
if (!
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
if (kit.output.bundleStrategy === 'inline') {
|
|
1155
|
-
// the bundle and stylesheet are inlined into the page and their files
|
|
1156
|
-
// deleted, so they must not appear in the list of cacheable assets
|
|
1157
|
-
for (const file of build_files) {
|
|
1158
|
-
if (!fs.existsSync(`${out}/client/${file}`)) {
|
|
1159
|
-
build_files.delete(file);
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
|
-
// in a service worker, `location` is the location of the service worker itself,
|
|
1165
|
-
// which is guaranteed to be `<base>/service-worker.js`
|
|
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 = [
|
|
1172
|
-
${Array.from(build_files)
|
|
1173
|
-
.map((file) => `base + ${s(`/${file}`)}`)
|
|
1174
|
-
.join(',\n')}
|
|
1113
|
+
if (!manifest_data_code) {
|
|
1114
|
+
// the client build computes `immutable`, unless it was skipped
|
|
1115
|
+
// because every route has `csr: false`
|
|
1116
|
+
immutable ??= collect_immutable(vite_server_manifest, kit.appDir, new Set());
|
|
1117
|
+
|
|
1118
|
+
manifest_data_code = dedent`
|
|
1119
|
+
export const immutable = [
|
|
1120
|
+
${immutable.map((entry) => s(entry)).join(',\n')}
|
|
1175
1121
|
];
|
|
1176
1122
|
|
|
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')}
|
|
1123
|
+
export const assets = [
|
|
1124
|
+
${manifest_data.assets.map((asset) => s({ path: asset.file })).join(',\n')}
|
|
1182
1125
|
];
|
|
1183
1126
|
|
|
1184
1127
|
export const prerendered = [
|
|
1185
|
-
${prerendered.paths.map((path) =>
|
|
1128
|
+
${prerendered.paths.map((path) => s({ path: path.replace(kit.paths.base, '').slice(1) })).join(',\n')}
|
|
1186
1129
|
];
|
|
1187
1130
|
|
|
1188
|
-
export const
|
|
1131
|
+
export const routes = [
|
|
1132
|
+
${manifest_data.routes.map((route) => s({ id: route.id })).join(',\n')}
|
|
1133
|
+
];
|
|
1189
1134
|
`;
|
|
1190
1135
|
}
|
|
1191
1136
|
|
|
1192
|
-
if (id ===
|
|
1193
|
-
return
|
|
1137
|
+
if (id === '\0virtual:app/manifest') {
|
|
1138
|
+
return `export { immutable, assets, prerendered, routes } from '__sveltekit/manifest-data';`;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
if (id === sveltekit_manifest_data) {
|
|
1142
|
+
return manifest_data_code;
|
|
1194
1143
|
}
|
|
1195
1144
|
|
|
1196
1145
|
if (id === sveltekit_env_service_worker) {
|
|
@@ -1198,11 +1147,17 @@ function kit({ svelte_config }) {
|
|
|
1198
1147
|
? create_sveltekit_env_service_worker(
|
|
1199
1148
|
explicit_env_config,
|
|
1200
1149
|
env,
|
|
1150
|
+
kit.version.name,
|
|
1201
1151
|
kit_global,
|
|
1202
1152
|
kit.paths.base,
|
|
1203
1153
|
kit.appDir
|
|
1204
1154
|
)
|
|
1205
|
-
: create_sveltekit_env_service_worker_dev(
|
|
1155
|
+
: create_sveltekit_env_service_worker_dev(
|
|
1156
|
+
explicit_env_config,
|
|
1157
|
+
env,
|
|
1158
|
+
kit.version.name,
|
|
1159
|
+
kit_global
|
|
1160
|
+
);
|
|
1206
1161
|
}
|
|
1207
1162
|
|
|
1208
1163
|
if (id === sveltekit_env_public_client) {
|
|
@@ -1212,16 +1167,31 @@ function kit({ svelte_config }) {
|
|
|
1212
1167
|
`const env = ${kit_global}.env;`
|
|
1213
1168
|
);
|
|
1214
1169
|
}
|
|
1170
|
+
}
|
|
1171
|
+
},
|
|
1215
1172
|
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1173
|
+
generateBundle(_, bundle) {
|
|
1174
|
+
const invalid_modules = new Set();
|
|
1175
|
+
const modules = new Map([
|
|
1176
|
+
[`${runtime_directory}/app/forms.js`, '$app/forms'],
|
|
1177
|
+
[`${runtime_directory}/app/navigation.js`, '$app/navigation'],
|
|
1178
|
+
[`${runtime_directory}/app/state/index.js`, '$app/state']
|
|
1179
|
+
]);
|
|
1180
|
+
|
|
1181
|
+
for (const output of Object.values(bundle)) {
|
|
1182
|
+
if (output.type !== 'chunk') continue;
|
|
1183
|
+
|
|
1184
|
+
for (const id of output.moduleIds) {
|
|
1185
|
+
const module = modules.get(id);
|
|
1186
|
+
if (module) invalid_modules.add(module);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
if (invalid_modules.size > 0) {
|
|
1223
1191
|
throw new Error(
|
|
1224
|
-
`Cannot import ${
|
|
1192
|
+
`Cannot import ${Array.from(modules.values())
|
|
1193
|
+
.filter((module) => invalid_modules.has(module))
|
|
1194
|
+
.join(', ')} into service-worker code.`
|
|
1225
1195
|
);
|
|
1226
1196
|
}
|
|
1227
1197
|
}
|
|
@@ -1233,17 +1203,19 @@ function kit({ svelte_config }) {
|
|
|
1233
1203
|
applyToEnvironment(environment) {
|
|
1234
1204
|
return !!service_worker_entry_file && environment.config.consumer === 'client';
|
|
1235
1205
|
},
|
|
1236
|
-
transform
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1206
|
+
transform: {
|
|
1207
|
+
handler(code, id) {
|
|
1208
|
+
if (id !== service_worker_entry_file) return;
|
|
1209
|
+
|
|
1210
|
+
// prepend the service worker with an import that configures
|
|
1211
|
+
// `env`, in case `$app/env/public` is imported. In production
|
|
1212
|
+
// this is required: dynamic public env vars aren't known at
|
|
1213
|
+
// build time, so `env.js` is loaded at runtime. In dev, the
|
|
1214
|
+
// imported module just inlines the current values instead.
|
|
1215
|
+
return {
|
|
1216
|
+
code: `import '__sveltekit/env/service-worker';\n${code}`
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1247
1219
|
}
|
|
1248
1220
|
};
|
|
1249
1221
|
|
|
@@ -1427,9 +1399,26 @@ function kit({ svelte_config }) {
|
|
|
1427
1399
|
output: {
|
|
1428
1400
|
format: inline ? 'iife' : 'esm',
|
|
1429
1401
|
entryFileNames: `${app_immutable}/[name].[hash].js`,
|
|
1430
|
-
chunkFileNames:
|
|
1402
|
+
chunkFileNames: (/** @type {Rolldown.PreRenderedChunk} */ chunk_info) => {
|
|
1403
|
+
// The manifest data chunk gets a fixed (non-hashed) filename so
|
|
1404
|
+
// that importers' content hashes are stable regardless of the
|
|
1405
|
+
// manifest content — this breaks the content-hash feedback loop
|
|
1406
|
+
if (chunk_info.name === 'sveltekit-manifest') {
|
|
1407
|
+
return `${kit.appDir}/manifest.js`;
|
|
1408
|
+
}
|
|
1409
|
+
return `${app_immutable}/chunks/[hash].js`;
|
|
1410
|
+
},
|
|
1431
1411
|
codeSplitting:
|
|
1432
|
-
svelte_config.kit.output.bundleStrategy === 'split'
|
|
1412
|
+
svelte_config.kit.output.bundleStrategy === 'split'
|
|
1413
|
+
? {
|
|
1414
|
+
groups: [
|
|
1415
|
+
{
|
|
1416
|
+
name: 'sveltekit-manifest',
|
|
1417
|
+
test: sveltekit_manifest_data
|
|
1418
|
+
}
|
|
1419
|
+
]
|
|
1420
|
+
}
|
|
1421
|
+
: false
|
|
1433
1422
|
},
|
|
1434
1423
|
// This silences Rolldown warnings about not supporting `import.meta`
|
|
1435
1424
|
// for the `iife` output format. We don't care because it's
|
|
@@ -1508,7 +1497,18 @@ function kit({ svelte_config }) {
|
|
|
1508
1497
|
* @see https://vitejs.dev/guide/api-plugin.html#configureserver
|
|
1509
1498
|
*/
|
|
1510
1499
|
async configureServer(server) {
|
|
1511
|
-
return await dev(
|
|
1500
|
+
return await dev(
|
|
1501
|
+
server,
|
|
1502
|
+
vite_config,
|
|
1503
|
+
svelte_config,
|
|
1504
|
+
() => remotes,
|
|
1505
|
+
root,
|
|
1506
|
+
(data) => {
|
|
1507
|
+
manifest_data = data;
|
|
1508
|
+
// Invalidate the manifest data module so it reloads with new routes/files
|
|
1509
|
+
invalidate_module(server, sveltekit_manifest_data);
|
|
1510
|
+
}
|
|
1511
|
+
);
|
|
1512
1512
|
},
|
|
1513
1513
|
|
|
1514
1514
|
/**
|
|
@@ -1564,6 +1564,15 @@ function kit({ svelte_config }) {
|
|
|
1564
1564
|
await builder.build(builder.environments.ssr)
|
|
1565
1565
|
);
|
|
1566
1566
|
|
|
1567
|
+
// Replace manifest placeholders in SSR output. `assets` and `routes`
|
|
1568
|
+
// are known from `manifest_data`. `immutable` and `prerendered` are not
|
|
1569
|
+
// known yet — they get sentinel strings that are replaced after
|
|
1570
|
+
// the client build and after prerendering respectively.
|
|
1571
|
+
replace_manifest_placeholder_variables(server_chunks, `${out}/server`, {
|
|
1572
|
+
assets: manifest_data.assets.map((asset) => ({ path: asset.file })),
|
|
1573
|
+
routes: manifest_data.routes.map((route) => ({ id: route.id }))
|
|
1574
|
+
});
|
|
1575
|
+
|
|
1567
1576
|
const verbose = builder.config.logLevel === 'info';
|
|
1568
1577
|
const log = logger({ verbose });
|
|
1569
1578
|
|
|
@@ -1695,6 +1704,41 @@ function kit({ svelte_config }) {
|
|
|
1695
1704
|
const deps_of = (entry, add_dynamic_css = false) =>
|
|
1696
1705
|
find_deps(vite_manifest, posixify(path.relative(root, entry)), add_dynamic_css, root);
|
|
1697
1706
|
|
|
1707
|
+
// the inline bundle and stylesheet are deleted further down, after
|
|
1708
|
+
// being inlined into the page, so they must not appear in `immutable`
|
|
1709
|
+
/** @type {Set<string>} */
|
|
1710
|
+
const inlined = new Set();
|
|
1711
|
+
/** @type {Rolldown.OutputAsset | undefined} */
|
|
1712
|
+
let inline_style;
|
|
1713
|
+
|
|
1714
|
+
if (kit.output.bundleStrategy === 'inline') {
|
|
1715
|
+
inline_style = /** @type {Rolldown.OutputAsset | undefined} */ (
|
|
1716
|
+
client_chunks.find(
|
|
1717
|
+
(chunk) =>
|
|
1718
|
+
chunk.type === 'asset' && chunk.names.length === 1 && chunk.names[0] === 'style.css'
|
|
1719
|
+
)
|
|
1720
|
+
);
|
|
1721
|
+
|
|
1722
|
+
inlined.add(deps_of(`${runtime_directory}/client/bundle.js`).file);
|
|
1723
|
+
if (inline_style) inlined.add(inline_style.fileName);
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
// Replace manifest placeholders in client output. `immutable` is
|
|
1727
|
+
// computed from the Vite client manifest, `assets` and `routes`
|
|
1728
|
+
// from `manifest_data`. `prerendered` is left as a placeholder
|
|
1729
|
+
// for now — it's replaced after prerendering completes.
|
|
1730
|
+
immutable = collect_immutable(vite_manifest, kit.appDir, inlined);
|
|
1731
|
+
|
|
1732
|
+
replace_manifest_placeholder_variables(client_chunks, `${out}/client`, {
|
|
1733
|
+
immutable,
|
|
1734
|
+
assets: manifest_data.assets.map((asset) => ({ path: asset.file })),
|
|
1735
|
+
routes: manifest_data.routes.map((route) => ({ id: route.id }))
|
|
1736
|
+
});
|
|
1737
|
+
|
|
1738
|
+
// Now that the client build is done, replace the `build` sentinel
|
|
1739
|
+
// in the SSR output with the real build files
|
|
1740
|
+
replace_manifest_placeholder_strings(`${out}/server`, { immutable });
|
|
1741
|
+
|
|
1698
1742
|
const has_explicit_dynamic_public_env = Object.values(explicit_env_config ?? {}).some(
|
|
1699
1743
|
(variable) => variable.public && !variable.static
|
|
1700
1744
|
);
|
|
@@ -1782,25 +1826,16 @@ function kit({ svelte_config }) {
|
|
|
1782
1826
|
};
|
|
1783
1827
|
|
|
1784
1828
|
if (svelte_config.kit.output.bundleStrategy === 'inline') {
|
|
1785
|
-
const style = /** @type {Rolldown.OutputAsset} */ (
|
|
1786
|
-
client_chunks.find(
|
|
1787
|
-
(chunk) =>
|
|
1788
|
-
chunk.type === 'asset' &&
|
|
1789
|
-
chunk.names.length === 1 &&
|
|
1790
|
-
chunk.names[0] === 'style.css'
|
|
1791
|
-
)
|
|
1792
|
-
);
|
|
1793
|
-
|
|
1794
1829
|
build_data.client.inline = {
|
|
1795
1830
|
script: read(`${out}/client/${start.file}`),
|
|
1796
|
-
style: /** @type {string | undefined} */ (
|
|
1831
|
+
style: /** @type {string | undefined} */ (inline_style?.source)
|
|
1797
1832
|
};
|
|
1798
1833
|
|
|
1799
1834
|
// the bundle and stylesheet are inlined into the page, so the
|
|
1800
1835
|
// emitted files are never loaded
|
|
1801
1836
|
fs.unlinkSync(`${out}/client/${start.file}`);
|
|
1802
1837
|
fs.rmSync(`${out}/client/${start.file}.map`, { force: true });
|
|
1803
|
-
if (
|
|
1838
|
+
if (inline_style) fs.unlinkSync(`${out}/client/${inline_style.fileName}`);
|
|
1804
1839
|
}
|
|
1805
1840
|
}
|
|
1806
1841
|
|
|
@@ -1860,10 +1895,30 @@ function kit({ svelte_config }) {
|
|
|
1860
1895
|
|
|
1861
1896
|
prerendered = prerender_results.prerendered;
|
|
1862
1897
|
|
|
1898
|
+
// Replace the `prerendered` sentinel in both SSR and client output
|
|
1899
|
+
// with the real prerendered paths. The other sentinels (`build`)
|
|
1900
|
+
// were already replaced after the client build.
|
|
1901
|
+
const prerendered_paths = prerendered.paths.map((p) => {
|
|
1902
|
+
return { path: p.replace(kit.paths.base, '').slice(1) };
|
|
1903
|
+
});
|
|
1904
|
+
|
|
1905
|
+
replace_manifest_placeholder_strings(`${out}/server`, { prerendered: prerendered_paths });
|
|
1906
|
+
replace_manifest_placeholder_strings(`${out}/client`, { prerendered: prerendered_paths });
|
|
1907
|
+
|
|
1908
|
+
// For `inline` strategy, the entry file was deleted and read into
|
|
1909
|
+
// `build_data.client.inline.script` — replace the sentinel there too
|
|
1910
|
+
if (build_data.client?.inline?.script) {
|
|
1911
|
+
build_data.client.inline.script = build_data.client.inline.script.replaceAll(
|
|
1912
|
+
'"__sveltekit_manifest_prerendered__"',
|
|
1913
|
+
JSON.stringify(prerendered_paths)
|
|
1914
|
+
);
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1863
1917
|
await treeshake_prerendered_remotes(
|
|
1864
1918
|
vite,
|
|
1865
1919
|
out,
|
|
1866
1920
|
remotes,
|
|
1921
|
+
remote_original_by_hash,
|
|
1867
1922
|
metadata,
|
|
1868
1923
|
process.cwd(),
|
|
1869
1924
|
server_chunks,
|
|
@@ -1956,6 +2011,7 @@ function kit({ svelte_config }) {
|
|
|
1956
2011
|
return /** @type {Plugin[]} */ (
|
|
1957
2012
|
[
|
|
1958
2013
|
svelte_config.kit.adapter?.vite?.plugins,
|
|
2014
|
+
plugin_resolve_root,
|
|
1959
2015
|
plugin_setup,
|
|
1960
2016
|
plugin_remote_guard,
|
|
1961
2017
|
plugin_remote,
|
|
@@ -2004,11 +2060,7 @@ function find_overridden_config(config, resolved_config, enforced_config, path,
|
|
|
2004
2060
|
const resolved = resolved_config[key];
|
|
2005
2061
|
|
|
2006
2062
|
if (enforced === true) {
|
|
2007
|
-
|
|
2008
|
-
// where config values like `root` may use backslashes while SvelteKit uses forward slashes.
|
|
2009
|
-
const a = typeof config[key] === 'string' ? posixify(config[key]) : config[key];
|
|
2010
|
-
const b = typeof resolved === 'string' ? posixify(resolved) : resolved;
|
|
2011
|
-
if (a !== b) {
|
|
2063
|
+
if (comparable(config[key]) !== comparable(resolved)) {
|
|
2012
2064
|
out.push(path + key);
|
|
2013
2065
|
}
|
|
2014
2066
|
} else {
|
|
@@ -2020,21 +2072,184 @@ function find_overridden_config(config, resolved_config, enforced_config, path,
|
|
|
2020
2072
|
}
|
|
2021
2073
|
|
|
2022
2074
|
/**
|
|
2023
|
-
*
|
|
2075
|
+
* Collects the content-hashed files of a Vite manifest, in the shape of
|
|
2076
|
+
* `$app/manifest`'s `immutable` export.
|
|
2077
|
+
*
|
|
2078
|
+
* @param {Manifest} manifest
|
|
2079
|
+
* @param {string} app_dir
|
|
2080
|
+
* @param {Set<string>} inlined files deleted from the output after being inlined into the page
|
|
2081
|
+
* @returns {Array<{ path: string }>}
|
|
2024
2082
|
*/
|
|
2025
|
-
const
|
|
2026
|
-
|
|
2027
|
-
|
|
2083
|
+
const collect_immutable = (manifest, app_dir, inlined) => {
|
|
2084
|
+
const prefix = `${app_dir}/immutable`;
|
|
2085
|
+
|
|
2086
|
+
/** @type {Set<string>} */
|
|
2087
|
+
const files = new Set();
|
|
2088
|
+
|
|
2089
|
+
/** @param {string} file */
|
|
2090
|
+
const add = (file) => {
|
|
2091
|
+
if (file.startsWith(prefix) && !inlined.has(file)) files.add(file);
|
|
2092
|
+
};
|
|
2093
|
+
|
|
2094
|
+
for (const key in manifest) {
|
|
2095
|
+
const { file, css, assets } = manifest[key];
|
|
2096
|
+
add(file);
|
|
2097
|
+
if (css) for (let i = 0; i < css.length; i++) add(css[i]);
|
|
2098
|
+
if (assets) for (let i = 0; i < assets.length; i++) add(assets[i]);
|
|
2028
2099
|
}
|
|
2029
2100
|
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2101
|
+
return Array.from(files, (path) => ({ path }));
|
|
2102
|
+
};
|
|
2103
|
+
|
|
2104
|
+
/**
|
|
2105
|
+
* Normalizes a config value for comparison, since Windows paths may use backslashes
|
|
2106
|
+
* and differ in casing (e.g. the drive letter) depending on where they came from.
|
|
2107
|
+
* @param {any} value
|
|
2108
|
+
*/
|
|
2109
|
+
function comparable(value) {
|
|
2110
|
+
if (typeof value !== 'string') return value;
|
|
2111
|
+
const normalized = posixify(value);
|
|
2112
|
+
return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2115
|
+
/**
|
|
2116
|
+
* Creates the `$app/manifest` data module. During development, real values
|
|
2117
|
+
* are emitted for `assets` and `routes` (the only data known at that point).
|
|
2118
|
+
*
|
|
2119
|
+
* During build, bare identifier placeholders (fake globals) are emitted.
|
|
2120
|
+
* The bundler leaves these as unresolved global references in the output,
|
|
2121
|
+
* which are then replaced with real values by scanning the output chunks
|
|
2122
|
+
* after each build completes. This avoids the content-hash feedback loop:
|
|
2123
|
+
* the manifest data lives in its own chunk with a fixed filename, so
|
|
2124
|
+
* importers' hashes are stable regardless of the manifest content.
|
|
2125
|
+
*
|
|
2126
|
+
* @param {boolean} is_build
|
|
2127
|
+
* @param {ManifestData | undefined} manifest_data
|
|
2128
|
+
* @returns {string}
|
|
2129
|
+
*/
|
|
2130
|
+
const create_manifest_data_module = (is_build, manifest_data) => {
|
|
2131
|
+
if (is_build) {
|
|
2132
|
+
// Bare identifiers (fake globals) — the bundler leaves these as
|
|
2133
|
+
// unresolved global references in the output. They are replaced
|
|
2134
|
+
// with real values by `replace_manifest_placeholder_variables`
|
|
2135
|
+
// after each build completes.
|
|
2136
|
+
return dedent`
|
|
2137
|
+
export const immutable = __SVELTEKIT_MANIFEST_IMMUTABLE__;
|
|
2138
|
+
export const assets = __SVELTEKIT_MANIFEST_ASSETS__;
|
|
2139
|
+
export const prerendered = __SVELTEKIT_MANIFEST_PRERENDERED__;
|
|
2140
|
+
export const routes = __SVELTEKIT_MANIFEST_ROUTES__;
|
|
2141
|
+
`;
|
|
2142
|
+
}
|
|
2143
|
+
|
|
2144
|
+
// In dev, `manifest_data` may not be set yet on the very first load,
|
|
2145
|
+
// but `configureServer` (which calls `sync.create`) runs before any
|
|
2146
|
+
// module is served, so it will be set by the time this is called.
|
|
2147
|
+
const routes = manifest_data?.routes.map((route) => s({ id: route.id })).join(',\n') ?? '';
|
|
2148
|
+
const assets = manifest_data?.assets.map((asset) => s({ path: asset.file })).join(',\n') ?? '';
|
|
2149
|
+
|
|
2150
|
+
return dedent`
|
|
2151
|
+
// empty during dev
|
|
2152
|
+
export const immutable = [];
|
|
2153
|
+
export const prerendered = [];
|
|
2154
|
+
|
|
2155
|
+
export const assets = [
|
|
2156
|
+
${assets}
|
|
2157
|
+
];
|
|
2158
|
+
|
|
2159
|
+
export const routes = [
|
|
2160
|
+
${routes}
|
|
2161
|
+
];
|
|
2162
|
+
`;
|
|
2163
|
+
};
|
|
2164
|
+
|
|
2165
|
+
/**
|
|
2166
|
+
* Replaces manifest data placeholder identifiers in output chunks with real
|
|
2167
|
+
* values, or strings that are valid JS (so thecode doesn't crash during prerendering)
|
|
2168
|
+
* but findable on disk for later replacement by `replace_manifest_placeholder_strings`.
|
|
2169
|
+
*
|
|
2170
|
+
* @param {Rolldown.RolldownOutput['output']} chunks
|
|
2171
|
+
* @param {string} output_dir
|
|
2172
|
+
* @param {{
|
|
2173
|
+
* immutable?: Array<{ path: string }>;
|
|
2174
|
+
* assets?: Array<{ path: string }>;
|
|
2175
|
+
* prerendered?: Array<{ path: string }>;
|
|
2176
|
+
* routes?: Array<{ id: string }>;
|
|
2177
|
+
* }} values
|
|
2178
|
+
*/
|
|
2179
|
+
const replace_manifest_placeholder_variables = (chunks, output_dir, values) => {
|
|
2180
|
+
/** @type {Record<string, string>} */
|
|
2181
|
+
const replacements = {
|
|
2182
|
+
__SVELTEKIT_MANIFEST_IMMUTABLE__: JSON.stringify(
|
|
2183
|
+
values.immutable ?? '__sveltekit_manifest_build__'
|
|
2184
|
+
),
|
|
2185
|
+
__SVELTEKIT_MANIFEST_ASSETS__: JSON.stringify(values.assets ?? '__sveltekit_manifest_files__'),
|
|
2186
|
+
__SVELTEKIT_MANIFEST_PRERENDERED__: JSON.stringify(
|
|
2187
|
+
values.prerendered ?? '__sveltekit_manifest_prerendered__'
|
|
2188
|
+
),
|
|
2189
|
+
__SVELTEKIT_MANIFEST_ROUTES__: JSON.stringify(values.routes ?? '__sveltekit_manifest_routes__')
|
|
2190
|
+
};
|
|
2191
|
+
|
|
2192
|
+
for (const chunk of chunks) {
|
|
2193
|
+
if (chunk.type !== 'chunk') continue;
|
|
2194
|
+
if (!chunk.code.includes('__SVELTEKIT_MANIFEST_')) continue;
|
|
2195
|
+
|
|
2196
|
+
let code = chunk.code;
|
|
2197
|
+
|
|
2198
|
+
for (const [identifier, replacement] of Object.entries(replacements)) {
|
|
2199
|
+
code = code.replaceAll(identifier, replacement);
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
const file_path = `${output_dir}/${chunk.fileName}`;
|
|
2203
|
+
fs.writeFileSync(file_path, code);
|
|
2204
|
+
}
|
|
2205
|
+
};
|
|
2206
|
+
|
|
2207
|
+
/**
|
|
2208
|
+
* Replaces manifest sentinel strings in files on disk with real values.
|
|
2209
|
+
* This is used for values that weren't known when the first replacement
|
|
2210
|
+
* pass ran (e.g. `build` wasn't known until after the client build,
|
|
2211
|
+
* `prerendered` wasn't known until after prerendering).
|
|
2212
|
+
*
|
|
2213
|
+
* @param {string} dir Directory to scan for .js files
|
|
2214
|
+
* @param {{
|
|
2215
|
+
* immutable?: Array<{ path: string }>;
|
|
2216
|
+
* prerendered?: Array<{ path: string }>;
|
|
2217
|
+
* }} values
|
|
2218
|
+
*/
|
|
2219
|
+
const replace_manifest_placeholder_strings = (dir, values) => {
|
|
2220
|
+
/** @type {Record<string, string>} */
|
|
2221
|
+
const replacements = {};
|
|
2222
|
+
|
|
2223
|
+
if (values.immutable !== undefined) {
|
|
2224
|
+
replacements['__sveltekit_manifest_build__'] = JSON.stringify(values.immutable);
|
|
2225
|
+
}
|
|
2226
|
+
if (values.prerendered !== undefined) {
|
|
2227
|
+
replacements['__sveltekit_manifest_prerendered__'] = JSON.stringify(values.prerendered);
|
|
2228
|
+
}
|
|
2229
|
+
|
|
2230
|
+
for (const file of fs.readdirSync(dir)) {
|
|
2231
|
+
const file_path = `${dir}/${file}`;
|
|
2232
|
+
const stat = fs.statSync(file_path);
|
|
2233
|
+
|
|
2234
|
+
if (stat.isDirectory()) {
|
|
2235
|
+
replace_manifest_placeholder_strings(file_path, values);
|
|
2236
|
+
continue;
|
|
2237
|
+
}
|
|
2238
|
+
|
|
2239
|
+
if (!file.endsWith('.js')) continue;
|
|
2240
|
+
|
|
2241
|
+
let code = read(file_path);
|
|
2242
|
+
let changed = false;
|
|
2243
|
+
|
|
2244
|
+
for (const [sentinel, replacement] of Object.entries(replacements)) {
|
|
2245
|
+
if (code.includes(sentinel)) {
|
|
2246
|
+
code = code.replaceAll(`"${sentinel}"`, replacement);
|
|
2247
|
+
changed = true;
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2251
|
+
if (changed) {
|
|
2252
|
+
fs.writeFileSync(file_path, code);
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
};
|