From f77bc70724cfb12533470a18eae24b7a306c69ef Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Thu, 17 Jul 2025 13:03:22 +0800 Subject: [PATCH 01/16] wip --- package.json | 5 +- packages/adapter-cloudflare/index.js | 72 +- packages/adapter-cloudflare/internal.d.ts | 11 + packages/adapter-cloudflare/package.json | 3 + packages/adapter-cloudflare/tsconfig.json | 2 +- packages/adapter-cloudflare/worker.js | 97 ++ .../src/exports/vite/build/build_server.js | 8 +- .../kit/src/exports/vite/dev/environment.js | 71 ++ packages/kit/src/exports/vite/dev/index.js | 634 ++++++------ packages/kit/src/exports/vite/index.js | 933 +++++++++++------- packages/kit/src/exports/vite/module_ids.js | 1 + packages/kit/src/types/internal.d.ts | 6 + pnpm-lock.yaml | 295 +++--- pnpm-workspace.yaml | 4 +- 14 files changed, 1314 insertions(+), 828 deletions(-) create mode 100644 packages/adapter-cloudflare/worker.js create mode 100644 packages/kit/src/exports/vite/dev/environment.js diff --git a/package.json b/package.json index 09052d1b6a80..006ae740cdbd 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,9 @@ "sharp", "svelte-preprocess", "workerd" - ] + ], + "overrides": { + "esm-env": "github:benmccann/esm-env#bcbddbc&path:packages/esm-env" + } } } diff --git a/packages/adapter-cloudflare/index.js b/packages/adapter-cloudflare/index.js index 266265556369..238ccbbc89d7 100644 --- a/packages/adapter-cloudflare/index.js +++ b/packages/adapter-cloudflare/index.js @@ -2,7 +2,7 @@ import { copyFileSync, existsSync, writeFileSync } from 'node:fs'; import path from 'node:path'; import process from 'node:process'; import { fileURLToPath } from 'node:url'; -import { getPlatformProxy, unstable_readConfig } from 'wrangler'; +import { unstable_readConfig } from 'wrangler'; /** @type {import('./index.js').default} */ export default function (options = {}) { @@ -128,41 +128,41 @@ export default function (options = {}) { ); } }, - emulate() { - // we want to invoke `getPlatformProxy` only once, but await it only when it is accessed. - // If we would await it here, it would hang indefinitely because the platform proxy only resolves once a request happens - const get_emulated = async () => { - const proxy = await getPlatformProxy(options.platformProxy); - const platform = /** @type {App.Platform} */ ({ - env: proxy.env, - ctx: proxy.ctx, - context: proxy.ctx, // deprecated in favor of ctx - caches: proxy.caches, - cf: proxy.cf - }); - /** @type {Record} */ - const env = {}; - const prerender_platform = /** @type {App.Platform} */ (/** @type {unknown} */ ({ env })); - for (const key in proxy.env) { - Object.defineProperty(env, key, { - get: () => { - throw new Error(`Cannot access platform.env.${key} in a prerenderable route`); - } - }); - } - return { platform, prerender_platform }; - }; - - /** @type {{ platform: App.Platform, prerender_platform: App.Platform }} */ - let emulated; - - return { - platform: async ({ prerender }) => { - emulated ??= await get_emulated(); - return prerender ? emulated.prerender_platform : emulated.platform; - } - }; - } + // emulate() { + // // we want to invoke `getPlatformProxy` only once, but await it only when it is accessed. + // // If we would await it here, it would hang indefinitely because the platform proxy only resolves once a request happens + // const get_emulated = async () => { + // const proxy = await getPlatformProxy(options.platformProxy); + // const platform = /** @type {App.Platform} */ ({ + // env: proxy.env, + // ctx: proxy.ctx, + // context: proxy.ctx, // deprecated in favor of ctx + // caches: proxy.caches, + // cf: proxy.cf + // }); + // /** @type {Record} */ + // const env = {}; + // const prerender_platform = /** @type {App.Platform} */ (/** @type {unknown} */ ({ env })); + // for (const key in proxy.env) { + // Object.defineProperty(env, key, { + // get: () => { + // throw new Error(`Cannot access platform.env.${key} in a prerenderable route`); + // } + // }); + // } + // return { platform, prerender_platform }; + // }; + + // /** @type {{ platform: App.Platform, prerender_platform: App.Platform }} */ + // let emulated; + + // return { + // platform: async ({ prerender }) => { + // emulated ??= await get_emulated(); + // return prerender ? emulated.prerender_platform : emulated.platform; + // } + // }; + // } }; } diff --git a/packages/adapter-cloudflare/internal.d.ts b/packages/adapter-cloudflare/internal.d.ts index 6c79569f7f7f..aa3c0abaf929 100644 --- a/packages/adapter-cloudflare/internal.d.ts +++ b/packages/adapter-cloudflare/internal.d.ts @@ -10,3 +10,14 @@ declare module 'MANIFEST' { export const app_path: string; export const base_path: string; } + +declare module '__sveltekit/vite-environment' { + // eslint-disable-next-line no-duplicate-imports + import { SSRManifest } from '@sveltejs/kit'; + + export const manifest: SSRManifest; + export const env: Record; + export const remote_address: string | undefined; + export const base_path: string; + export const prerendered: Set; +} diff --git a/packages/adapter-cloudflare/package.json b/packages/adapter-cloudflare/package.json index b1ab4d0e8a3d..77c58b219a1a 100644 --- a/packages/adapter-cloudflare/package.json +++ b/packages/adapter-cloudflare/package.json @@ -23,6 +23,9 @@ "types": "./index.d.ts", "import": "./index.js" }, + "./worker": { + "import": "./worker.js" + }, "./package.json": "./package.json" }, "types": "index.d.ts", diff --git a/packages/adapter-cloudflare/tsconfig.json b/packages/adapter-cloudflare/tsconfig.json index dea57ac8d9a4..f3cca384b213 100644 --- a/packages/adapter-cloudflare/tsconfig.json +++ b/packages/adapter-cloudflare/tsconfig.json @@ -15,5 +15,5 @@ "lib": ["es2021"], "types": ["@cloudflare/workers-types"] }, - "include": ["index.js", "utils.js", "test/utils.js", "internal.d.ts", "src/worker.js"] + "include": ["index.js", "worker.js", "test/utils.js", "internal.d.ts", "src/worker.js"] } diff --git a/packages/adapter-cloudflare/worker.js b/packages/adapter-cloudflare/worker.js new file mode 100644 index 000000000000..0fbc95583223 --- /dev/null +++ b/packages/adapter-cloudflare/worker.js @@ -0,0 +1,97 @@ +import { Server } from '../kit/src/runtime/server/index.js'; +// TODO: use prod variables when building +// TODO: fix kit virtual module type issues when this file is consumed by an app +import { + manifest, + env, + remote_address, + base_path, + prerendered +} from '__sveltekit/vite-environment'; +import * as Cache from 'worktop/cfw.cache'; + +const app_path = `/${manifest.appPath}`; + +const immutable = `${app_path}/immutable/`; +const version_file = `${app_path}/version.json`; + +const server = new Server(manifest); + +await server.init({ env }); + +/** + * @param {Request} request + * @param {{ ASSETS: { fetch: typeof fetch } }} env + * @param {import('@cloudflare/workers-types').ExecutionContext} ctx + * @returns {Promise} + */ +export async function handleRequest(request, env, ctx) { + // skip cache if "cache-control: no-cache" in request + let pragma = request.headers.get('cache-control') || ''; + let res = !pragma.includes('no-cache') && (await Cache.lookup(request)); + if (res) return res; + + let { pathname, search } = new URL(request.url); + try { + pathname = decodeURIComponent(pathname); + } catch { + // ignore invalid URI + } + + const stripped_pathname = pathname.replace(/\/$/, ''); + + // files in /static, the service worker, and Vite imported server assets + let is_static_asset = false; + const filename = stripped_pathname.slice(base_path.length + 1); + if (filename) { + is_static_asset = + manifest.assets.has(filename) || + manifest.assets.has(filename + '/index.html') || + filename in manifest._.server_assets || + filename + '/index.html' in manifest._.server_assets; + } + + let location = pathname.at(-1) === '/' ? stripped_pathname : pathname + '/'; + + if ( + is_static_asset || + prerendered.has(pathname) || + pathname === version_file || + pathname.startsWith(immutable) + ) { + res = await env.ASSETS.fetch(request); + } else if (location && prerendered.has(location)) { + // trailing slash redirect for prerendered pages + if (search) location += search; + res = new Response('', { + status: 308, + headers: { + location + } + }); + } else { + // dynamically-generated pages + res = await server.respond(request, { + platform: { + env, + ctx, + context: ctx, // deprecated in favor of ctx + // @ts-expect-error webworker types from worktop are not compatible with Cloudflare Workers types + caches, + // @ts-expect-error the type is correct but ts is confused because platform.cf uses the type from index.ts while req.cf uses the type from index.d.ts + cf: request.cf + }, + getClientAddress() { + if (remote_address) return remote_address; + throw new Error('Could not determine clientAddress'); + // TODO: use the header in prod + // return request.headers.get('cf-connecting-ip'); + } + }); + } + + // write to `Cache` only if response is not an error, + // let `Cache.save` handle the Cache-Control and Vary headers + pragma = res.headers.get('cache-control') || ''; + return pragma && res.status < 400 ? Cache.save(request, res, ctx) : res; +} diff --git a/packages/kit/src/exports/vite/build/build_server.js b/packages/kit/src/exports/vite/build/build_server.js index 7af4073ef09d..8d384727bb21 100644 --- a/packages/kit/src/exports/vite/build/build_server.js +++ b/packages/kit/src/exports/vite/build/build_server.js @@ -13,21 +13,21 @@ import { create_node_analyser } from '../static_analysis/index.js'; * @param {import('types').ManifestData} manifest_data * @param {import('vite').Manifest} server_manifest * @param {import('vite').Manifest | null} client_manifest - * @param {import('vite').Rollup.OutputBundle | null} server_bundle + * @param {import('vite').Rollup.RollupOutput['output'] | null} server_chunks * @param {import('vite').Rollup.RollupOutput['output'] | null} client_chunks * @param {import('types').RecursiveRequired} output_config * @param {Map | null, children: string[] }>} static_exports */ -export async function build_server_nodes(out, kit, manifest_data, server_manifest, client_manifest, server_bundle, client_chunks, output_config, static_exports) { +export async function build_server_nodes(out, kit, manifest_data, server_manifest, client_manifest, server_chunks, client_chunks, output_config, static_exports) { mkdirp(`${out}/server/nodes`); mkdirp(`${out}/server/stylesheets`); /** @type {Map} */ const stylesheets_to_inline = new Map(); - if (server_bundle && client_chunks && kit.inlineStyleThreshold > 0) { + if (server_chunks && client_chunks && kit.inlineStyleThreshold > 0) { const client = get_stylesheets(client_chunks); - const server = get_stylesheets(Object.values(server_bundle)); + const server = get_stylesheets(server_chunks); // map server stylesheet name to the client stylesheet name for (const [id, client_stylesheet] of client.stylesheets_used) { diff --git a/packages/kit/src/exports/vite/dev/environment.js b/packages/kit/src/exports/vite/dev/environment.js new file mode 100644 index 000000000000..615cd964e357 --- /dev/null +++ b/packages/kit/src/exports/vite/dev/environment.js @@ -0,0 +1,71 @@ +import path from 'node:path'; + +// `posixify` and `to_fs` are duplicated from utils/filesystem.js to avoid +// the import from `node:fs` which isn't available in Cloudflare's workerd runtime + +/** @param {string} str */ +export function posixify(str) { + return str.replace(/\\/g, '/'); +} + +/** + * Prepend given path with `/@fs` prefix + * @param {string} str + */ +export function to_fs(str) { + str = posixify(str); + return `/@fs${ + // Windows/Linux separation - Windows starts with a drive letter, we need a / in front there + str.startsWith('/') ? '' : '/' + }${str}`; +} + +/** @param {string} id */ +export async function resolve(id) { + // TODO: doesn't work for files symlinked to kit package workspace. Try in new app with node_modules? + const url = id.startsWith('..') ? to_fs(path.posix.resolve(id)) : `/${id}`; + console.log({ + id, + url + }) + + const module = await loud_ssr_load_module(url); + + // TODO: module_node + // const module_node = await vite.moduleGraph.getModuleByUrl(url); + // if (!module_node) throw new Error(`Could not find node for ${url}`); + + // return { module, module_node, url }; + return { module, module_node: '', url }; +} + +/** + * @param {string} url + * @returns {Promise>} + */ +export async function loud_ssr_load_module(url) { + try { + return await import(/* @vite-ignore */ url); + } catch (/** @type {any} */ err) { + // TODO: implement error logging + err; + // const msg = buildErrorMessage(err, [colors.red(`Internal server error: ${err.message}`)]); + + // if (!vite.config.logger.hasErrorLogged(err)) { + // vite.config.logger.error(msg, { error: err }); + // } + + // vite.ws.send({ + // type: 'error', + // err: { + // ...err, + // // these properties are non-enumerable and will + // // not be serialized unless we explicitly include them + // message: err.message, + // stack: err.stack + // } + // }); + + throw err; + } +} diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 818cc09096ef..551a4ba98f11 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -5,7 +5,7 @@ import { URL } from 'node:url'; import { AsyncLocalStorage } from 'node:async_hooks'; import colors from 'kleur'; import sirv from 'sirv'; -import { isCSSRequest, loadEnv, buildErrorMessage } from 'vite'; +import { isCSSRequest, loadEnv, buildErrorMessage, createServerModuleRunner } from 'vite'; import { createReadableStream, getRequest, setResponse } from '../../../exports/node/index.js'; import { installPolyfills } from '../../../exports/node/polyfills.js'; import { coalesce_to_error } from '../../../utils/error.js'; @@ -20,6 +20,7 @@ import { SCHEME } from '../../../utils/url.js'; import { check_feature } from '../../../utils/features.js'; import { escape_html } from '../../../utils/escape.js'; import { create_node_analyser } from '../static_analysis/index.js'; +import { sveltekit_vite_environment } from '../module_ids.js'; const cwd = process.cwd(); // vite-specifc queries that we should skip handling for css urls @@ -29,9 +30,10 @@ const vite_css_query_regex = /(?:\?|&)(?:raw|url|inline)(?:&|$)/; * @param {import('vite').ViteDevServer} vite * @param {import('vite').ResolvedConfig} vite_config * @param {import('types').ValidatedConfig} svelte_config + * @param {import('types').DevEnvironment} dev_environment * @return {Promise void>>} */ -export async function dev(vite, vite_config, svelte_config) { +export async function dev(vite, vite_config, svelte_config, dev_environment) { installPolyfills(); const async_local_storage = new AsyncLocalStorage(); @@ -90,6 +92,18 @@ export async function dev(vite, vite_config, svelte_config) { } } + function invalidate_vite_environment_module() { + for (const environment in vite.environments) { + const module = vite.environments[environment].moduleGraph.getModuleById( + sveltekit_vite_environment + ); + + if (module) { + vite.environments[environment].moduleGraph.invalidateModule(module); + } + } + } + /** @param {string} id */ async function resolve(id) { const url = id.startsWith('..') ? to_fs(path.posix.resolve(id)) : `/${id}`; @@ -105,10 +119,16 @@ export async function dev(vite, vite_config, svelte_config) { /** @type {(file: string) => void} */ let invalidate_page_options; - function update_manifest() { + /** @type {Map | null>} */ + let node_page_options; + + async function update_manifest() { try { ({ manifest_data } = sync.create(svelte_config)); + dev_environment.manifest_data = manifest_data; + invalidate_vite_environment_module(); + if (manifest_error) { manifest_error = null; vite.ws.send({ type: 'full-reload' }); @@ -128,6 +148,8 @@ export async function dev(vite, vite_config, svelte_config) { return; } + node_page_options = new Map(); + const node_analyser = create_node_analyser({ resolve: async (server_node) => { const { module } = await resolve(server_node); @@ -136,177 +158,187 @@ export async function dev(vite, vite_config, svelte_config) { }); invalidate_page_options = node_analyser.invalidate_page_options; - manifest = { - appDir: svelte_config.kit.appDir, - appPath: svelte_config.kit.appDir, - assets: new Set(manifest_data.assets.map((asset) => asset.file)), - mimeTypes: get_mime_lookup(manifest_data), - _: { - client: { - start: `${runtime_base}/client/entry.js`, - app: `${to_fs(svelte_config.kit.outDir)}/generated/client/app.js`, - imports: [], - stylesheets: [], - fonts: [], - uses_env_dynamic_public: true, - nodes: - svelte_config.kit.router.resolution === 'client' - ? undefined - : manifest_data.nodes.map((node, i) => { - if (node.component || node.universal) { - return `${svelte_config.kit.paths.base}${to_fs(svelte_config.kit.outDir)}/generated/client/nodes/${i}.js`; - } - }), - // `css` is not necessary in dev, as the JS file from `nodes` will reference the CSS file - routes: - svelte_config.kit.router.resolution === 'client' - ? undefined - : compact( - manifest_data.routes.map((route) => { - if (!route.page) return; - - return { - id: route.id, - pattern: route.pattern, - params: route.params, - layouts: route.page.layouts.map((l) => - l !== undefined ? [!!manifest_data.nodes[l].server, l] : undefined - ), - errors: route.page.errors, - leaf: [!!manifest_data.nodes[route.page.leaf].server, route.page.leaf] - }; - }) - ) - }, - server_assets: new Proxy( - {}, - { - has: (_, /** @type {string} */ file) => fs.existsSync(from_fs(file)), - get: (_, /** @type {string} */ file) => fs.statSync(from_fs(file)).size - } - ), - nodes: manifest_data.nodes.map((node, index) => { - return async () => { - /** @type {import('types').SSRNode} */ - const result = {}; - result.index = index; - result.universal_id = node.universal; - result.server_id = node.server; - - // these are unused in dev, but it's easier to include them - result.imports = []; - result.stylesheets = []; - result.fonts = []; - - /** @type {import('vite').ModuleNode[]} */ - const module_nodes = []; - - if (node.component) { - result.component = async () => { - const { module_node, module } = await resolve( - /** @type {string} */ (node.component) - ); - - module_nodes.push(module_node); - - return module.default; - }; - } - - if (node.universal) { - const page_options = await node_analyser.get_page_options(node); - if (page_options?.ssr === false) { - result.universal = page_options; - } else { - // TODO: explain why the file was loaded on the server if we fail to load it - const { module, module_node } = await resolve(node.universal); - module_nodes.push(module_node); - result.universal = module; - } - } - - if (node.server) { - const { module } = await resolve(node.server); - result.server = module; - } - - // in dev we inline all styles to avoid FOUC. this gets populated lazily so that - // components/stylesheets loaded via import() during `load` are included - result.inline_styles = async () => { - /** @type {Set} */ - const deps = new Set(); - - for (const module_node of module_nodes) { - await find_deps(vite, module_node, deps); - } - - /** @type {Record} */ - const styles = {}; - - for (const dep of deps) { - if (isCSSRequest(dep.url) && !vite_css_query_regex.test(dep.url)) { - const inlineCssUrl = dep.url.includes('?') - ? dep.url.replace('?', '?inline&') - : dep.url + '?inline'; - try { - const mod = await vite.ssrLoadModule(inlineCssUrl); - styles[dep.url] = mod.default; - } catch { - // this can happen with dynamically imported modules, I think - // because the Vite module graph doesn't distinguish between - // static and dynamic imports? TODO investigate, submit fix - } - } - } - - return styles; - }; - - return result; - }; - }), - prerendered_routes: new Set(), - routes: compact( - manifest_data.routes.map((route) => { - if (!route.page && !route.endpoint) return null; - - const endpoint = route.endpoint; - - return { - id: route.id, - pattern: route.pattern, - params: route.params, - page: route.page, - endpoint: endpoint - ? async () => { - const url = path.resolve(cwd, endpoint.file); - return await loud_ssr_load_module(url); - } - : null, - endpoint_id: endpoint?.file - }; - }) - ), - matchers: async () => { - /** @type {Record} */ - const matchers = {}; - - for (const key in manifest_data.matchers) { - const file = manifest_data.matchers[key]; - const url = path.resolve(cwd, file); - const module = await vite.ssrLoadModule(url, { fixStacktrace: true }); - - if (module.match) { - matchers[key] = module.match; - } else { - throw new Error(`${file} does not export a \`match\` function`); - } - } - - return matchers; - } + // vite.environments.ssr.hot.send('', {}) + // vite.environments.ssr.hot.on() + + for (const node of manifest_data.nodes) { + if (node.universal) { + const page_options = await node_analyser.get_page_options(node); + node_page_options.set(node.universal, page_options); } - }; + } + + // manifest = { + // appDir: svelte_config.kit.appDir, + // appPath: svelte_config.kit.appDir, + // assets: new Set(manifest_data.assets.map((asset) => asset.file)), + // mimeTypes: get_mime_lookup(manifest_data), + // _: { + // client: { + // start: `${runtime_base}/client/entry.js`, + // app: `${to_fs(svelte_config.kit.outDir)}/generated/client/app.js`, + // imports: [], + // stylesheets: [], + // fonts: [], + // uses_env_dynamic_public: true, + // nodes: + // svelte_config.kit.router.resolution === 'client' + // ? undefined + // : manifest_data.nodes.map((node, i) => { + // if (node.component || node.universal) { + // return `${svelte_config.kit.paths.base}${to_fs(svelte_config.kit.outDir)}/generated/client/nodes/${i}.js`; + // } + // }), + // // `css` is not necessary in dev, as the JS file from `nodes` will reference the CSS file + // routes: + // svelte_config.kit.router.resolution === 'client' + // ? undefined + // : compact( + // manifest_data.routes.map((route) => { + // if (!route.page) return; + + // return { + // id: route.id, + // pattern: route.pattern, + // params: route.params, + // layouts: route.page.layouts.map((l) => + // l !== undefined ? [!!manifest_data.nodes[l].server, l] : undefined + // ), + // errors: route.page.errors, + // leaf: [!!manifest_data.nodes[route.page.leaf].server, route.page.leaf] + // }; + // }) + // ) + // }, + // server_assets: new Proxy( + // {}, + // { + // has: (_, /** @type {string} */ file) => fs.existsSync(from_fs(file)), + // get: (_, /** @type {string} */ file) => fs.statSync(from_fs(file)).size + // } + // ), + // nodes: manifest_data.nodes.map((node, index) => { + // return async () => { + // /** @type {import('types').SSRNode} */ + // const result = {}; + // result.index = index; + // result.universal_id = node.universal; + // result.server_id = node.server; + + // // these are unused in dev, but it's easier to include them + // result.imports = []; + // result.stylesheets = []; + // result.fonts = []; + + // /** @type {import('vite').ModuleNode[]} */ + // const module_nodes = []; + + // if (node.component) { + // result.component = async () => { + // const { module_node, module } = await resolve( + // /** @type {string} */ (node.component) + // ); + + // module_nodes.push(module_node); + + // return module.default; + // }; + // } + + // if (node.universal) { + // const page_options = await node_analyser.get_page_options(node); + // if (page_options?.ssr === false) { + // result.universal = page_options; + // } else { + // // TODO: explain why the file was loaded on the server if we fail to load it + // const { module, module_node } = await resolve(node.universal); + // module_nodes.push(module_node); + // result.universal = module; + // } + // } + + // if (node.server) { + // const { module } = await resolve(node.server); + // result.server = module; + // } + + // // in dev we inline all styles to avoid FOUC. this gets populated lazily so that + // // components/stylesheets loaded via import() during `load` are included + // result.inline_styles = async () => { + // /** @type {Set} */ + // const deps = new Set(); + + // for (const module_node of module_nodes) { + // await find_deps(vite, module_node, deps); + // } + + // /** @type {Record} */ + // const styles = {}; + + // for (const dep of deps) { + // if (isCSSRequest(dep.url) && !vite_css_query_regex.test(dep.url)) { + // const inlineCssUrl = dep.url.includes('?') + // ? dep.url.replace('?', '?inline&') + // : dep.url + '?inline'; + // try { + // const mod = await vite.ssrLoadModule(inlineCssUrl); + // styles[dep.url] = mod.default; + // } catch { + // // this can happen with dynamically imported modules, I think + // // because the Vite module graph doesn't distinguish between + // // static and dynamic imports? TODO investigate, submit fix + // } + // } + // } + + // return styles; + // }; + + // return result; + // }; + // }), + // prerendered_routes: new Set(), + // routes: compact( + // manifest_data.routes.map((route) => { + // if (!route.page && !route.endpoint) return null; + + // const endpoint = route.endpoint; + + // return { + // id: route.id, + // pattern: route.pattern, + // params: route.params, + // page: route.page, + // endpoint: endpoint + // ? async () => { + // const url = path.resolve(cwd, endpoint.file); + // return await loud_ssr_load_module(url); + // } + // : null, + // endpoint_id: endpoint?.file + // }; + // }) + // ), + // matchers: async () => { + // /** @type {Record} */ + // const matchers = {}; + + // for (const key in manifest_data.matchers) { + // const file = manifest_data.matchers[key]; + // const url = path.resolve(cwd, file); + // const module = await vite.ssrLoadModule(url, { fixStacktrace: true }); + + // if (module.match) { + // matchers[key] = module.match; + // } else { + // throw new Error(`${file} does not export a \`match\` function`); + // } + // } + + // return matchers; + // } + // } + // }; } /** @param {Error} error */ @@ -320,7 +352,7 @@ export async function dev(vite, vite_config, svelte_config) { return error.stack; } - update_manifest(); + await update_manifest(); /** * @param {string} event @@ -439,7 +471,8 @@ export async function dev(vite, vite_config, svelte_config) { }); const env = loadEnv(vite_config.mode, svelte_config.kit.env.dir, ''); - const emulator = await svelte_config.kit.adapter?.emulate?.(); + dev_environment.env = env; + // const emulator = await svelte_config.kit.adapter?.emulate?.(); return () => { const serve_static_middleware = vite.middlewares.stack.find( @@ -451,129 +484,138 @@ export async function dev(vite, vite_config, svelte_config) { // serving routes with those names. See https://github.com/vitejs/vite/issues/7363 remove_static_middlewares(vite.middlewares); - vite.middlewares.use(async (req, res) => { - // Vite's base middleware strips out the base path. Restore it - const original_url = req.url; - req.url = req.originalUrl; - try { - const base = `${vite.config.server.https ? 'https' : 'http'}://${ - req.headers[':authority'] || req.headers.host - }`; - - const decoded = decodeURI(new URL(base + req.url).pathname); - const file = posixify(path.resolve(decoded.slice(svelte_config.kit.paths.base.length + 1))); - const is_file = fs.existsSync(file) && !fs.statSync(file).isDirectory(); - const allowed = - !vite_config.server.fs.strict || - vite_config.server.fs.allow.some((dir) => file.startsWith(dir)); - - if (is_file && allowed) { - req.url = original_url; - // @ts-expect-error - serve_static_middleware.handle(req, res); - return; - } - - if (!decoded.startsWith(svelte_config.kit.paths.base)) { - return not_found(req, res, svelte_config.kit.paths.base); - } - - if (decoded === svelte_config.kit.paths.base + '/service-worker.js') { - const resolved = resolve_entry(svelte_config.kit.files.serviceWorker); - - if (resolved) { - res.writeHead(200, { - 'content-type': 'application/javascript' - }); - res.end(`import '${svelte_config.kit.paths.base}${to_fs(resolved)}';`); - } else { - res.writeHead(404); - res.end('not found'); - } - - return; - } - - // we have to import `Server` before calling `set_assets` - const { Server } = /** @type {import('types').ServerModule} */ ( - await vite.ssrLoadModule(`${runtime_base}/server/index.js`, { fixStacktrace: true }) - ); - - const { set_fix_stack_trace } = await vite.ssrLoadModule( - `${runtime_base}/shared-server.js` - ); - set_fix_stack_trace(fix_stack_trace); - - const { set_assets } = await vite.ssrLoadModule('__sveltekit/paths'); - set_assets(assets); - - const server = new Server(manifest); - - await server.init({ - env, - read: (file) => createReadableStream(from_fs(file)) - }); - - const request = await getRequest({ - base, - request: req - }); - - if (manifest_error) { - console.error(colors.bold().red(manifest_error.message)); - - const error_page = load_error_page(svelte_config); - - /** @param {{ status: number; message: string }} opts */ - const error_template = ({ status, message }) => { - return error_page - .replace(/%sveltekit\.status%/g, String(status)) - .replace(/%sveltekit\.error\.message%/g, escape_html(message)); - }; - - res.writeHead(500, { - 'Content-Type': 'text/html; charset=utf-8' - }); - res.end( - error_template({ status: 500, message: manifest_error.message ?? 'Invalid routes' }) - ); - - return; - } - - const rendered = await server.respond(request, { - getClientAddress: () => { - const { remoteAddress } = req.socket; - if (remoteAddress) return remoteAddress; - throw new Error('Could not determine clientAddress'); - }, - read: (file) => { - if (file in manifest._.server_assets) { - return fs.readFileSync(from_fs(file)); - } - - return fs.readFileSync(path.join(svelte_config.kit.files.assets, file)); - }, - before_handle: (event, config, prerender) => { - async_local_storage.enterWith({ event, config, prerender }); - }, - emulator - }); - - if (rendered.status === 404) { - // @ts-expect-error - serve_static_middleware.handle(req, res, () => { - void setResponse(res, rendered); - }); - } else { - void setResponse(res, rendered); - } - } catch (e) { - const error = coalesce_to_error(e); - res.statusCode = 500; - res.end(fix_stack_trace(error)); + vite.middlewares.stack.unshift({ + route: '', + /** @type {import('vite').Connect.NextHandleFunction} */ + handle: (req, _, next) => { + dev_environment.remote_address = req.socket.remoteAddress; + next(); } }); + + // vite.middlewares.use(async (req, res) => { + // // Vite's base middleware strips out the base path. Restore it + // const original_url = req.url; + // req.url = req.originalUrl; + // try { + // const base = `${vite.config.server.https ? 'https' : 'http'}://${ + // req.headers[':authority'] || req.headers.host + // }`; + + // const decoded = decodeURI(new URL(base + req.url).pathname); + // const file = posixify(path.resolve(decoded.slice(svelte_config.kit.paths.base.length + 1))); + // const is_file = fs.existsSync(file) && !fs.statSync(file).isDirectory(); + // const allowed = + // !vite_config.server.fs.strict || + // vite_config.server.fs.allow.some((dir) => file.startsWith(dir)); + + // if (is_file && allowed) { + // req.url = original_url; + // // @ts-expect-error + // serve_static_middleware.handle(req, res); + // return; + // } + + // if (!decoded.startsWith(svelte_config.kit.paths.base)) { + // return not_found(req, res, svelte_config.kit.paths.base); + // } + + // if (decoded === svelte_config.kit.paths.base + '/service-worker.js') { + // const resolved = resolve_entry(svelte_config.kit.files.serviceWorker); + + // if (resolved) { + // res.writeHead(200, { + // 'content-type': 'application/javascript' + // }); + // res.end(`import '${svelte_config.kit.paths.base}${to_fs(resolved)}';`); + // } else { + // res.writeHead(404); + // res.end('not found'); + // } + + // return; + // } + + // // we have to import `Server` before calling `set_assets` + // const { Server } = /** @type {import('types').ServerModule} */ ( + // await vite.ssrLoadModule(`${runtime_base}/server/index.js`, { fixStacktrace: true }) + // ); + + // const { set_fix_stack_trace } = await vite.ssrLoadModule( + // `${runtime_base}/shared-server.js` + // ); + // set_fix_stack_trace(fix_stack_trace); + + // const { set_assets } = await vite.ssrLoadModule('__sveltekit/paths'); + // set_assets(assets); + + // const server = new Server(manifest); + + // await server.init({ + // env, + // read: (file) => createReadableStream(from_fs(file)) + // }); + + // const request = await getRequest({ + // base, + // request: req + // }); + + // if (manifest_error) { + // console.error(colors.bold().red(manifest_error.message)); + + // const error_page = load_error_page(svelte_config); + + // /** @param {{ status: number; message: string }} opts */ + // const error_template = ({ status, message }) => { + // return error_page + // .replace(/%sveltekit\.status%/g, String(status)) + // .replace(/%sveltekit\.error\.message%/g, escape_html(message)); + // }; + + // res.writeHead(500, { + // 'Content-Type': 'text/html; charset=utf-8' + // }); + // res.end( + // error_template({ status: 500, message: manifest_error.message ?? 'Invalid routes' }) + // ); + + // return; + // } + + // const rendered = await server.respond(request, { + // getClientAddress: () => { + // const { remoteAddress } = req.socket; + // if (remoteAddress) return remoteAddress; + // throw new Error('Could not determine clientAddress'); + // }, + // read: (file) => { + // if (file in manifest._.server_assets) { + // return fs.readFileSync(from_fs(file)); + // } + + // return fs.readFileSync(path.join(svelte_config.kit.files.assets, file)); + // }, + // before_handle: (event, config, prerender) => { + // async_local_storage.enterWith({ event, config, prerender }); + // }, + // emulator + // }); + + // if (rendered.status === 404) { + // // @ts-expect-error + // serve_static_middleware.handle(req, res, () => { + // void setResponse(res, rendered); + // }); + // } else { + // void setResponse(res, rendered); + // } + // } catch (e) { + // const error = coalesce_to_error(e); + // res.statusCode = 500; + // res.end(fix_stack_trace(error)); + // } + // }); }; } diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index 934a2beaa045..b910ba407298 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -4,11 +4,19 @@ import process from 'node:process'; import colors from 'kleur'; -import { copy, mkdirp, posixify, read, resolve_entry, rimraf } from '../../utils/filesystem.js'; +import { + copy, + mkdirp, + posixify, + read, + resolve_entry, + rimraf, + to_fs +} from '../../utils/filesystem.js'; import { create_static_module, create_dynamic_module } from '../../core/env.js'; import * as sync from '../../core/sync/sync.js'; import { create_assets } from '../../core/sync/create_manifest_data/index.js'; -import { runtime_directory, logger } from '../../core/utils.js'; +import { runtime_directory, logger, get_mime_lookup, runtime_base } from '../../core/utils.js'; import { load_config } from '../../core/config/index.js'; import { generate_manifest } from '../../core/generate_manifest/index.js'; import { build_server_nodes } from './build/build_server.js'; @@ -32,13 +40,16 @@ import { service_worker, sveltekit_environment, sveltekit_paths, - sveltekit_server + sveltekit_server, + sveltekit_vite_environment } from './module_ids.js'; import { import_peer } from '../../utils/import.js'; import { compact } from '../../utils/array.js'; const cwd = process.cwd(); +const dev_environment = /** @type {import('types').DevEnvironment} */ ({}); + /** @type {import('./types.js').EnforcedConfig} */ const enforced_config = { appType: true, @@ -155,15 +166,12 @@ export async function sveltekit() { ...svelte_config.vitePlugin }; + /** @type {import('@sveltejs/vite-plugin-svelte')} */ const { svelte } = await import_peer('@sveltejs/vite-plugin-svelte'); return [...svelte(vite_plugin_svelte_options), ...(await kit({ svelte_config }))]; } -// These variables live outside the `kit()` function because it is re-invoked by each Vite build - -let secondary_build_started = false; - /** @type {import('types').ManifestData} */ let manifest_data; @@ -309,7 +317,6 @@ async function kit({ svelte_config }) { if (is_build) { if (!new_config.build) new_config.build = {}; - new_config.build.ssr = !secondary_build_started; new_config.define = { __SVELTEKIT_ADAPTER_NAME__: s(kit.adapter?.name), @@ -319,10 +326,6 @@ async function kit({ svelte_config }) { __SVELTEKIT_EMBEDDED__: kit.embedded ? 'true' : 'false', __SVELTEKIT_CLIENT_ROUTING__: kit.router.resolution === 'client' ? 'true' : 'false' }; - - if (!secondary_build_started) { - manifest_data = sync.all(svelte_config, config_env.mode).manifest_data; - } } else { new_config.define = { __SVELTEKIT_APP_VERSION_POLL_INTERVAL__: '0', @@ -337,6 +340,17 @@ async function kit({ svelte_config }) { 'cookie', 'set-cookie-parser' ]; + + // TODO: vite-plugin-cloudflare doesn't allow `ssr.external` but VPS and Kit are using it + /** @type {NonNullable} */ (new_config.ssr).external = + undefined; + // only needed because of vite-plugin-cloudflare + // TODO: remove when https://github.com/cloudflare/workers-sdk/issues/9036#issuecomment-2825271144 is fixed + /** @type {NonNullable} */ (new_config.ssr).noExternal = + undefined; + + // vite-plugin-svelte is setting this but it doesn't work with vite-plugin-cloudflare + /** @type {NonNullable} */ (new_config.resolve).external = undefined; } warn_overridden_config(config, new_config); @@ -399,14 +413,14 @@ async function kit({ svelte_config }) { } }, - load(id, options) { - const browser = !options?.ssr; + load(id) { + const browser = this.environment.config.consumer === 'client'; const global = is_build ? `globalThis.__sveltekit_${version_hash}` : 'globalThis.__sveltekit_dev'; - if (options?.ssr === false && process.env.TEST !== 'true') { + if (this.environment.config.consumer === 'client' && process.env.TEST !== 'true') { const normalized_cwd = vite.normalizePath(cwd); const normalized_lib = vite.normalizePath(kit.files.lib); if ( @@ -541,6 +555,182 @@ Tips: } `; } + + case sveltekit_vite_environment: { + const { manifest_data, env, remote_address } = dev_environment; + + return dedent` + import path from "node:path"; + import { resolve, loud_ssr_load_module } from "${runtime_base}/../exports/vite/dev/environment.js"; + + const cwd = ${s(cwd)}; + + export const manifest = { + appDir: ${s(svelte_config.kit.appDir)}, + appPath: ${s(svelte_config.kit.appDir)}, + assets: new Set(${s(manifest_data.assets.map((asset) => asset.file))}), + mimeTypes: ${s(get_mime_lookup(manifest_data))}, + _: { + client: { + start: "${runtime_base}/client/entry.js", + app: "${to_fs(svelte_config.kit.outDir)}/generated/client/app.js", + imports: [], + stylesheets: [], + fonts: [], + uses_env_dynamic_public: true, + nodes: ${ + svelte_config.kit.router.resolution === 'client' + ? 'undefined' + : s( + manifest_data.nodes.map((node, i) => { + if (node.component || node.universal) { + return `${svelte_config.kit.paths.base}${to_fs(svelte_config.kit.outDir)}/generated/client/nodes/${i}.js`; + } + }) + ) + }, + routes: ${ + svelte_config.kit.router.resolution === 'client' + ? 'undefined' + : s( + compact( + manifest_data.routes.map((route) => { + if (!route.page) return; + + return { + id: route.id, + pattern: route.pattern, + params: route.params, + layouts: route.page.layouts.map((l) => + l !== undefined ? [!!manifest_data.nodes[l].server, l] : undefined + ), + errors: route.page.errors, + leaf: [ + !!manifest_data.nodes[route.page.leaf].server, + route.page.leaf + ] + }; + }) + ) + ) + } + }, + // TODO: fs only works in Node.js. try using import.meta.hot and serialise results + server_assets: new Proxy( + {}, + { + has: (_, file) => true, + get: (_, file) => 1 + } + ), + nodes: [${manifest_data.nodes + .map((node, index) => { + const component = s(node.component); + + return dedent` + async () => { + const result = { + index: ${s(index)}, + universal_id: ${s(node.universal)}, + server_id: ${s(node.server)}, + imports: [], + stylesheets: [], + fonts: [] + }; + + const module_nodes = []; + + if (${component}) { + result.component = async () => { + const { module_node, module } = await resolve(${component}); + module_nodes.push(module_node); + return module.default; + }; + } + + if (result.universal_id) { + const { module, module_node } = await resolve(result.universal_id); + module_nodes.push(module_node); + result.universal = module; + // TODO: can't stringify node because it's an object with other object references. use import.meta.hot ? + // const page_options = await node_analyser.get_page_options(node); + // if (page_options?.ssr === false) { + // result.universal = page_options; + // } else { + // // TODO: explain why the file was loaded on the server if we fail to load it + // const { module, module_node } = await resolve(result.universal_id); + // module_nodes.push(module_node); + // result.universal = module; + // } + } + + if (result.server_id) { + const { module } = await resolve(result.server_id); + result.server = module; + } + + // TODO: result.inline_styles + result.inline_styles = async () => ({}); + + return result; + } + `; + }) + .join(',\n')} + ], + prerendered_routes: new Set(), + routes: [${compact( + manifest_data.routes.map((route) => { + if (!route.page && !route.endpoint) return null; + + const endpoint = route.endpoint; + + return dedent` + { + id: ${s(route.id)}, + pattern: /${route.pattern.source}/, + params: ${s(route.params)}, + page: ${s(route.page)}, + endpoint: ${ + endpoint + ? `async () => { + const url = path.resolve(cwd, ${s(endpoint.file)}); + return await loud_ssr_load_module(url); + }` + : 'null' + }, + endpoint_id: ${s(endpoint?.file)} + } + `; + }) + ).join(',\n')}], + matchers: async () => { + const matchers = {}; + + for (const [key, file] of ${s(Object.entries(manifest_data.matchers))}) { + const url = path.resolve(cwd, file); + const module = await import(/* @vite-ignore */ url); + if (module.match) { + matchers[key] = module.match; + } else { + throw new Error(\`\${file} does not export a \\\`match\\\` function\`) + } + } + + return matchers; + } + } + } + + export const env = ${s(env)}; + + export const remote_address = ${s(remote_address)}; + + export const base_path = ${s(svelte_config.kit.paths.base)}; + + export const prerendered = manifest._.prerendered_routes; + `; + } } } }; @@ -556,7 +746,7 @@ Tips: writeBundle: { sequential: true, handler(_options) { - if (vite_config.build.ssr) return; + if (this.environment.config.consumer === 'server') return; const guard = module_guard(this, { cwd: vite.normalizePath(process.cwd()), @@ -582,59 +772,62 @@ Tips: * Build the SvelteKit-provided Vite config to be merged with the user's vite.config.js file. * @see https://vitejs.dev/guide/api-plugin.html#config */ - config(config) { + config(config, env_config) { /** @type {import('vite').UserConfig} */ let new_config; if (is_build) { - const ssr = /** @type {boolean} */ (config.build?.ssr); const prefix = `${kit.appDir}/immutable`; /** @type {Record} */ - const input = {}; + const server_input = { + index: `${runtime_directory}/server/index.js`, + internal: `${kit.outDir}/generated/server/internal.js` + }; + + manifest_data = sync.all(svelte_config, env_config.mode).manifest_data; - if (ssr) { - input.index = `${runtime_directory}/server/index.js`; - input.internal = `${kit.outDir}/generated/server/internal.js`; + // add entry points for every endpoint... + manifest_data.routes.forEach((route) => { + if (route.endpoint) { + const resolved = path.resolve(route.endpoint.file); + const relative = decodeURIComponent(path.relative(kit.files.routes, resolved)); + const name = posixify(path.join('entries/endpoints', relative.replace(/\.js$/, ''))); + server_input[name] = resolved; + } + }); - // add entry points for every endpoint... - manifest_data.routes.forEach((route) => { - if (route.endpoint) { - const resolved = path.resolve(route.endpoint.file); + // ...and every component used by pages... + manifest_data.nodes.forEach((node) => { + for (const file of [node.component, node.universal, node.server]) { + if (file) { + const resolved = path.resolve(file); const relative = decodeURIComponent(path.relative(kit.files.routes, resolved)); - const name = posixify(path.join('entries/endpoints', relative.replace(/\.js$/, ''))); - input[name] = resolved; - } - }); - // ...and every component used by pages... - manifest_data.nodes.forEach((node) => { - for (const file of [node.component, node.universal, node.server]) { - if (file) { - const resolved = path.resolve(file); - const relative = decodeURIComponent(path.relative(kit.files.routes, resolved)); - - const name = relative.startsWith('..') - ? posixify(path.join('entries/fallbacks', path.basename(file))) - : posixify(path.join('entries/pages', relative.replace(/\.js$/, ''))); - input[name] = resolved; - } + const name = relative.startsWith('..') + ? posixify(path.join('entries/fallbacks', path.basename(file))) + : posixify(path.join('entries/pages', relative.replace(/\.js$/, ''))); + server_input[name] = resolved; } - }); + } + }); - // ...and every matcher - Object.entries(manifest_data.matchers).forEach(([key, file]) => { - const name = posixify(path.join('entries/matchers', key)); - input[name] = path.resolve(file); - }); - } else if (svelte_config.kit.output.bundleStrategy !== 'split') { - input['bundle'] = `${runtime_directory}/client/bundle.js`; + // ...and every matcher + Object.entries(manifest_data.matchers).forEach(([key, file]) => { + const name = posixify(path.join('entries/matchers', key)); + server_input[name] = path.resolve(file); + }); + + /** @type {Record} */ + const client_input = {}; + if (svelte_config.kit.output.bundleStrategy !== 'split') { + client_input['bundle'] = `${runtime_directory}/client/bundle.js`; } else { - input['entry/start'] = `${runtime_directory}/client/entry.js`; - input['entry/app'] = `${kit.outDir}/generated/client-optimized/app.js`; + client_input['entry/start'] = `${runtime_directory}/client/entry.js`; + client_input['entry/app'] = `${kit.outDir}/generated/client-optimized/app.js`; manifest_data.nodes.forEach((node, i) => { if (node.component || node.universal) { - input[`nodes/${i}`] = `${kit.outDir}/generated/client-optimized/nodes/${i}.js`; + client_input[`nodes/${i}`] = `${kit.outDir}/generated/client-optimized/nodes/${i}.js`; } }); } @@ -646,32 +839,26 @@ Tips: // E.g. Vite generates `new URL('/asset.png', import.meta).href` for a relative path vs just '/asset.png'. // That's larger and takes longer to run and also causes an HTML diff between SSR and client // causing us to do a more expensive hydration check. - const client_base = - kit.paths.relative !== false || kit.paths.assets ? './' : kit.paths.base || '/'; + // const client_base = + // kit.paths.relative !== false || kit.paths.assets ? './' : kit.paths.base || '/'; - const inline = !ssr && svelte_config.kit.output.bundleStrategy === 'inline'; - const split = ssr || svelte_config.kit.output.bundleStrategy === 'split'; + const inline = svelte_config.kit.output.bundleStrategy === 'inline'; new_config = { - base: ssr ? assets_base(kit) : client_base, + appType: 'custom', + // TODO: Vite doesn't support different base paths for different environments + // base: ssr ? assets_base(kit) : client_base, + base: assets_base(kit), build: { - copyPublicDir: !ssr, - cssCodeSplit: svelte_config.kit.output.bundleStrategy !== 'inline', + cssCodeSplit: !inline, cssMinify: initial_config.build?.minify == null ? true : !!initial_config.build.minify, - // don't use the default name to avoid collisions with 'static/manifest.json' - manifest: '.vite/manifest.json', // TODO: remove this after bumping peer dep to vite 5 - outDir: `${out}/${ssr ? 'server' : 'client'}`, + manifest: true, rollupOptions: { - input: inline ? input['bundle'] : input, output: { - format: inline ? 'iife' : 'esm', name: `__sveltekit_${version_hash}.app`, - entryFileNames: ssr ? '[name].js' : `${prefix}/[name].[hash].${ext}`, - chunkFileNames: ssr ? 'chunks/[name].js' : `${prefix}/chunks/[hash].${ext}`, assetFileNames: `${prefix}/assets/[name].[hash][extname]`, hoistTransitiveImports: false, sourcemapIgnoreList, - manualChunks: split ? undefined : () => 'bundle', inlineDynamicImports: false }, preserveEntrySignatures: 'strict', @@ -690,9 +877,308 @@ Tips: handler(warning); } + } + }, + environments: { + ssr: { + build: { + copyPublicDir: false, + outDir: `${out}/server`, + target: 'node18.13', + emitAssets: true, + rollupOptions: { + input: server_input, + output: { + entryFileNames: '[name].js', + chunkFileNames: 'chunks/[name].js' + } + } + } }, - ssrEmitAssets: true, - target: ssr ? 'node18.13' : undefined + client: { + build: { + outDir: `${out}/client`, + rollupOptions: { + input: inline ? client_input['bundle'] : client_input, + preserveEntrySignatures: 'strict', + output: { + format: inline ? 'iife' : 'esm', + entryFileNames: `${prefix}/[name].[hash].${ext}`, + chunkFileNames: `${prefix}/chunks/[hash].${ext}`, + manualChunks: + svelte_config.kit.output.bundleStrategy === 'split' + ? undefined + : () => 'bundle' + } + } + } + } + }, + builder: { + buildApp: async (builder) => { + // clears the output directories + if (!builder.config.build.watch) { + rimraf(out); + } + mkdirp(out); + + const { output: server_chunks } = /** @type {import('vite').Rollup.RollupOutput} */ ( + await builder.build(builder.environments.ssr) + ); + + const verbose = vite_config.logLevel === 'info'; + const log = logger({ verbose }); + + /** @type {import('vite').Manifest} */ + const server_manifest = JSON.parse(read(`${out}/server/.vite/manifest.json`)); + + /** @type {import('types').BuildData} */ + const build_data = { + app_dir: kit.appDir, + app_path: `${kit.paths.base.slice(1)}${kit.paths.base ? '/' : ''}${kit.appDir}`, + manifest_data, + out_dir: out, + service_worker: service_worker_entry_file ? 'service-worker.js' : null, // TODO make file configurable? + client: null, + server_manifest + }; + + const manifest_path = `${out}/server/manifest-full.js`; + fs.writeFileSync( + manifest_path, + `export const manifest = ${generate_manifest({ + build_data, + prerendered: [], + relative_path: '.', + routes: manifest_data.routes + })};\n` + ); + + log.info('Analysing routes'); + + const { metadata, static_exports } = await analyse({ + hash: kit.router.type === 'hash', + manifest_path, + manifest_data, + server_manifest, + tracked_features, + env: { ...env.private, ...env.public }, + out, + output_config: svelte_config.output + }); + + log.info('Building app'); + + // create client build + write_client_manifest( + kit, + manifest_data, + `${kit.outDir}/generated/client-optimized`, + metadata.nodes + ); + + const { output: client_chunks } = /** @type {import('vite').Rollup.RollupOutput} */ ( + await builder.build(builder.environments.client) + ); + + copy( + `${out}/server/${kit.appDir}/immutable/assets`, + `${out}/client/${kit.appDir}/immutable/assets` + ); + + /** @type {import('vite').Manifest} */ + const client_manifest = JSON.parse(read(`${out}/client/.vite/manifest.json`)); + + /** + * @param {string} entry + * @param {boolean} [add_dynamic_css] + */ + const deps_of = (entry, add_dynamic_css = false) => + find_deps(client_manifest, posixify(path.relative('.', entry)), add_dynamic_css); + + if (svelte_config.kit.output.bundleStrategy === 'split') { + const start = deps_of(`${runtime_directory}/client/entry.js`); + const app = deps_of(`${kit.outDir}/generated/client-optimized/app.js`); + + build_data.client = { + start: start.file, + app: app.file, + imports: [...start.imports, ...app.imports], + stylesheets: [...start.stylesheets, ...app.stylesheets], + fonts: [...start.fonts, ...app.fonts], + uses_env_dynamic_public: client_chunks.some( + (chunk) => chunk.type === 'chunk' && chunk.modules[env_dynamic_public] + ) + }; + + // In case of server-side route resolution, we create a purpose-built route manifest that is + // similar to that on the client, with as much information computed upfront so that we + // don't need to include any code of the actual routes in the server bundle. + if (svelte_config.kit.router.resolution === 'server') { + const nodes = manifest_data.nodes.map((node, i) => { + if (node.component || node.universal) { + const entry = `${kit.outDir}/generated/client-optimized/nodes/${i}.js`; + const deps = deps_of(entry, true); + const file = resolve_symlinks( + client_manifest, + `${kit.outDir}/generated/client-optimized/nodes/${i}.js` + ).chunk.file; + + return { file, css: deps.stylesheets }; + } + }); + build_data.client.nodes = nodes.map((node) => node?.file); + build_data.client.css = nodes.map((node) => node?.css); + + build_data.client.routes = compact( + manifest_data.routes.map((route) => { + if (!route.page) return; + + return { + id: route.id, + pattern: route.pattern, + params: route.params, + layouts: route.page.layouts.map((l) => + l !== undefined ? [metadata.nodes[l].has_server_load, l] : undefined + ), + errors: route.page.errors, + leaf: [metadata.nodes[route.page.leaf].has_server_load, route.page.leaf] + }; + }) + ); + } + } else { + const start = deps_of(`${runtime_directory}/client/bundle.js`); + + build_data.client = { + start: start.file, + imports: start.imports, + stylesheets: start.stylesheets, + fonts: start.fonts, + uses_env_dynamic_public: client_chunks.some( + (chunk) => chunk.type === 'chunk' && chunk.modules[env_dynamic_public] + ) + }; + + if (svelte_config.kit.output.bundleStrategy === 'inline') { + const style = /** @type {import('vite').Rollup.OutputAsset} */ ( + client_chunks.find( + (chunk) => + chunk.type === 'asset' && + chunk.names.length === 1 && + chunk.names[0] === 'style.css' + ) + ); + + build_data.client.inline = { + script: read(`${out}/client/${start.file}`), + style: /** @type {string | undefined} */ (style?.source) + }; + } + } + + // regenerate manifest now that we have client entry... + fs.writeFileSync( + manifest_path, + `export const manifest = ${generate_manifest({ + build_data, + prerendered: [], + relative_path: '.', + routes: manifest_data.routes + })};\n` + ); + + // regenerate nodes with the client manifest... + await build_server_nodes( + out, + kit, + manifest_data, + server_manifest, + client_manifest, + server_chunks, + client_chunks, + svelte_config.kit.output, + static_exports + ); + + // ...and prerender + const { prerendered, prerender_map } = await prerender({ + hash: kit.router.type === 'hash', + out, + manifest_path, + metadata, + verbose, + env: { ...env.private, ...env.public } + }); + + // generate a new manifest that doesn't include prerendered pages + fs.writeFileSync( + `${out}/server/manifest.js`, + `export const manifest = ${generate_manifest({ + build_data, + prerendered: prerendered.paths, + relative_path: '.', + routes: manifest_data.routes.filter( + (route) => prerender_map.get(route.id) !== true + ) + })};\n` + ); + + if (service_worker_entry_file) { + if (kit.paths.assets) { + throw new Error('Cannot use service worker alongside config.kit.paths.assets'); + } + + log.info('Building service worker'); + + // TODO: migrate service worker to environment? + await build_service_worker( + out, + kit, + { + ...vite_config, + build: { + ...vite_config.build, + minify: initial_config.build?.minify ?? true + } + }, + manifest_data, + service_worker_entry_file, + prerendered, + client_manifest + ); + } + + // we need to defer this to closeBundle, so that adapters copy files + // created by other Vite plugins + finalise = async () => { + console.log( + `\nRun ${colors + .bold() + .cyan('npm run preview')} to preview your production build locally.` + ); + + if (kit.adapter) { + const { adapt } = await import('../../core/adapt/index.js'); + await adapt( + svelte_config, + build_data, + metadata, + prerendered, + prerender_map, + log, + vite_config + ); + } else { + console.log(colors.bold().yellow('\nNo adapter specified')); + + const link = colors.bold().cyan('https://svelte.dev/docs/kit/adapters'); + console.log( + `See ${link} to learn how to configure your app to run on the platform of your choosing` + ); + } + }; + } }, publicDir: kit.files.assets, worker: { @@ -721,6 +1207,11 @@ Tips: }; } + // TODO: Cloudflare Vite plugin doesn't allow `ssr.external` but VPS and Kit are using it + /** @type {import('vite').SSROptions} */ (config.ssr).external = undefined; + // TODO: see https://github.com/cloudflare/workers-sdk/issues/9036#issuecomment-2825271144 + /** @type {import('vite').SSROptions} */ (config.ssr).noExternal = undefined; + warn_overridden_config(config, new_config); return new_config; @@ -731,7 +1222,7 @@ Tips: * @see https://vitejs.dev/guide/api-plugin.html#configureserver */ async configureServer(vite) { - return await dev(vite, vite_config, svelte_config); + return await dev(vite, vite_config, svelte_config, dev_environment); }, /** @@ -742,20 +1233,6 @@ Tips: return preview(vite, vite_config, svelte_config); }, - /** - * Clears the output directories. - */ - buildStart() { - if (secondary_build_started) return; - - if (is_build) { - if (!vite_config.build.watch) { - rimraf(out); - } - mkdirp(out); - } - }, - renderChunk(code, chunk) { if (code.includes('__SVELTEKIT_TRACK__')) { return { @@ -771,302 +1248,20 @@ Tips: }, generateBundle() { - if (vite_config.build.ssr) return; - + if (this.environment.name !== 'client') return; this.emitFile({ type: 'asset', fileName: `${kit.appDir}/version.json`, source: s({ version: kit.version.name }) }); }, - - /** - * Vite builds a single bundle. We need three bundles: client, server, and service worker. - * The user's package.json scripts will invoke the Vite CLI to execute the server build. We - * then use this hook to kick off builds for the client and service worker. - */ - writeBundle: { - sequential: true, - async handler(_options, bundle) { - if (secondary_build_started) return; // only run this once - - const verbose = vite_config.logLevel === 'info'; - const log = logger({ verbose }); - - /** @type {import('vite').Manifest} */ - const server_manifest = JSON.parse(read(`${out}/server/${vite_config.build.manifest}`)); - - /** @type {import('types').BuildData} */ - const build_data = { - app_dir: kit.appDir, - app_path: `${kit.paths.base.slice(1)}${kit.paths.base ? '/' : ''}${kit.appDir}`, - manifest_data, - out_dir: out, - service_worker: service_worker_entry_file ? 'service-worker.js' : null, // TODO make file configurable? - client: null, - server_manifest - }; - - const manifest_path = `${out}/server/manifest-full.js`; - fs.writeFileSync( - manifest_path, - `export const manifest = ${generate_manifest({ - build_data, - prerendered: [], - relative_path: '.', - routes: manifest_data.routes - })};\n` - ); - - log.info('Analysing routes'); - - const { metadata, static_exports } = await analyse({ - hash: kit.router.type === 'hash', - manifest_path, - manifest_data, - server_manifest, - tracked_features, - env: { ...env.private, ...env.public }, - out, - output_config: svelte_config.output - }); - - log.info('Building app'); - - // create client build - write_client_manifest( - kit, - manifest_data, - `${kit.outDir}/generated/client-optimized`, - metadata.nodes - ); - - secondary_build_started = true; - - const { output: client_chunks } = /** @type {import('vite').Rollup.RollupOutput} */ ( - await vite.build({ - configFile: vite_config.configFile, - // CLI args - mode: vite_config_env.mode, - logLevel: vite_config.logLevel, - clearScreen: vite_config.clearScreen, - build: { - minify: initial_config.build?.minify, - assetsInlineLimit: vite_config.build.assetsInlineLimit, - sourcemap: vite_config.build.sourcemap - }, - optimizeDeps: { - force: vite_config.optimizeDeps.force - } - }) - ); - - copy( - `${out}/server/${kit.appDir}/immutable/assets`, - `${out}/client/${kit.appDir}/immutable/assets` - ); - - /** @type {import('vite').Manifest} */ - const client_manifest = JSON.parse(read(`${out}/client/${vite_config.build.manifest}`)); - - /** - * @param {string} entry - * @param {boolean} [add_dynamic_css] - */ - const deps_of = (entry, add_dynamic_css = false) => - find_deps(client_manifest, posixify(path.relative('.', entry)), add_dynamic_css); - - if (svelte_config.kit.output.bundleStrategy === 'split') { - const start = deps_of(`${runtime_directory}/client/entry.js`); - const app = deps_of(`${kit.outDir}/generated/client-optimized/app.js`); - - build_data.client = { - start: start.file, - app: app.file, - imports: [...start.imports, ...app.imports], - stylesheets: [...start.stylesheets, ...app.stylesheets], - fonts: [...start.fonts, ...app.fonts], - uses_env_dynamic_public: client_chunks.some( - (chunk) => chunk.type === 'chunk' && chunk.modules[env_dynamic_public] - ) - }; - - // In case of server-side route resolution, we create a purpose-built route manifest that is - // similar to that on the client, with as much information computed upfront so that we - // don't need to include any code of the actual routes in the server bundle. - if (svelte_config.kit.router.resolution === 'server') { - const nodes = manifest_data.nodes.map((node, i) => { - if (node.component || node.universal) { - const entry = `${kit.outDir}/generated/client-optimized/nodes/${i}.js`; - const deps = deps_of(entry, true); - const file = resolve_symlinks( - client_manifest, - `${kit.outDir}/generated/client-optimized/nodes/${i}.js` - ).chunk.file; - - return { file, css: deps.stylesheets }; - } - }); - build_data.client.nodes = nodes.map((node) => node?.file); - build_data.client.css = nodes.map((node) => node?.css); - - build_data.client.routes = compact( - manifest_data.routes.map((route) => { - if (!route.page) return; - - return { - id: route.id, - pattern: route.pattern, - params: route.params, - layouts: route.page.layouts.map((l) => - l !== undefined ? [metadata.nodes[l].has_server_load, l] : undefined - ), - errors: route.page.errors, - leaf: [metadata.nodes[route.page.leaf].has_server_load, route.page.leaf] - }; - }) - ); - } - } else { - const start = deps_of(`${runtime_directory}/client/bundle.js`); - - build_data.client = { - start: start.file, - imports: start.imports, - stylesheets: start.stylesheets, - fonts: start.fonts, - uses_env_dynamic_public: client_chunks.some( - (chunk) => chunk.type === 'chunk' && chunk.modules[env_dynamic_public] - ) - }; - - if (svelte_config.kit.output.bundleStrategy === 'inline') { - const style = /** @type {import('vite').Rollup.OutputAsset} */ ( - client_chunks.find( - (chunk) => - chunk.type === 'asset' && - chunk.names.length === 1 && - chunk.names[0] === 'style.css' - ) - ); - - build_data.client.inline = { - script: read(`${out}/client/${start.file}`), - style: /** @type {string | undefined} */ (style?.source) - }; - } - } - - // regenerate manifest now that we have client entry... - fs.writeFileSync( - manifest_path, - `export const manifest = ${generate_manifest({ - build_data, - prerendered: [], - relative_path: '.', - routes: manifest_data.routes - })};\n` - ); - - // regenerate nodes with the client manifest... - await build_server_nodes( - out, - kit, - manifest_data, - server_manifest, - client_manifest, - bundle, - client_chunks, - svelte_config.kit.output, - static_exports - ); - - // ...and prerender - const { prerendered, prerender_map } = await prerender({ - hash: kit.router.type === 'hash', - out, - manifest_path, - metadata, - verbose, - env: { ...env.private, ...env.public } - }); - - // generate a new manifest that doesn't include prerendered pages - fs.writeFileSync( - `${out}/server/manifest.js`, - `export const manifest = ${generate_manifest({ - build_data, - prerendered: prerendered.paths, - relative_path: '.', - routes: manifest_data.routes.filter((route) => prerender_map.get(route.id) !== true) - })};\n` - ); - - if (service_worker_entry_file) { - if (kit.paths.assets) { - throw new Error('Cannot use service worker alongside config.kit.paths.assets'); - } - - log.info('Building service worker'); - - await build_service_worker( - out, - kit, - { - ...vite_config, - build: { - ...vite_config.build, - minify: initial_config.build?.minify ?? true - } - }, - manifest_data, - service_worker_entry_file, - prerendered, - client_manifest - ); - } - - // we need to defer this to closeBundle, so that adapters copy files - // created by other Vite plugins - finalise = async () => { - console.log( - `\nRun ${colors - .bold() - .cyan('npm run preview')} to preview your production build locally.` - ); - - if (kit.adapter) { - const { adapt } = await import('../../core/adapt/index.js'); - await adapt( - svelte_config, - build_data, - metadata, - prerendered, - prerender_map, - log, - vite_config - ); - } else { - console.log(colors.bold().yellow('\nNo adapter specified')); - - const link = colors.bold().cyan('https://svelte.dev/docs/kit/adapters'); - console.log( - `See ${link} to learn how to configure your app to run on the platform of your choosing` - ); - } - - secondary_build_started = false; - }; - } - }, - /** * Runs the adapter. */ closeBundle: { sequential: true, async handler() { - if (!vite_config.build.ssr) return; + if (this.environment.name !== 'client') return; await finalise?.(); } } diff --git a/packages/kit/src/exports/vite/module_ids.js b/packages/kit/src/exports/vite/module_ids.js index 91b5caeddb4f..7b7441da0dc1 100644 --- a/packages/kit/src/exports/vite/module_ids.js +++ b/packages/kit/src/exports/vite/module_ids.js @@ -10,6 +10,7 @@ export const service_worker = '\0virtual:service-worker'; export const sveltekit_environment = '\0virtual:__sveltekit/environment'; export const sveltekit_paths = '\0virtual:__sveltekit/paths'; export const sveltekit_server = '\0virtual:__sveltekit/server'; +export const sveltekit_vite_environment = '\0virtual:__sveltekit/vite-environment'; export const app_server = fileURLToPath( new URL('../../runtime/app/server/index.js', import.meta.url) diff --git a/packages/kit/src/types/internal.d.ts b/packages/kit/src/types/internal.d.ts index 17e2425e3c17..2f027114f668 100644 --- a/packages/kit/src/types/internal.d.ts +++ b/packages/kit/src/types/internal.d.ts @@ -521,3 +521,9 @@ export type ValidatedKitConfig = Omit, 'adapter'> & export * from '../exports/index.js'; export * from './private.js'; + +export interface DevEnvironment { + manifest_data: ManifestData; + env: Record; + remote_address: string | undefined; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dc3b5400e2e4..b1e1ac29673a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,18 +10,21 @@ catalogs: specifier: ^1.51.1 version: 1.51.1 '@sveltejs/vite-plugin-svelte': - specifier: ^6.0.0-next.0 - version: 6.0.0-next.0 + specifier: ^6.1.0 + version: 6.1.0 cross-env: specifier: ^7.0.3 version: 7.0.3 vite: - specifier: ^6.3.5 - version: 6.3.5 + specifier: ^7.0.3 + version: 7.0.3 vitest: specifier: ^3.2.3 version: 3.2.3 +overrides: + esm-env: github:benmccann/esm-env#bcbddbc&path:packages/esm-env + importers: .: @@ -58,7 +61,7 @@ importers: version: link:../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1)) '@types/node': specifier: ^18.19.48 version: 18.19.50 @@ -104,7 +107,7 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) server-side-dep: specifier: file:server-side-dep version: file:packages/adapter-cloudflare/test/apps/pages/server-side-dep @@ -113,7 +116,7 @@ importers: version: 5.23.1 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) wrangler: specifier: ^4.14.3 version: 4.14.4(@cloudflare/workers-types@4.20250508.0) @@ -125,7 +128,7 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -137,7 +140,7 @@ importers: version: 5.23.1 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) wrangler: specifier: ^4.14.3 version: 4.14.4(@cloudflare/workers-types@4.20250508.0) @@ -171,7 +174,7 @@ importers: version: link:../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1)) '@types/node': specifier: ^18.19.48 version: 18.19.50 @@ -211,7 +214,7 @@ importers: version: link:../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1)) '@types/node': specifier: ^18.19.48 version: 18.19.50 @@ -238,7 +241,7 @@ importers: version: link:../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1)) '@types/node': specifier: ^18.19.48 version: 18.19.50 @@ -253,7 +256,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/adapter-static/test/apps/prerendered: devDependencies: @@ -262,7 +265,7 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) sirv-cli: specifier: ^3.0.0 version: 3.0.0 @@ -271,7 +274,7 @@ importers: version: 5.23.1 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/adapter-static/test/apps/spa: devDependencies: @@ -283,7 +286,7 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) sirv-cli: specifier: ^3.0.0 version: 3.0.0 @@ -292,7 +295,7 @@ importers: version: 5.23.1 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/adapter-vercel: dependencies: @@ -308,7 +311,7 @@ importers: version: link:../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1)) '@types/node': specifier: ^18.19.48 version: 18.19.50 @@ -323,7 +326,7 @@ importers: dependencies: '@sveltejs/kit': specifier: ^1.0.0 || ^2.0.0 - version: link:../kit + version: 2.24.0(@sveltejs/vite-plugin-svelte@6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)))(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) devDependencies: typescript: specifier: ^5.3.3 @@ -351,7 +354,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1)) '@types/estree': specifier: ^1.0.5 version: 1.0.7 @@ -369,7 +372,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) vitest: specifier: 'catalog:' version: 3.2.3(@types/node@18.19.50)(lightningcss@1.30.1) @@ -392,8 +395,8 @@ importers: specifier: ^5.1.0 version: 5.1.0 esm-env: - specifier: ^1.2.2 - version: 1.2.2 + specifier: github:benmccann/esm-env#bcbddbc&path:packages/esm-env + version: https://codeload.github.com/benmccann/esm-env/tar.gz/bcbddbc#path:packages/esm-env kleur: specifier: ^4.1.5 version: 4.1.5 @@ -418,7 +421,7 @@ importers: version: 1.51.1 '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1)) '@types/connect': specifier: ^3.4.38 version: 3.4.38 @@ -445,7 +448,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) vitest: specifier: 'catalog:' version: 3.2.3(@types/node@18.19.50)(lightningcss@1.30.1) @@ -460,7 +463,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -478,7 +481,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/apps/basics: devDependencies: @@ -487,7 +490,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -505,7 +508,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/apps/dev-only: devDependencies: @@ -514,7 +517,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -559,7 +562,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/apps/embed: devDependencies: @@ -568,7 +571,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -583,7 +586,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/apps/hash-based-routing: devDependencies: @@ -592,7 +595,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -607,7 +610,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/apps/no-ssr: devDependencies: @@ -616,7 +619,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -631,7 +634,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/apps/options: devDependencies: @@ -643,7 +646,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -658,7 +661,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/apps/options-2: devDependencies: @@ -670,7 +673,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -685,7 +688,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/apps/prerendered-app-error-pages: devDependencies: @@ -694,7 +697,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -709,7 +712,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/apps/writes: devDependencies: @@ -718,7 +721,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -733,7 +736,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors: devDependencies: @@ -751,7 +754,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -763,7 +766,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors/apps/prerenderable-incorrect-fragment: devDependencies: @@ -775,7 +778,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -787,7 +790,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors/apps/prerenderable-not-prerendered: devDependencies: @@ -799,7 +802,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -811,7 +814,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors/apps/private-dynamic-env: devDependencies: @@ -820,7 +823,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -832,7 +835,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors/apps/private-dynamic-env-dynamic-import: devDependencies: @@ -841,7 +844,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -853,7 +856,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors/apps/private-static-env: devDependencies: @@ -862,7 +865,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -877,7 +880,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors/apps/private-static-env-dynamic-import: devDependencies: @@ -886,7 +889,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -898,7 +901,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors/apps/server-only-folder: devDependencies: @@ -907,7 +910,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -919,7 +922,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors/apps/server-only-folder-dynamic-import: devDependencies: @@ -928,7 +931,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -940,7 +943,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors/apps/server-only-module: devDependencies: @@ -949,7 +952,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -961,7 +964,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors/apps/server-only-module-dynamic-import: devDependencies: @@ -970,7 +973,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -982,7 +985,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors/apps/service-worker-dynamic-public-env: devDependencies: @@ -991,7 +994,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -1003,7 +1006,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors/apps/service-worker-private-env: devDependencies: @@ -1012,7 +1015,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -1024,7 +1027,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/build-errors/apps/syntax-error: devDependencies: @@ -1033,7 +1036,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -1045,7 +1048,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages/kit/test/prerendering/basics: devDependencies: @@ -1054,7 +1057,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -1066,7 +1069,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) vitest: specifier: 'catalog:' version: 3.2.3(@types/node@18.19.50)(lightningcss@1.30.1) @@ -1078,7 +1081,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -1090,7 +1093,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) vitest: specifier: 'catalog:' version: 3.2.3(@types/node@18.19.50)(lightningcss@1.30.1) @@ -1102,7 +1105,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) svelte: specifier: ^5.23.1 version: 5.23.1 @@ -1114,7 +1117,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) vitest: specifier: 'catalog:' version: 3.2.3(@types/node@18.19.50)(lightningcss@1.30.1) @@ -1139,7 +1142,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1)) '@types/node': specifier: ^18.19.48 version: 18.19.50 @@ -1202,7 +1205,7 @@ importers: version: link:../../packages/package '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + version: 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) prettier: specifier: ^3.3.2 version: 3.3.3 @@ -1223,7 +1226,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + version: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) packages: @@ -2233,20 +2236,29 @@ packages: typescript: '>= 5' typescript-eslint: '>= 8' - '@sveltejs/vite-plugin-svelte-inspector@5.0.0-next.0': - resolution: {integrity: sha512-G++kR34xZSd3cT6VVOB781Pa2KOS756/ZKK7urSyXmrhK/D/mPiUvjZwWKNVTDOXkwrvVt/Y3cLecbR6Qm66Kw==} + '@sveltejs/kit@2.24.0': + resolution: {integrity: sha512-6aCsU6PwxB4CQBJEvLnOoSv8hoviZWDVTKDTzQoERG6vpIHeXJufVWQlyaOXrdSlqBiwknHm0nQT/S/Nn3518A==} + engines: {node: '>=18.13'} + hasBin: true + peerDependencies: + '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 + + '@sveltejs/vite-plugin-svelte-inspector@5.0.0': + resolution: {integrity: sha512-iwQ8Z4ET6ZFSt/gC+tVfcsSBHwsqc6RumSaiLUkAurW3BCpJam65cmHw0oOlDMTO0u+PZi9hilBRYN+LZNHTUQ==} engines: {node: ^20.19 || ^22.12 || >=24} peerDependencies: '@sveltejs/vite-plugin-svelte': ^6.0.0-next.0 svelte: ^5.0.0 - vite: ^6.3.0 || ^7.0.0-beta.0 + vite: ^6.3.0 || ^7.0.0 - '@sveltejs/vite-plugin-svelte@6.0.0-next.0': - resolution: {integrity: sha512-IMz7Q2bfMKmOg3LCbtvKoHlDeEhYQ2A7wqXYSC9cvQY+thCpxBwXHdVdWXYBre7GX3pCsmHDdsQFoySLsgq/hg==} + '@sveltejs/vite-plugin-svelte@6.1.0': + resolution: {integrity: sha512-+U6lz1wvGEG/BvQyL4z/flyNdQ9xDNv5vrh+vWBWTHaebqT0c9RNggpZTo/XSPoHsSCWBlYaTlRX8pZ9GATXCw==} engines: {node: ^20.19 || ^22.12 || >=24} peerDependencies: svelte: ^5.0.0 - vite: ^6.3.0 || ^7.0.0-beta.0 + vite: ^6.3.0 || ^7.0.0 '@svitejs/changesets-changelog-github-compact@1.2.0': resolution: {integrity: sha512-08eKiDAjj4zLug1taXSIJ0kGL5cawjVCyJkBb6EWSg5fEPX6L+Wtr0CH2If4j5KYylz85iaZiFlUItvgJvll5g==} @@ -2980,8 +2992,9 @@ packages: jiti: optional: true - esm-env@1.2.2: - resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} + esm-env@https://codeload.github.com/benmccann/esm-env/tar.gz/bcbddbc#path:packages/esm-env: + resolution: {path: packages/esm-env, tarball: https://codeload.github.com/benmccann/esm-env/tar.gz/bcbddbc} + version: 1.2.2 espree@10.4.0: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} @@ -4440,19 +4453,19 @@ packages: engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - vite@6.3.5: - resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + vite@7.0.3: + resolution: {integrity: sha512-y2L5oJZF7bj4c0jgGYgBNSdIu+5HF+m68rn2cQXFbGoShdhV1phX9rbnxy9YXj82aS8MMsCLAAFkRxZeWdldrQ==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@types/node': ^20.19.0 || >=22.12.0 jiti: '>=1.21.0' - less: '*' + less: ^4.0.0 lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 yaml: ^2.4.2 @@ -4480,10 +4493,10 @@ packages: yaml: optional: true - vitefu@1.0.6: - resolution: {integrity: sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==} + vitefu@1.1.1: + resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 peerDependenciesMeta: vite: optional: true @@ -5526,6 +5539,10 @@ snapshots: dependencies: acorn: 8.14.1 + '@sveltejs/acorn-typescript@1.0.5(acorn@8.15.0)': + dependencies: + acorn: 8.15.0 + '@sveltejs/eslint-config@8.2.0(@stylistic/eslint-plugin-js@2.1.0(eslint@9.29.0))(eslint-config-prettier@9.1.0(eslint@9.29.0))(eslint-plugin-n@17.16.1(eslint@9.29.0)(typescript@5.8.3))(eslint-plugin-svelte@3.9.3(eslint@9.29.0)(svelte@5.23.1))(eslint@9.29.0)(typescript-eslint@8.35.0(eslint@9.29.0)(typescript@5.8.3))(typescript@5.8.3)': dependencies: '@stylistic/eslint-plugin-js': 2.1.0(eslint@9.29.0) @@ -5537,25 +5554,65 @@ snapshots: typescript: 5.8.3 typescript-eslint: 8.35.0(eslint@9.29.0)(typescript@5.8.3) - '@sveltejs/vite-plugin-svelte-inspector@5.0.0-next.0(@sveltejs/vite-plugin-svelte@6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)))(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1))': + '@sveltejs/kit@2.24.0(@sveltejs/vite-plugin-svelte@6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)))(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) + '@sveltejs/vite-plugin-svelte': 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) + '@types/cookie': 0.6.0 + acorn: 8.15.0 + cookie: 0.6.0 + devalue: 5.1.0 + esm-env: https://codeload.github.com/benmccann/esm-env/tar.gz/bcbddbc#path:packages/esm-env + kleur: 4.1.5 + magic-string: 0.30.17 + mrmime: 2.0.0 + sade: 1.8.1 + set-cookie-parser: 2.6.0 + sirv: 3.0.0 + svelte: 5.23.1 + vite: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) + + '@sveltejs/vite-plugin-svelte-inspector@5.0.0(@sveltejs/vite-plugin-svelte@6.1.0(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1)))(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1))': + dependencies: + '@sveltejs/vite-plugin-svelte': 6.1.0(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1)) + debug: 4.4.1 + svelte: 5.23.1 + vite: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) + transitivePeerDependencies: + - supports-color + + '@sveltejs/vite-plugin-svelte-inspector@5.0.0(@sveltejs/vite-plugin-svelte@6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)))(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1))': + dependencies: + '@sveltejs/vite-plugin-svelte': 6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) debug: 4.4.1 svelte: 5.23.1 - vite: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + vite: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) + transitivePeerDependencies: + - supports-color + + '@sveltejs/vite-plugin-svelte@6.1.0(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1))': + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 5.0.0(@sveltejs/vite-plugin-svelte@6.1.0(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1)))(svelte@5.23.1)(vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1)) + debug: 4.4.1 + deepmerge: 4.3.1 + kleur: 4.1.5 + magic-string: 0.30.17 + svelte: 5.23.1 + vite: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) + vitefu: 1.1.1(vite@7.0.3(lightningcss@1.30.1)) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1))': + '@sveltejs/vite-plugin-svelte@6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.0-next.0(@sveltejs/vite-plugin-svelte@6.0.0-next.0(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)))(svelte@5.23.1)(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.0(@sveltejs/vite-plugin-svelte@6.1.0(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)))(svelte@5.23.1)(vite@7.0.3(lightningcss@1.30.1)) debug: 4.4.1 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.17 svelte: 5.23.1 - vite: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) - vitefu: 1.0.6(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + vite: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) + vitefu: 1.1.1(vite@7.0.3(lightningcss@1.30.1)) transitivePeerDependencies: - supports-color @@ -5750,13 +5807,13 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.3(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1))': + '@vitest/mocker@3.2.3(vite@7.0.3(lightningcss@1.30.1))': dependencies: '@vitest/spy': 3.2.3 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + vite: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) '@vitest/pretty-format@3.2.3': dependencies: @@ -6418,7 +6475,7 @@ snapshots: transitivePeerDependencies: - supports-color - esm-env@1.2.2: {} + esm-env@https://codeload.github.com/benmccann/esm-env/tar.gz/bcbddbc#path:packages/esm-env: {} espree@10.4.0: dependencies: @@ -7620,7 +7677,7 @@ snapshots: aria-query: 5.3.2 axobject-query: 4.1.0 clsx: 2.1.1 - esm-env: 1.2.2 + esm-env: https://codeload.github.com/benmccann/esm-env/tar.gz/bcbddbc#path:packages/esm-env esrap: 1.4.5 is-reference: 3.0.3 locate-character: 3.0.0 @@ -7792,7 +7849,7 @@ snapshots: debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + vite: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) transitivePeerDependencies: - '@types/node' - jiti @@ -7807,7 +7864,7 @@ snapshots: - tsx - yaml - vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1): + vite@7.0.3(@types/node@18.19.50)(lightningcss@1.30.1): dependencies: esbuild: 0.25.5 fdir: 6.4.6(picomatch@4.0.2) @@ -7820,15 +7877,15 @@ snapshots: fsevents: 2.3.3 lightningcss: 1.30.1 - vitefu@1.0.6(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)): + vitefu@1.1.1(vite@7.0.3(lightningcss@1.30.1)): optionalDependencies: - vite: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + vite: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) vitest@3.2.3(@types/node@18.19.50)(lightningcss@1.30.1): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.3 - '@vitest/mocker': 3.2.3(vite@6.3.5(@types/node@18.19.50)(lightningcss@1.30.1)) + '@vitest/mocker': 3.2.3(vite@7.0.3(lightningcss@1.30.1)) '@vitest/pretty-format': 3.2.3 '@vitest/runner': 3.2.3 '@vitest/snapshot': 3.2.3 @@ -7846,7 +7903,7 @@ snapshots: tinyglobby: 0.2.14 tinypool: 1.1.0 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@18.19.50)(lightningcss@1.30.1) + vite: 7.0.3(@types/node@18.19.50)(lightningcss@1.30.1) vite-node: 3.2.3(@types/node@18.19.50)(lightningcss@1.30.1) why-is-node-running: 2.3.0 optionalDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 5ad4aae36e92..5e01111c8548 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -12,7 +12,7 @@ packages: catalog: '@playwright/test': '^1.51.1' - '@sveltejs/vite-plugin-svelte': '^6.0.0-next.0' + '@sveltejs/vite-plugin-svelte': '^6.1.0' 'cross-env': '^7.0.3' 'vitest': '^3.2.3' - 'vite': '^6.3.5' + 'vite': '^7.0.3' From 498ef93aaada88e87fe56cab683c0f7f1e10eec9 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Thu, 17 Jul 2025 13:40:35 +0800 Subject: [PATCH 02/16] add files to files array --- packages/adapter-cloudflare/package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/adapter-cloudflare/package.json b/packages/adapter-cloudflare/package.json index 3622b696f24b..400acc014dcd 100644 --- a/packages/adapter-cloudflare/package.json +++ b/packages/adapter-cloudflare/package.json @@ -32,6 +32,8 @@ "files": [ "files", "index.js", + "utils.js", + "worker.js", "index.d.ts", "ambient.d.ts" ], From b3d902f64aebf6906f27d215b3f58e144d43ca1c Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Fri, 18 Jul 2025 10:37:16 +0800 Subject: [PATCH 03/16] bump peer dep --- packages/kit/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/package.json b/packages/kit/package.json index 906b9735baeb..19ff030f0813 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -48,7 +48,7 @@ "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" + "vite": "^7.0.0-beta.0" }, "bin": { "svelte-kit": "svelte-kit.js" From d5b77865f2f797af71a244a8672ccce619efac41 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Fri, 18 Jul 2025 10:45:45 +0800 Subject: [PATCH 04/16] use node 20 types --- packages/adapter-auto/package.json | 2 +- packages/adapter-cloudflare/package.json | 2 +- packages/adapter-netlify/package.json | 2 +- packages/adapter-node/package.json | 2 +- packages/adapter-static/package.json | 2 +- packages/adapter-vercel/package.json | 2 +- packages/enhanced-img/package.json | 2 +- packages/kit/package.json | 2 +- packages/package/package.json | 2 +- pnpm-workspace.yaml | 1 + 10 files changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/adapter-auto/package.json b/packages/adapter-auto/package.json index e245a5a5a3b1..e2c48cbc8575 100644 --- a/packages/adapter-auto/package.json +++ b/packages/adapter-auto/package.json @@ -42,7 +42,7 @@ "devDependencies": { "@sveltejs/kit": "workspace:^", "@sveltejs/vite-plugin-svelte": "catalog:", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "typescript": "^5.3.3", "vitest": "catalog:" }, diff --git a/packages/adapter-cloudflare/package.json b/packages/adapter-cloudflare/package.json index 5d457778bfe6..bb184a75bbf1 100644 --- a/packages/adapter-cloudflare/package.json +++ b/packages/adapter-cloudflare/package.json @@ -54,7 +54,7 @@ "devDependencies": { "@playwright/test": "catalog:", "@sveltejs/kit": "workspace:^", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "esbuild": "^0.25.4", "typescript": "^5.3.3", "vitest": "catalog:" diff --git a/packages/adapter-netlify/package.json b/packages/adapter-netlify/package.json index 4f809f1447cd..cdcce0c0e209 100644 --- a/packages/adapter-netlify/package.json +++ b/packages/adapter-netlify/package.json @@ -55,7 +55,7 @@ "@rollup/plugin-node-resolve": "^16.0.0", "@sveltejs/kit": "workspace:^", "@sveltejs/vite-plugin-svelte": "catalog:", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "@types/set-cookie-parser": "^2.4.7", "rollup": "^4.14.2", "typescript": "^5.3.3", diff --git a/packages/adapter-node/package.json b/packages/adapter-node/package.json index 25f456fe4e70..e75bc1061708 100644 --- a/packages/adapter-node/package.json +++ b/packages/adapter-node/package.json @@ -45,7 +45,7 @@ "@polka/url": "^1.0.0-next.28", "@sveltejs/kit": "workspace:^", "@sveltejs/vite-plugin-svelte": "catalog:", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "polka": "^1.0.0-next.28", "sirv": "^3.0.0", "typescript": "^5.3.3", diff --git a/packages/adapter-static/package.json b/packages/adapter-static/package.json index b7c5315b4073..d4a256f45df6 100644 --- a/packages/adapter-static/package.json +++ b/packages/adapter-static/package.json @@ -42,7 +42,7 @@ "@playwright/test": "catalog:", "@sveltejs/kit": "workspace:^", "@sveltejs/vite-plugin-svelte": "catalog:", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "sirv": "^3.0.0", "svelte": "^5.35.5", "typescript": "^5.3.3", diff --git a/packages/adapter-vercel/package.json b/packages/adapter-vercel/package.json index bb1b28134460..6a567f1c8c20 100644 --- a/packages/adapter-vercel/package.json +++ b/packages/adapter-vercel/package.json @@ -46,7 +46,7 @@ "devDependencies": { "@sveltejs/kit": "workspace:^", "@sveltejs/vite-plugin-svelte": "catalog:", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "typescript": "^5.3.3", "vitest": "catalog:" }, diff --git a/packages/enhanced-img/package.json b/packages/enhanced-img/package.json index 8c9e0fb98f3d..ec967187bb46 100644 --- a/packages/enhanced-img/package.json +++ b/packages/enhanced-img/package.json @@ -45,7 +45,7 @@ "devDependencies": { "@sveltejs/vite-plugin-svelte": "catalog:", "@types/estree": "^1.0.5", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "rollup": "^4.27.4", "svelte": "^5.35.5", "typescript": "^5.6.3", diff --git a/packages/kit/package.json b/packages/kit/package.json index 5671a7f20cf6..a520af0153a6 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -35,7 +35,7 @@ "@playwright/test": "catalog:", "@sveltejs/vite-plugin-svelte": "catalog:", "@types/connect": "^3.4.38", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "@types/set-cookie-parser": "^2.4.7", "dts-buddy": "^0.6.1", "rollup": "^4.14.2", diff --git a/packages/package/package.json b/packages/package/package.json index 5470c8236bcb..3b1ca7b71974 100644 --- a/packages/package/package.json +++ b/packages/package/package.json @@ -28,7 +28,7 @@ }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "catalog:", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "@types/semver": "^7.5.6", "prettier": "^3.1.1", "svelte": "^5.35.5", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a401e45c1ae6..166530f6a0f0 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -14,6 +14,7 @@ packages: catalog: '@playwright/test': '^1.51.1' '@sveltejs/vite-plugin-svelte': '^6.1.0' + '@types/node': '^20.14.8' 'cross-env': '^7.0.3' 'vitest': '^3.2.3' 'vite': '^7.0.3' From ef4d10e8f15581e520dd3d6a459a679f44e99c85 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Fri, 18 Jul 2025 12:33:48 +0800 Subject: [PATCH 05/16] ignore virtual modules when optimising deps --- packages/kit/src/exports/vite/index.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index 8d4102482e24..4cfc3d125754 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -356,7 +356,9 @@ async function kit({ svelte_config }) { undefined; // vite-plugin-svelte is setting this but it doesn't work with vite-plugin-cloudflare - /** @type {NonNullable} */ (new_config.resolve).external = undefined; + /** @type {NonNullable} */ ( + new_config.resolve + ).external = undefined; } warn_overridden_config(config, new_config); @@ -1209,9 +1211,19 @@ Tips: } // TODO: Cloudflare Vite plugin doesn't allow `ssr.external` but VPS and Kit are using it - /** @type {import('vite').SSROptions} */ (config.ssr).external = undefined; + /** @type {import('vite').SSROptions} */ (new_config.ssr).external = undefined; // TODO: see https://github.com/cloudflare/workers-sdk/issues/9036#issuecomment-2825271144 - /** @type {import('vite').SSROptions} */ (config.ssr).noExternal = undefined; + /** @type {import('vite').SSROptions} */ (new_config.ssr).noExternal = undefined; + + // TODO: move this to Cloudflare adapter? + // Ensure vite-plugin-cloudflare ignores virtual modules when optimising dependencies + new_config.environments = { + ssr: { + optimizeDeps: { + exclude: [...(config.environments?.ssr.optimizeDeps?.exclude ?? []), '__sveltekit/*'] + } + } + }; warn_overridden_config(config, new_config); From a02fbfa13ed5cc9fc6c0f20ccb6df1fa423c7885 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Thu, 24 Jul 2025 13:52:29 +0800 Subject: [PATCH 06/16] try this to avoid prebundling kit in worker --- packages/adapter-cloudflare/tsconfig.json | 3 +- packages/adapter-cloudflare/worker.js | 2 +- packages/kit/src/exports/internal/index.js | 2 + .../kit/src/exports/vite/dev/environment.js | 6 +- packages/kit/src/exports/vite/index.js | 71 +++++++++++-------- 5 files changed, 49 insertions(+), 35 deletions(-) diff --git a/packages/adapter-cloudflare/tsconfig.json b/packages/adapter-cloudflare/tsconfig.json index b693c7b68958..332d2de93077 100644 --- a/packages/adapter-cloudflare/tsconfig.json +++ b/packages/adapter-cloudflare/tsconfig.json @@ -9,7 +9,8 @@ "moduleResolution": "node16", "baseUrl": ".", "paths": { - "@sveltejs/kit": ["../kit/types/index"] + "@sveltejs/kit": ["../kit/types/index.d.ts"], + "@sveltejs/kit/internal": ["../kit/src/exports/internal/index.js"] }, // taken from the Cloudflare Workers TypeScript template https://github.com/cloudflare/workers-sdk/blob/main/packages/create-cloudflare/templates/hello-world/ts/tsconfig.json "lib": ["es2021"], diff --git a/packages/adapter-cloudflare/worker.js b/packages/adapter-cloudflare/worker.js index 0fbc95583223..0e8e86b74ddf 100644 --- a/packages/adapter-cloudflare/worker.js +++ b/packages/adapter-cloudflare/worker.js @@ -1,4 +1,4 @@ -import { Server } from '../kit/src/runtime/server/index.js'; +import { Server } from '@sveltejs/kit/internal'; // TODO: use prod variables when building // TODO: fix kit virtual module type issues when this file is consumed by an app import { diff --git a/packages/kit/src/exports/internal/index.js b/packages/kit/src/exports/internal/index.js index aa0b93f8965b..72bbb71f15d5 100644 --- a/packages/kit/src/exports/internal/index.js +++ b/packages/kit/src/exports/internal/index.js @@ -61,3 +61,5 @@ export class ActionFailure { this.data = data; } } + +export { Server } from '../../runtime/server/index.js'; diff --git a/packages/kit/src/exports/vite/dev/environment.js b/packages/kit/src/exports/vite/dev/environment.js index 615cd964e357..a27b617b1402 100644 --- a/packages/kit/src/exports/vite/dev/environment.js +++ b/packages/kit/src/exports/vite/dev/environment.js @@ -22,12 +22,8 @@ export function to_fs(str) { /** @param {string} id */ export async function resolve(id) { - // TODO: doesn't work for files symlinked to kit package workspace. Try in new app with node_modules? + // TODO: doesn't work for files symlinked to kit package workspace const url = id.startsWith('..') ? to_fs(path.posix.resolve(id)) : `/${id}`; - console.log({ - id, - url - }) const module = await loud_ssr_load_module(url); diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index 4cfc3d125754..9d905ea466bb 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -346,21 +346,51 @@ async function kit({ svelte_config }) { 'cookie', 'set-cookie-parser' ]; - - // TODO: vite-plugin-cloudflare doesn't allow `ssr.external` but VPS and Kit are using it - /** @type {NonNullable} */ (new_config.ssr).external = - undefined; - // only needed because of vite-plugin-cloudflare - // TODO: remove when https://github.com/cloudflare/workers-sdk/issues/9036#issuecomment-2825271144 is fixed - /** @type {NonNullable} */ (new_config.ssr).noExternal = - undefined; - - // vite-plugin-svelte is setting this but it doesn't work with vite-plugin-cloudflare - /** @type {NonNullable} */ ( - new_config.resolve - ).external = undefined; } + // TODO: move these to the Cloudflare adapter + + // vite-plugin-cloudflare doesn't allow `ssr.external` but VPS and Kit set it + /** @type {import('vite').SSROptions} */ (config.ssr).external = undefined; + /** @type {NonNullable} */ (new_config.ssr).external = + undefined; + + // TODO: remove these when https://github.com/cloudflare/workers-sdk/issues/9036#issuecomment-2825271144 is resolved + /** @type {import('vite').SSROptions} */ (config.ssr).noExternal = undefined; + /** @type {import('vite').SSROptions} */ (new_config.ssr).noExternal = undefined; + + // we need to set this because server environments don't inherit the top-level optimizeDeps option + // see https://vite.dev/guide/api-environment.html#environments-configuration + // const optimize_deps = vite.mergeConfig( + // config?.optimizeDeps ?? {}, + // new_config?.optimizeDeps ?? {}, + // false + // ); + // new_config.environments = { + // ssr: { + // optimizeDeps: vite.mergeConfig( + // optimize_deps, + // { + // // ensure vite-plugin-cloudflare ignores virtual modules when optimising dependencies + // exclude: ['__sveltekit/*'] + // }, + // false + // ) + // } + // }; + // TODO: find a better way to inherit top level optimizeDeps options + new_config.environments = { + ssr: { + optimizeDeps: { + include: config.optimizeDeps?.include ?? [], + exclude: [...(new_config.optimizeDeps?.exclude ?? []), '__sveltekit/*'], + extensions: config.optimizeDeps?.extensions ?? [], + entries: new_config.optimizeDeps?.entries ?? [], + esbuildOptions: config.optimizeDeps?.esbuildOptions + } + } + }; + warn_overridden_config(config, new_config); return new_config; @@ -1210,21 +1240,6 @@ Tips: }; } - // TODO: Cloudflare Vite plugin doesn't allow `ssr.external` but VPS and Kit are using it - /** @type {import('vite').SSROptions} */ (new_config.ssr).external = undefined; - // TODO: see https://github.com/cloudflare/workers-sdk/issues/9036#issuecomment-2825271144 - /** @type {import('vite').SSROptions} */ (new_config.ssr).noExternal = undefined; - - // TODO: move this to Cloudflare adapter? - // Ensure vite-plugin-cloudflare ignores virtual modules when optimising dependencies - new_config.environments = { - ssr: { - optimizeDeps: { - exclude: [...(config.environments?.ssr.optimizeDeps?.exclude ?? []), '__sveltekit/*'] - } - } - }; - warn_overridden_config(config, new_config); return new_config; From 4ca01c9cacb26dbf3ad07836decd5b6d93c33352 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Thu, 24 Jul 2025 14:15:17 +0800 Subject: [PATCH 07/16] export server from different path --- packages/adapter-cloudflare/index.js | 2 +- packages/adapter-cloudflare/tsconfig.json | 2 +- packages/adapter-cloudflare/worker.js | 2 +- packages/kit/package.json | 4 ++++ packages/kit/src/exports/internal/index.js | 2 -- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/adapter-cloudflare/index.js b/packages/adapter-cloudflare/index.js index 56bd90ae3597..362f6f9b2fb0 100644 --- a/packages/adapter-cloudflare/index.js +++ b/packages/adapter-cloudflare/index.js @@ -2,7 +2,7 @@ import { copyFileSync, existsSync, writeFileSync } from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { VERSION } from '@sveltejs/kit'; -import { getPlatformProxy, unstable_readConfig } from 'wrangler'; +import { unstable_readConfig } from 'wrangler'; import { is_building_for_cloudflare_pages, validate_worker_settings } from './utils.js'; const name = '@sveltejs/adapter-cloudflare'; diff --git a/packages/adapter-cloudflare/tsconfig.json b/packages/adapter-cloudflare/tsconfig.json index 332d2de93077..134da2171ba3 100644 --- a/packages/adapter-cloudflare/tsconfig.json +++ b/packages/adapter-cloudflare/tsconfig.json @@ -10,7 +10,7 @@ "baseUrl": ".", "paths": { "@sveltejs/kit": ["../kit/types/index.d.ts"], - "@sveltejs/kit/internal": ["../kit/src/exports/internal/index.js"] + "@sveltejs/kit/internal/server": ["../kit/src/runtime/server/index.js"] }, // taken from the Cloudflare Workers TypeScript template https://github.com/cloudflare/workers-sdk/blob/main/packages/create-cloudflare/templates/hello-world/ts/tsconfig.json "lib": ["es2021"], diff --git a/packages/adapter-cloudflare/worker.js b/packages/adapter-cloudflare/worker.js index 0e8e86b74ddf..2f1cc7d9a93e 100644 --- a/packages/adapter-cloudflare/worker.js +++ b/packages/adapter-cloudflare/worker.js @@ -1,4 +1,4 @@ -import { Server } from '@sveltejs/kit/internal'; +import { Server } from '@sveltejs/kit/internal/server'; // TODO: use prod variables when building // TODO: fix kit virtual module type issues when this file is consumed by an app import { diff --git a/packages/kit/package.json b/packages/kit/package.json index 8c131bc5cfbb..96ae81663cd0 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -87,6 +87,10 @@ "types": "./types/index.d.ts", "import": "./src/exports/internal/index.js" }, + "./internal/server": { + "types": "./types/index.d.ts", + "import": "./src/runtime/server/index.js" + }, "./node": { "types": "./types/index.d.ts", "import": "./src/exports/node/index.js" diff --git a/packages/kit/src/exports/internal/index.js b/packages/kit/src/exports/internal/index.js index 72bbb71f15d5..aa0b93f8965b 100644 --- a/packages/kit/src/exports/internal/index.js +++ b/packages/kit/src/exports/internal/index.js @@ -61,5 +61,3 @@ export class ActionFailure { this.data = data; } } - -export { Server } from '../../runtime/server/index.js'; From 21ee281bc10d6151ba22fc17b413bb7415cc9715 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Thu, 24 Jul 2025 16:04:29 +0800 Subject: [PATCH 08/16] optimise cjs deps --- packages/kit/src/exports/vite/index.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index 9d905ea466bb..c738e84791b4 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -382,7 +382,13 @@ async function kit({ svelte_config }) { new_config.environments = { ssr: { optimizeDeps: { - include: config.optimizeDeps?.include ?? [], + include: [ + ...(config.optimizeDeps?.include ?? []), + // @sveltejs/kit is excluded from optimization but some of its + // dependencies are packaged as CommonJS so we need to include those + '@sveltejs/kit > cookie', + '@sveltejs/kit > set-cookie-parser' + ], exclude: [...(new_config.optimizeDeps?.exclude ?? []), '__sveltekit/*'], extensions: config.optimizeDeps?.extensions ?? [], entries: new_config.optimizeDeps?.entries ?? [], From 9158a25410031a7036c11ae5854dada5d3d02684 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Thu, 24 Jul 2025 16:06:40 +0800 Subject: [PATCH 09/16] with dep optimisation --- packages/adapter-cloudflare/worker.js | 2 +- packages/kit/src/exports/vite/index.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/adapter-cloudflare/worker.js b/packages/adapter-cloudflare/worker.js index 2f1cc7d9a93e..0fbc95583223 100644 --- a/packages/adapter-cloudflare/worker.js +++ b/packages/adapter-cloudflare/worker.js @@ -1,4 +1,4 @@ -import { Server } from '@sveltejs/kit/internal/server'; +import { Server } from '../kit/src/runtime/server/index.js'; // TODO: use prod variables when building // TODO: fix kit virtual module type issues when this file is consumed by an app import { diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index c738e84791b4..55f7461f423b 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -384,10 +384,10 @@ async function kit({ svelte_config }) { optimizeDeps: { include: [ ...(config.optimizeDeps?.include ?? []), - // @sveltejs/kit is excluded from optimization but some of its - // dependencies are packaged as CommonJS so we need to include those - '@sveltejs/kit > cookie', - '@sveltejs/kit > set-cookie-parser' + // // @sveltejs/kit is excluded from optimization but some of its + // // dependencies are packaged as CommonJS so we need to include those + // '@sveltejs/kit > cookie', + // '@sveltejs/kit > set-cookie-parser' ], exclude: [...(new_config.optimizeDeps?.exclude ?? []), '__sveltekit/*'], extensions: config.optimizeDeps?.extensions ?? [], From f4eb279bab966e9b908be6863cd6026a5e5b93e9 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Thu, 24 Jul 2025 16:07:05 +0800 Subject: [PATCH 10/16] without dep optimisation --- packages/adapter-cloudflare/worker.js | 2 +- packages/kit/src/exports/vite/index.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/adapter-cloudflare/worker.js b/packages/adapter-cloudflare/worker.js index 0fbc95583223..2f1cc7d9a93e 100644 --- a/packages/adapter-cloudflare/worker.js +++ b/packages/adapter-cloudflare/worker.js @@ -1,4 +1,4 @@ -import { Server } from '../kit/src/runtime/server/index.js'; +import { Server } from '@sveltejs/kit/internal/server'; // TODO: use prod variables when building // TODO: fix kit virtual module type issues when this file is consumed by an app import { diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index 55f7461f423b..c738e84791b4 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -384,10 +384,10 @@ async function kit({ svelte_config }) { optimizeDeps: { include: [ ...(config.optimizeDeps?.include ?? []), - // // @sveltejs/kit is excluded from optimization but some of its - // // dependencies are packaged as CommonJS so we need to include those - // '@sveltejs/kit > cookie', - // '@sveltejs/kit > set-cookie-parser' + // @sveltejs/kit is excluded from optimization but some of its + // dependencies are packaged as CommonJS so we need to include those + '@sveltejs/kit > cookie', + '@sveltejs/kit > set-cookie-parser' ], exclude: [...(new_config.optimizeDeps?.exclude ?? []), '__sveltekit/*'], extensions: config.optimizeDeps?.extensions ?? [], From 99d8a2f48bab0e71ef94e14723b99b7deb7c70be Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Mon, 28 Jul 2025 11:50:36 +0800 Subject: [PATCH 11/16] patch until cloudflare vite plugin releases --- packages/kit/src/exports/vite/index.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index c738e84791b4..f783e15c9947 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -397,6 +397,16 @@ async function kit({ svelte_config }) { } }; + // TODO: remove this once https://github.com/cloudflare/workers-sdk/pull/10054 is released + // @ts-ignore + config.environments.ssr.resolve.conditions = [ + // @ts-ignore + config.environments.ssr.resolve.conditions[0], + 'worker', + // @ts-ignore + ...config.environments.ssr.resolve.conditions.slice(1) + ]; + warn_overridden_config(config, new_config); return new_config; From 7f1feb176aaa7b5301dfec01ed8f3a1023ec63ed Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Mon, 28 Jul 2025 11:50:59 +0800 Subject: [PATCH 12/16] correctly handle static assets in dev --- packages/adapter-cloudflare/worker.js | 39 ++++++++++-------- packages/kit/src/exports/vite/dev/index.js | 48 ++++++++++++++++++---- 2 files changed, 62 insertions(+), 25 deletions(-) diff --git a/packages/adapter-cloudflare/worker.js b/packages/adapter-cloudflare/worker.js index 2f1cc7d9a93e..a65e992354b5 100644 --- a/packages/adapter-cloudflare/worker.js +++ b/packages/adapter-cloudflare/worker.js @@ -1,6 +1,7 @@ import { Server } from '@sveltejs/kit/internal/server'; // TODO: use prod variables when building // TODO: fix kit virtual module type issues when this file is consumed by an app +import { version } from '__sveltekit/environment'; import { manifest, env, @@ -12,7 +13,7 @@ import * as Cache from 'worktop/cfw.cache'; const app_path = `/${manifest.appPath}`; -const immutable = `${app_path}/immutable/`; +// const immutable = `${app_path}/immutable/`; const version_file = `${app_path}/version.json`; const server = new Server(manifest); @@ -41,25 +42,29 @@ export async function handleRequest(request, env, ctx) { const stripped_pathname = pathname.replace(/\/$/, ''); // files in /static, the service worker, and Vite imported server assets - let is_static_asset = false; - const filename = stripped_pathname.slice(base_path.length + 1); - if (filename) { - is_static_asset = - manifest.assets.has(filename) || - manifest.assets.has(filename + '/index.html') || - filename in manifest._.server_assets || - filename + '/index.html' in manifest._.server_assets; - } + // let is_static_asset = false; + // const filename = stripped_pathname.slice(base_path.length + 1); + // if (filename) { + // is_static_asset = + // manifest.assets.has(filename) || + // manifest.assets.has(filename + '/index.html') || + // filename in manifest._.server_assets || + // filename + '/index.html' in manifest._.server_assets; + // } let location = pathname.at(-1) === '/' ? stripped_pathname : pathname + '/'; - if ( - is_static_asset || - prerendered.has(pathname) || - pathname === version_file || - pathname.startsWith(immutable) - ) { - res = await env.ASSETS.fetch(request); + // TODO: we should only return the version var in dev because the version file is not written to disk + if (pathname === version_file) { + res = new Response(version); + // } else if ( + // is_static_asset || + // prerendered.has(pathname) || + // pathname === version_file || + // pathname.startsWith(immutable) + // ) { + // // TODO: verify if the ASSETS can be used during development + // res = await env.ASSETS.fetch(request); } else if (location && prerendered.has(location)) { // trailing slash redirect for prerendered pages if (search) location += search; diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 53346adf8c48..9d71cb14424d 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -158,9 +158,6 @@ export async function dev(vite, vite_config, svelte_config, dev_environment) { }); invalidate_page_options = node_analyser.invalidate_page_options; - // vite.environments.ssr.hot.send('', {}) - // vite.environments.ssr.hot.on() - for (const node of manifest_data.nodes) { if (node.universal) { const page_options = await node_analyser.get_page_options(node); @@ -475,14 +472,47 @@ export async function dev(vite, vite_config, svelte_config, dev_environment) { // const emulator = await svelte_config.kit.adapter?.emulate?.(); return () => { - const serve_static_middleware = vite.middlewares.stack.find( + // Vite will give a 403 on URLs like /test, /static, and /package.json preventing us from + // serving routes with those names. See https://github.com/vitejs/vite/issues/7363 + remove_static_middlewares(vite.middlewares); + + const serve_static_middleware_index = vite.middlewares.stack.findIndex( (middleware) => /** @type {function} */ (middleware.handle).name === 'viteServeStaticMiddleware' ); + const serve_static_middleware = vite.middlewares.stack[serve_static_middleware_index]; + vite.middlewares.stack[serve_static_middleware_index] = { + route: '', + /** @type {import('vite').Connect.NextHandleFunction} */ + handle: (req, res, next) => { + // Vite's base middleware strips out the base path. Restore it + const original_url = req.url; + req.url = req.originalUrl; + const base = `${vite.config.server.https ? 'https' : 'http'}://${ + req.headers[':authority'] || req.headers.host + }`; + + const decoded = decodeURI(new URL(base + req.url).pathname); + const file = posixify(path.resolve(decoded.slice(svelte_config.kit.paths.base.length + 1))); + const is_file = fs.existsSync(file) && !fs.statSync(file).isDirectory(); + const allowed = + !vite_config.server.fs.strict || + vite_config.server.fs.allow.some((dir) => file.startsWith(dir)); + + if (is_file && allowed) { + req.url = original_url; + // @ts-expect-error + serve_static_middleware.handle(req, res); + return; + } - // Vite will give a 403 on URLs like /test, /static, and /package.json preventing us from - // serving routes with those names. See https://github.com/vitejs/vite/issues/7363 - remove_static_middlewares(vite.middlewares); + if (!decoded.startsWith(svelte_config.kit.paths.base)) { + return not_found(req, res, svelte_config.kit.paths.base); + } + + next(); + } + }; vite.middlewares.stack.unshift({ route: '', @@ -520,6 +550,7 @@ export async function dev(vite, vite_config, svelte_config, dev_environment) { // return not_found(req, res, svelte_config.kit.paths.base); // } + // TODO: serve service worker in dev from cloudflare worker // if (decoded === svelte_config.kit.paths.base + '/service-worker.js') { // const resolved = resolve_entry(svelte_config.kit.files.serviceWorker); @@ -561,6 +592,7 @@ export async function dev(vite, vite_config, svelte_config, dev_environment) { // request: req // }); + // TODO: ensure this runs even when cloudflare vite plugin takes over // if (manifest_error) { // console.error(colors.bold().red(manifest_error.message)); @@ -623,7 +655,7 @@ export async function dev(vite, vite_config, svelte_config, dev_environment) { * @param {import('connect').Server} server */ function remove_static_middlewares(server) { - const static_middlewares = ['viteServeStaticMiddleware', 'viteServePublicMiddleware']; + const static_middlewares = ['viteServePublicMiddleware']; for (let i = server.stack.length - 1; i > 0; i--) { // @ts-expect-error using internals if (static_middlewares.includes(server.stack[i].handle.name)) { From 2ee2c2cc548150a76f98fd28a339ed550cccb799 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Tue, 29 Jul 2025 14:08:37 +0800 Subject: [PATCH 13/16] always optimize deps --- packages/adapter-cloudflare/worker.js | 37 +++++++++++++------------- packages/kit/src/exports/vite/index.js | 32 +++------------------- 2 files changed, 22 insertions(+), 47 deletions(-) diff --git a/packages/adapter-cloudflare/worker.js b/packages/adapter-cloudflare/worker.js index a65e992354b5..ca2ad64503cc 100644 --- a/packages/adapter-cloudflare/worker.js +++ b/packages/adapter-cloudflare/worker.js @@ -13,7 +13,7 @@ import * as Cache from 'worktop/cfw.cache'; const app_path = `/${manifest.appPath}`; -// const immutable = `${app_path}/immutable/`; +const immutable = `${app_path}/immutable/`; const version_file = `${app_path}/version.json`; const server = new Server(manifest); @@ -42,29 +42,30 @@ export async function handleRequest(request, env, ctx) { const stripped_pathname = pathname.replace(/\/$/, ''); // files in /static, the service worker, and Vite imported server assets - // let is_static_asset = false; - // const filename = stripped_pathname.slice(base_path.length + 1); - // if (filename) { - // is_static_asset = - // manifest.assets.has(filename) || - // manifest.assets.has(filename + '/index.html') || - // filename in manifest._.server_assets || - // filename + '/index.html' in manifest._.server_assets; - // } + let is_static_asset = false; + const filename = stripped_pathname.slice(base_path.length + 1); + if (filename) { + is_static_asset = + manifest.assets.has(filename) || + manifest.assets.has(filename + '/index.html') || + filename in manifest._.server_assets || + filename + '/index.html' in manifest._.server_assets; + } let location = pathname.at(-1) === '/' ? stripped_pathname : pathname + '/'; // TODO: we should only return the version var in dev because the version file is not written to disk if (pathname === version_file) { res = new Response(version); - // } else if ( - // is_static_asset || - // prerendered.has(pathname) || - // pathname === version_file || - // pathname.startsWith(immutable) - // ) { - // // TODO: verify if the ASSETS can be used during development - // res = await env.ASSETS.fetch(request); + // TODO: only in production + // } + // else if ( + // is_static_asset || + // prerendered.has(pathname) || + // pathname === version_file || + // pathname.startsWith(immutable) + // ) { + // res = await env.ASSETS.fetch(request); } else if (location && prerendered.has(location)) { // trailing slash redirect for prerendered pages if (search) location += search; diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index f783e15c9947..b7f506016c67 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -350,7 +350,7 @@ async function kit({ svelte_config }) { // TODO: move these to the Cloudflare adapter - // vite-plugin-cloudflare doesn't allow `ssr.external` but VPS and Kit set it + // @cloudflare/vite-plugin doesn't allow `ssr.external` but VPS and SvelteKit set it /** @type {import('vite').SSROptions} */ (config.ssr).external = undefined; /** @type {NonNullable} */ (new_config.ssr).external = undefined; @@ -361,38 +361,12 @@ async function kit({ svelte_config }) { // we need to set this because server environments don't inherit the top-level optimizeDeps option // see https://vite.dev/guide/api-environment.html#environments-configuration - // const optimize_deps = vite.mergeConfig( - // config?.optimizeDeps ?? {}, - // new_config?.optimizeDeps ?? {}, - // false - // ); - // new_config.environments = { - // ssr: { - // optimizeDeps: vite.mergeConfig( - // optimize_deps, - // { - // // ensure vite-plugin-cloudflare ignores virtual modules when optimising dependencies - // exclude: ['__sveltekit/*'] - // }, - // false - // ) - // } - // }; // TODO: find a better way to inherit top level optimizeDeps options new_config.environments = { ssr: { optimizeDeps: { - include: [ - ...(config.optimizeDeps?.include ?? []), - // @sveltejs/kit is excluded from optimization but some of its - // dependencies are packaged as CommonJS so we need to include those - '@sveltejs/kit > cookie', - '@sveltejs/kit > set-cookie-parser' - ], - exclude: [...(new_config.optimizeDeps?.exclude ?? []), '__sveltekit/*'], - extensions: config.optimizeDeps?.extensions ?? [], - entries: new_config.optimizeDeps?.entries ?? [], - esbuildOptions: config.optimizeDeps?.esbuildOptions + exclude: ['__sveltekit', '$app'], + // entries: new_config.optimizeDeps?.entries ?? [], } } }; From 463cd5d75aa5cddb8685ca5ff7761f8993b1316a Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Wed, 30 Jul 2025 14:06:43 +0800 Subject: [PATCH 14/16] remove workaround --- packages/kit/src/exports/vite/index.js | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index b7f506016c67..254bd7bf087c 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -359,28 +359,14 @@ async function kit({ svelte_config }) { /** @type {import('vite').SSROptions} */ (config.ssr).noExternal = undefined; /** @type {import('vite').SSROptions} */ (new_config.ssr).noExternal = undefined; - // we need to set this because server environments don't inherit the top-level optimizeDeps option - // see https://vite.dev/guide/api-environment.html#environments-configuration - // TODO: find a better way to inherit top level optimizeDeps options new_config.environments = { ssr: { optimizeDeps: { - exclude: ['__sveltekit', '$app'], - // entries: new_config.optimizeDeps?.entries ?? [], + exclude: ['__sveltekit', '$app'] } } }; - // TODO: remove this once https://github.com/cloudflare/workers-sdk/pull/10054 is released - // @ts-ignore - config.environments.ssr.resolve.conditions = [ - // @ts-ignore - config.environments.ssr.resolve.conditions[0], - 'worker', - // @ts-ignore - ...config.environments.ssr.resolve.conditions.slice(1) - ]; - warn_overridden_config(config, new_config); return new_config; From 7fdfe68f598c0262a97a15d000bf6ea27a609264 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Wed, 30 Jul 2025 15:34:33 +0800 Subject: [PATCH 15/16] fix svelte context not being set correctly --- packages/kit/src/exports/vite/index.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index 254bd7bf087c..778519e57445 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -361,8 +361,31 @@ async function kit({ svelte_config }) { new_config.environments = { ssr: { + // TODO: try to exclude `@sveltejs/kit` optimizeDeps: { - exclude: ['__sveltekit', '$app'] + // we need to exclude `svelte` so that `@sveltejs/kit` and user code + // use the same instance of `svelte` when setting and getting the context + exclude: ['__sveltekit', 'svelte'], + esbuildOptions: { + plugins: [ + { + name: 'sveltekit-alias', + setup(build) { + build.onResolve({ filter: /^\$app\// }, async (args) => { + const result = await build.resolve( + `${runtime_directory}/${args.path.slice(1)}`, + { kind: 'import-statement', resolveDir: args.resolveDir } + ); + if (result.errors.length > 0) { + return { errors: result.errors }; + } + return { path: result.path }; + }); + } + } + ] + }, + entries: [`${kit.files.routes}/**/+*.{svelte,js,ts}`] } } }; From ad109ad18509c8c2ed9944afc771aad30d2a1f5f Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Tue, 26 Aug 2025 09:47:22 +0800 Subject: [PATCH 16/16] im changing latops so just commit wip --- packages/adapter-cloudflare/worker.js | 5 ++++ packages/kit/src/exports/vite/index.js | 26 ++------------------ packages/kit/src/runtime/app/state/server.js | 2 +- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/packages/adapter-cloudflare/worker.js b/packages/adapter-cloudflare/worker.js index ca2ad64503cc..8e9cff5be85f 100644 --- a/packages/adapter-cloudflare/worker.js +++ b/packages/adapter-cloudflare/worker.js @@ -101,3 +101,8 @@ export async function handleRequest(request, env, ctx) { pragma = res.headers.get('cache-control') || ''; return pragma && res.status < 400 ? Cache.save(request, res, ctx) : res; } + +// Without this, server file changes will invalidate the entire server module graph +if (import.meta.hot) { + import.meta.hot.accept(); +} diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index 778519e57445..bf3fd25c165f 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -361,31 +361,9 @@ async function kit({ svelte_config }) { new_config.environments = { ssr: { - // TODO: try to exclude `@sveltejs/kit` optimizeDeps: { - // we need to exclude `svelte` so that `@sveltejs/kit` and user code - // use the same instance of `svelte` when setting and getting the context - exclude: ['__sveltekit', 'svelte'], - esbuildOptions: { - plugins: [ - { - name: 'sveltekit-alias', - setup(build) { - build.onResolve({ filter: /^\$app\// }, async (args) => { - const result = await build.resolve( - `${runtime_directory}/${args.path.slice(1)}`, - { kind: 'import-statement', resolveDir: args.resolveDir } - ); - if (result.errors.length > 0) { - return { errors: result.errors }; - } - return { path: result.path }; - }); - } - } - ] - }, - entries: [`${kit.files.routes}/**/+*.{svelte,js,ts}`] + include: ['@sveltejs/kit > cookie', '@sveltejs/kit > set-cookie-parser'], + exclude: ['@sveltejs/adapter-cloudflare', 'svelte'] } } }; diff --git a/packages/kit/src/runtime/app/state/server.js b/packages/kit/src/runtime/app/state/server.js index ef60721a895e..d003671d7b75 100644 --- a/packages/kit/src/runtime/app/state/server.js +++ b/packages/kit/src/runtime/app/state/server.js @@ -10,7 +10,7 @@ function context_dev(name) { return context(); } catch { throw new Error( - `Can only read '${name}' on the server during rendering (not in e.g. \`load\` functions), as it is bound to the current request via component context. This prevents state from leaking between users.` + + `Can only read '${name}' on the server during rendering (not in e.g. \`load\` functions), as it is bound to the current request via component context. This prevents state from leaking between users. ` + 'For more information, see https://svelte.dev/docs/kit/state-management#avoid-shared-state-on-the-server' ); }