Skip to content

Commit 43a745a

Browse files
committed
fix: make preview work with Vite 5
1 parent 10d5f96 commit 43a745a

File tree

2 files changed

+50
-56
lines changed

2 files changed

+50
-56
lines changed

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

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import fs from 'node:fs';
2-
import path from 'node:path';
2+
import path, { join } from 'node:path';
33

44
import { svelte } from '@sveltejs/vite-plugin-svelte';
55
import colors from 'kleur';
@@ -19,15 +19,21 @@ import { dev } from './dev/index.js';
1919
import { is_illegal, module_guard, normalize_id } from './graph_analysis/index.js';
2020
import { preview } from './preview/index.js';
2121
import { get_config_aliases, get_env, strip_virtual_prefix } from './utils.js';
22+
import { SVELTE_KIT_ASSETS } from '../../constants.js';
2223
import { write_client_manifest } from '../../core/sync/write_client_manifest.js';
2324
import prerender from '../../core/postbuild/prerender.js';
2425
import analyse from '../../core/postbuild/analyse.js';
2526
import { s } from '../../utils/misc.js';
2627
import { hash } from '../../runtime/hash.js';
2728
import { dedent, isSvelte5Plus } from '../../core/sync/utils.js';
29+
import sirv from 'sirv';
2830

2931
export { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
3032

33+
/** @typedef {import('http').IncomingMessage} Req */
34+
/** @typedef {import('http').ServerResponse} Res */
35+
/** @typedef {(req: Req, res: Res, next: () => void) => void} Handler */
36+
3137
const cwd = process.cwd();
3238

3339
/** @type {import('./types.js').EnforcedConfig} */
@@ -617,6 +623,23 @@ function kit({ svelte_config }) {
617623
* @see https://vitejs.dev/guide/api-plugin.html#configurepreviewserver
618624
*/
619625
configurePreviewServer(vite) {
626+
// generated client assets and the contents of `static`
627+
const { paths } = svelte_config.kit;
628+
const assets = paths.assets ? SVELTE_KIT_ASSETS : paths.base;
629+
vite.middlewares.use(
630+
scoped(
631+
assets,
632+
sirv(join(svelte_config.kit.outDir, 'output/client'), {
633+
setHeaders: (res, pathname) => {
634+
// only apply to immutable directory, not e.g. version.json
635+
if (pathname.startsWith(`/${svelte_config.kit.appDir}/immutable`)) {
636+
res.setHeader('cache-control', 'public,max-age=31536000,immutable');
637+
}
638+
}
639+
})
640+
)
641+
);
642+
620643
return preview(vite, vite_config, svelte_config);
621644
},
622645

@@ -906,3 +929,25 @@ const create_service_worker_module = (config) => dedent`
906929
export const prerendered = [];
907930
export const version = ${s(config.kit.version.name)};
908931
`;
932+
933+
/**
934+
* @param {string} scope
935+
* @param {Handler} handler
936+
* @returns {Handler}
937+
*/
938+
function scoped(scope, handler) {
939+
if (scope === '') return handler;
940+
941+
return (req, res, next) => {
942+
if (req.url?.startsWith(scope)) {
943+
const original_url = req.url;
944+
req.url = req.url.slice(scope.length);
945+
handler(req, res, () => {
946+
req.url = original_url;
947+
next();
948+
});
949+
} else {
950+
next();
951+
}
952+
};
953+
}

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

Lines changed: 4 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { getRequest, setResponse } from '../../../exports/node/index.js';
88
import { installPolyfills } from '../../../exports/node/polyfills.js';
99
import { SVELTE_KIT_ASSETS } from '../../../constants.js';
1010
import { should_polyfill } from '../../../utils/platform.js';
11-
import { not_found } from '../utils.js';
1211

1312
/** @typedef {import('http').IncomingMessage} Req */
1413
/** @typedef {import('http').ServerResponse} Res */
@@ -54,42 +53,15 @@ export async function preview(vite, vite_config, svelte_config) {
5453
});
5554

5655
return () => {
57-
// generated client assets and the contents of `static`
58-
vite.middlewares.use(
59-
scoped(
60-
assets,
61-
sirv(join(svelte_config.kit.outDir, 'output/client'), {
62-
setHeaders: (res, pathname) => {
63-
// only apply to immutable directory, not e.g. version.json
64-
if (pathname.startsWith(`/${svelte_config.kit.appDir}/immutable`)) {
65-
res.setHeader('cache-control', 'public,max-age=31536000,immutable');
66-
}
67-
}
68-
})
69-
)
70-
);
71-
72-
vite.middlewares.use((req, res, next) => {
73-
const original_url = /** @type {string} */ (req.url);
74-
const { pathname } = new URL(original_url, 'http://dummy');
75-
76-
if (pathname.startsWith(base)) {
77-
next();
78-
} else {
79-
res.statusCode = 404;
80-
not_found(req, res, base);
81-
}
82-
});
83-
8456
// prerendered dependencies
8557
vite.middlewares.use(
86-
scoped(base, mutable(join(svelte_config.kit.outDir, 'output/prerendered/dependencies')))
58+
mutable(join(svelte_config.kit.outDir, 'output/prerendered/dependencies'))
8759
);
8860

8961
// prerendered pages (we can't just use sirv because we need to
9062
// preserve the correct trailingSlash behaviour)
9163
vite.middlewares.use(
92-
scoped(base, (req, res, next) => {
64+
(req, res, next) => {
9365
let if_none_match_value = req.headers['if-none-match'];
9466

9567
if (if_none_match_value?.startsWith('W/"')) {
@@ -149,18 +121,17 @@ export async function preview(vite, vite_config, svelte_config) {
149121
} else {
150122
next();
151123
}
152-
})
124+
}
153125
);
154126

155127
// SSR
156128
vite.middlewares.use(async (req, res) => {
157129
const host = req.headers['host'];
158130

159131
let request;
160-
161132
try {
162133
request = await getRequest({
163-
base: `${protocol}://${host}`,
134+
base: new URL(base, `${protocol}://${host}`).href,
164135
request: req
165136
});
166137
} catch (/** @type {any} */ err) {
@@ -195,28 +166,6 @@ const mutable = (dir) =>
195166
})
196167
: (_req, _res, next) => next();
197168

198-
/**
199-
* @param {string} scope
200-
* @param {Handler} handler
201-
* @returns {Handler}
202-
*/
203-
function scoped(scope, handler) {
204-
if (scope === '') return handler;
205-
206-
return (req, res, next) => {
207-
if (req.url?.startsWith(scope)) {
208-
const original_url = req.url;
209-
req.url = req.url.slice(scope.length);
210-
handler(req, res, () => {
211-
req.url = original_url;
212-
next();
213-
});
214-
} else {
215-
next();
216-
}
217-
};
218-
}
219-
220169
/** @param {string} path */
221170
function is_file(path) {
222171
return fs.existsSync(path) && !fs.statSync(path).isDirectory();

0 commit comments

Comments
 (0)