From 32739ac0819be3f89d5c9b03a689d5743c8af057 Mon Sep 17 00:00:00 2001 From: Ottomated Date: Mon, 31 Aug 2026 14:39:44 -0700 Subject: [PATCH 1/4] feat: allow adapters to pass a function for vite config --- .changeset/fifty-breads-judge.md | 6 ++ packages/adapter-cloudflare/index.js | 20 +++--- packages/kit/src/core/adapt/builder.spec.js | 2 +- packages/kit/src/core/config/index.js | 6 ++ packages/kit/src/exports/public.d.ts | 73 ++++++++++++-------- packages/kit/src/exports/vite/index.js | 6 ++ packages/kit/src/types/internal.d.ts | 6 +- packages/kit/src/utils/features.js | 2 +- packages/kit/types/index.d.ts | 76 +++++++++++++-------- 9 files changed, 123 insertions(+), 74 deletions(-) create mode 100644 .changeset/fifty-breads-judge.md diff --git a/.changeset/fifty-breads-judge.md b/.changeset/fifty-breads-judge.md new file mode 100644 index 000000000000..7fab2d19e887 --- /dev/null +++ b/.changeset/fifty-breads-judge.md @@ -0,0 +1,6 @@ +--- +"@sveltejs/kit": minor +--- + +feat: allow adapters to pass a function for vite config + \ No newline at end of file diff --git a/packages/adapter-cloudflare/index.js b/packages/adapter-cloudflare/index.js index 68f731cdc25d..51801dd3378c 100644 --- a/packages/adapter-cloudflare/index.js +++ b/packages/adapter-cloudflare/index.js @@ -198,17 +198,15 @@ export default function (options = {}) { ).cf = globalThis.__sveltekit_cloudflare_platform?.cf; return request; }, - plugins: { - pre: [ - virtual_workers_module( - { - configPath: options.config, - ...options.platformProxy - }, - stub_import - ) - ] - } + plugins: [ + virtual_workers_module( + { + configPath: options.config, + ...options.platformProxy + }, + stub_import + ) + ] } }; } diff --git a/packages/kit/src/core/adapt/builder.spec.js b/packages/kit/src/core/adapt/builder.spec.js index 226e6436db42..868e66c1424e 100644 --- a/packages/kit/src/core/adapt/builder.spec.js +++ b/packages/kit/src/core/adapt/builder.spec.js @@ -20,7 +20,7 @@ test('copy files', () => { }; const builder = create_builder({ - config: /** @type {import('types').ValidatedConfig} */ (mocked), + config: /** @type {import('types').ValidatedConfig} */ (/** @type {unknown} */ (mocked)), // @ts-expect-error build_data: {}, // @ts-expect-error diff --git a/packages/kit/src/core/config/index.js b/packages/kit/src/core/config/index.js index 31ba3baa2952..bdb938a8f4a3 100644 --- a/packages/kit/src/core/config/index.js +++ b/packages/kit/src/core/config/index.js @@ -200,6 +200,12 @@ export function validate_config(config) { } } + if (typeof config.adapter?.vite === 'function') { + validated.adapter.vite = config.adapter.vite({ + config: validated + }); + } + return validated; } catch (e) { const error = /** @type {Error} */ (e); diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index f243771587c7..29c499dece33 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -26,7 +26,7 @@ type Span = import('@opentelemetry/api').Span; /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. */ -export interface Adapter { +export interface Adapter { /** * The name of the adapter, using for logging. Will typically correspond to the package name. */ @@ -57,34 +57,49 @@ export interface Adapter { * during dev, build and prerendering. */ emulate?: () => MaybePromise; - vite?: { - /** - * This function overrides the default behavior during Vite's dev and preview modes - * to convert an `http.IncomingMessage` to a `Request` object. - * To call the original `setRequest` function, import it from `@sveltejs/kit/node`. - * @since 3.0.0 - */ - getRequest?: typeof getRequest; - /** - * This function overrides the default behavior in Vite's dev and preview modes - * to write a `Response` object to a `http.ServerResponse`. - * To call the original `setResponse` function, import it from `@sveltejs/kit/node`. - * @since 3.0.0 - */ - setResponse?: typeof setResponse; - plugins?: { - /** - * Vite plugins placed before any of SvelteKit's own plugins. - * @since 3.0.0 - */ - pre?: Plugin[]; - /** - * Vite plugins placed after any of SvelteKit's own plugins. - * @since 3.0.0 - */ - post?: Plugin[]; - }; - }; + /** + * Options for configuring and interacting with Vite + * @since 3.0.0 + */ + vite?: ViteResolved extends true + ? AdapterViteConfig + : AdapterViteConfig | ((ctx: { config: ValidatedConfig }) => AdapterViteConfig); +} + +interface AdapterViteConfig { + /** + * This function overrides the default behavior during Vite's dev and preview modes + * to convert an `http.IncomingMessage` to a `Request` object. + * To call the original `setRequest` function, import it from `@sveltejs/kit/node`. + * @since 3.0.0 + */ + getRequest?: typeof getRequest; + /** + * This function overrides the default behavior in Vite's dev and preview modes + * to write a `Response` object to a `http.ServerResponse`. + * To call the original `setResponse` function, import it from `@sveltejs/kit/node`. + * @since 3.0.0 + */ + setResponse?: typeof setResponse; + /** + * Vite plugins injected by the adapter. By default, + * they are placed before SvelteKit's plugins. + * @since 3.0.0 + */ + plugins?: + | Plugin[] + | { + /** + * Vite plugins placed before any of SvelteKit's own plugins. + * @since 3.0.0 + */ + pre?: Plugin[]; + /** + * Vite plugins placed after any of SvelteKit's own plugins. + * @since 3.0.0 + */ + post?: Plugin[]; + }; } export type LoadProperties | void> = input extends void diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index f46915e1068e..4756c11ff221 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -637,6 +637,12 @@ function kit({ svelte_config }) { /** @type {(() => Promise) | null} */ let finalise = null; + if (Array.isArray(svelte_config.adapter?.vite?.plugins)) { + svelte_config.adapter.vite.plugins = { + pre: svelte_config.adapter.vite.plugins + }; + } + return /** @type {Plugin[]} */ ( [ svelte_config.adapter?.vite?.plugins?.pre, diff --git a/packages/kit/src/types/internal.d.ts b/packages/kit/src/types/internal.d.ts index ab935ae0938a..62320d075933 100644 --- a/packages/kit/src/types/internal.d.ts +++ b/packages/kit/src/types/internal.d.ts @@ -8,7 +8,8 @@ import { Actions, RequestEvent, Emulator, - HttpError + HttpError, + Adapter } from '@sveltejs/kit'; import { RemoteFormIssue, RemoteQuery, RemoteLiveQuery } from '$app/server'; import { Config } from '@sveltejs/kit/vite'; @@ -592,7 +593,8 @@ export interface Uses { search_params: Set; } -export type ValidatedConfig = RecursiveRequired> & { +export type ValidatedConfig = RecursiveRequired> & { + adapter: Adapter; preprocess: Config['preprocess']; }; diff --git a/packages/kit/src/utils/features.js b/packages/kit/src/utils/features.js index e39032fcf68d..66dc7b874613 100644 --- a/packages/kit/src/utils/features.js +++ b/packages/kit/src/utils/features.js @@ -2,7 +2,7 @@ * @param {string} route_id * @param {Record} config * @param {string} feature - * @param {import('@sveltejs/kit').Adapter | undefined} adapter + * @param {import('@sveltejs/kit').Adapter | undefined} adapter */ export function check_feature(route_id, config, feature, adapter) { if (!adapter) return; diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 6ad1b0c12309..4e1538b1ee52 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -13,7 +13,7 @@ declare module '@sveltejs/kit' { /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. */ - export interface Adapter { + export interface Adapter { /** * The name of the adapter, using for logging. Will typically correspond to the package name. */ @@ -44,34 +44,49 @@ declare module '@sveltejs/kit' { * during dev, build and prerendering. */ emulate?: () => MaybePromise; - vite?: { - /** - * This function overrides the default behavior during Vite's dev and preview modes - * to convert an `http.IncomingMessage` to a `Request` object. - * To call the original `setRequest` function, import it from `@sveltejs/kit/node`. - * @since 3.0.0 - */ - getRequest?: typeof getRequest; - /** - * This function overrides the default behavior in Vite's dev and preview modes - * to write a `Response` object to a `http.ServerResponse`. - * To call the original `setResponse` function, import it from `@sveltejs/kit/node`. - * @since 3.0.0 - */ - setResponse?: typeof setResponse; - plugins?: { - /** - * Vite plugins placed before any of SvelteKit's own plugins. - * @since 3.0.0 - */ - pre?: Plugin[]; - /** - * Vite plugins placed after any of SvelteKit's own plugins. - * @since 3.0.0 - */ - post?: Plugin[]; - }; - }; + /** + * Options for configuring and interacting with Vite + * @since 3.0.0 + */ + vite?: ViteResolved extends true + ? AdapterViteConfig + : AdapterViteConfig | ((ctx: { config: ValidatedConfig }) => AdapterViteConfig); + } + + interface AdapterViteConfig { + /** + * This function overrides the default behavior during Vite's dev and preview modes + * to convert an `http.IncomingMessage` to a `Request` object. + * To call the original `setRequest` function, import it from `@sveltejs/kit/node`. + * @since 3.0.0 + */ + getRequest?: typeof getRequest; + /** + * This function overrides the default behavior in Vite's dev and preview modes + * to write a `Response` object to a `http.ServerResponse`. + * To call the original `setResponse` function, import it from `@sveltejs/kit/node`. + * @since 3.0.0 + */ + setResponse?: typeof setResponse; + /** + * Vite plugins injected by the adapter. By default, + * they are placed before SvelteKit's plugins. + * @since 3.0.0 + */ + plugins?: + | Plugin[] + | { + /** + * Vite plugins placed before any of SvelteKit's own plugins. + * @since 3.0.0 + */ + pre?: Plugin[]; + /** + * Vite plugins placed after any of SvelteKit's own plugins. + * @since 3.0.0 + */ + post?: Plugin[]; + }; } export type LoadProperties | void> = input extends void @@ -931,7 +946,8 @@ declare module '@sveltejs/kit' { : T[K]; // Use the exact type for everything else }; - type ValidatedConfig = RecursiveRequired> & { + type ValidatedConfig = RecursiveRequired> & { + adapter: Adapter; preprocess: Config['preprocess']; }; /** From 41a7ea4869ceb65c85954a1e385c98ffc9c480fe Mon Sep 17 00:00:00 2001 From: Ottomated Date: Tue, 1 Sep 2026 10:18:07 -0700 Subject: [PATCH 2/4] remove generic --- packages/kit/src/exports/public.d.ts | 8 +++----- packages/kit/src/types/internal.d.ts | 5 +++-- packages/kit/src/utils/features.js | 2 +- packages/kit/types/index.d.ts | 10 ++++------ 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 29c499dece33..5cd549540ccb 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -26,7 +26,7 @@ type Span = import('@opentelemetry/api').Span; /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. */ -export interface Adapter { +export interface Adapter { /** * The name of the adapter, using for logging. Will typically correspond to the package name. */ @@ -61,12 +61,10 @@ export interface Adapter { * Options for configuring and interacting with Vite * @since 3.0.0 */ - vite?: ViteResolved extends true - ? AdapterViteConfig - : AdapterViteConfig | ((ctx: { config: ValidatedConfig }) => AdapterViteConfig); + vite?: AdapterViteConfig | ((ctx: { config: ValidatedConfig }) => AdapterViteConfig); } -interface AdapterViteConfig { +export interface AdapterViteConfig { /** * This function overrides the default behavior during Vite's dev and preview modes * to convert an `http.IncomingMessage` to a `Request` object. diff --git a/packages/kit/src/types/internal.d.ts b/packages/kit/src/types/internal.d.ts index 62320d075933..8a107863f31a 100644 --- a/packages/kit/src/types/internal.d.ts +++ b/packages/kit/src/types/internal.d.ts @@ -9,7 +9,8 @@ import { RequestEvent, Emulator, HttpError, - Adapter + Adapter, + AdapterViteConfig } from '@sveltejs/kit'; import { RemoteFormIssue, RemoteQuery, RemoteLiveQuery } from '$app/server'; import { Config } from '@sveltejs/kit/vite'; @@ -594,7 +595,7 @@ export interface Uses { } export type ValidatedConfig = RecursiveRequired> & { - adapter: Adapter; + adapter: Adapter & { vite?: AdapterViteConfig }; preprocess: Config['preprocess']; }; diff --git a/packages/kit/src/utils/features.js b/packages/kit/src/utils/features.js index 66dc7b874613..e39032fcf68d 100644 --- a/packages/kit/src/utils/features.js +++ b/packages/kit/src/utils/features.js @@ -2,7 +2,7 @@ * @param {string} route_id * @param {Record} config * @param {string} feature - * @param {import('@sveltejs/kit').Adapter | undefined} adapter + * @param {import('@sveltejs/kit').Adapter | undefined} adapter */ export function check_feature(route_id, config, feature, adapter) { if (!adapter) return; diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 4e1538b1ee52..1b6bee761ab2 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -13,7 +13,7 @@ declare module '@sveltejs/kit' { /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. */ - export interface Adapter { + export interface Adapter { /** * The name of the adapter, using for logging. Will typically correspond to the package name. */ @@ -48,12 +48,10 @@ declare module '@sveltejs/kit' { * Options for configuring and interacting with Vite * @since 3.0.0 */ - vite?: ViteResolved extends true - ? AdapterViteConfig - : AdapterViteConfig | ((ctx: { config: ValidatedConfig }) => AdapterViteConfig); + vite?: AdapterViteConfig | ((ctx: { config: ValidatedConfig }) => AdapterViteConfig); } - interface AdapterViteConfig { + export interface AdapterViteConfig { /** * This function overrides the default behavior during Vite's dev and preview modes * to convert an `http.IncomingMessage` to a `Request` object. @@ -947,7 +945,7 @@ declare module '@sveltejs/kit' { }; type ValidatedConfig = RecursiveRequired> & { - adapter: Adapter; + adapter: Adapter & { vite?: AdapterViteConfig }; preprocess: Config['preprocess']; }; /** From 68a8a09045927228295f4d88b5974961e96ad53d Mon Sep 17 00:00:00 2001 From: ottomated <31470743+ottomated@users.noreply.github.com> Date: Tue, 1 Sep 2026 10:20:30 -0700 Subject: [PATCH 3/4] Update .changeset/fifty-breads-judge.md Co-authored-by: Tee Ming --- .changeset/fifty-breads-judge.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/fifty-breads-judge.md b/.changeset/fifty-breads-judge.md index 7fab2d19e887..4b49fc2d8725 100644 --- a/.changeset/fifty-breads-judge.md +++ b/.changeset/fifty-breads-judge.md @@ -2,5 +2,5 @@ "@sveltejs/kit": minor --- -feat: allow adapters to pass a function for vite config +feat: allow adapters to receive the Svelte config as a function argument when adding Vite plugins \ No newline at end of file From 0c1556ea1e5fb00cff14e219af3f0bbdb84a02ee Mon Sep 17 00:00:00 2001 From: Ottomated Date: Tue, 1 Sep 2026 10:54:03 -0700 Subject: [PATCH 4/4] remove cast --- packages/kit/src/core/adapt/builder.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/src/core/adapt/builder.spec.js b/packages/kit/src/core/adapt/builder.spec.js index 47995aa7a8a5..9b0f97144bae 100644 --- a/packages/kit/src/core/adapt/builder.spec.js +++ b/packages/kit/src/core/adapt/builder.spec.js @@ -41,7 +41,7 @@ test('copy files', () => { }; const builder = create_builder({ - config: /** @type {import('types').ValidatedConfig} */ (/** @type {unknown} */ (mocked)), + config: /** @type {import('types').ValidatedConfig} */ (mocked), // @ts-expect-error build_data: {}, // @ts-expect-error