fix(sveltekit): Read SvelteKit config from the Vite plugin - #23678
Conversation
SvelteKit 3 removed `svelte.config.js` (adapter, `files` and `outDir` now go to the `sveltekit()` Vite plugin), and SvelteKit 2.66+ lets users move their config there too. The SDK still imported `svelte.config.js`, so those setups silently fell back to defaults - breaking source map upload paths and `rewriteFrames` for custom adapter `out`, `outDir` or hooks paths. Read the config from the SvelteKit Vite plugin's `api.options` instead, normalized across both majors. `svelte.config.js` stays as the fallback - SvelteKit only exposes `api.options` from 2.62 on, so older 2.x apps still resolve through the file. Not `@sveltejs/load-config`: it re-resolves the `vite.config.js` we're being constructed by, so it waits on itself and hangs - and it reads this same `api.options` anyway. Co-Authored-By: Claude Opus 5 <[email protected]>
|
bugbot run |
size-limit report 📦
|
`sveltekit()` is an async factory in both SvelteKit majors, so the plugins array Vite passes to `config` hooks still holds an unresolved promise where the SvelteKit plugin will be - the config is only findable in `configResolved`. Awaiting it from the source maps plugin's `config` hook blocked the very phase that would resolve it, hanging `vite build` whenever source map upload was enabled (the default). Record the user's `build.sourcemap` setting in `config` (it has to be read before our own source map settings plugin overwrites it) and resolve the adapter output dir in `configResolved`, which is still early enough to run the adapter before the build writes anything. The e2e apps all disable source map upload, so nothing exercised this path; the Vite integration test now uses an async SvelteKit factory with uploads enabled, and hangs without this fix. Co-Authored-By: Claude Opus 5 <[email protected]>
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 2fd3d9e. Configure here.
`process_config()` resolves `outDir` and `files.hooks.*` against the cwd before SvelteKit exposes them on the Vite plugin's `api.options`, so reading the config from there handed us absolute paths where `svelte.config.js` gave relative ones. That broke two things: the hooks file regexp gained a leading `//` and stopped matching any Vite module id, so the global values were no longer injected into `hooks.server.*` at all; and `__sentry_sveltekit_output_dir` became a build machine path that `rewriteFrames` can't match at runtime anywhere else. Normalizing in `normalizeKitConfig()` covers both sources and also drops the platform separator, which would have broken the same matching on Windows. Also settle the config promise in a `finally` so a throwing `configResolved` can't leave the build hanging on `get()` with no error. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01P8qBB5MAGR4KYNfMWJcuCF
Corrects three that claimed something the code doesn't do: `adapter` is consumed by `sentrySvelteKit()` rather than the resolver; the resolver being first in the array isn't what lets the other plugins await it (Vite runs `configResolved` concurrently); and `build.sourcemap` is read after our own source map settings plugin has already set it, not before - renamed the variable to match. The rest is trimming: no new facts, just fewer lines saying them. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01P8qBB5MAGR4KYNfMWJcuCF
Lms24
left a comment
There was a problem hiding this comment.
Nice! Had one question but otherwise looks good!
| /** | ||
| * Picks the SvelteKit options off the SvelteKit Vite plugin, if it's registered. | ||
| * Exported only for testing. | ||
| */ | ||
| export function findKitConfigInPlugins(plugins: unknown): ResolvedKitConfig | undefined { |
There was a problem hiding this comment.
q/to double check: Does this work even though our plugin must be registered before the sveltekit plugin as per https://docs.sentry.io/platforms/javascript/guides/sveltekit/manual-setup/#configure-vite?
If this is an issue, maybe we can set enforce: 'post'? (not verified, just an idea)
There was a problem hiding this comment.
configResolved gets the fully resolved plugin list 👍
Backport of: #23678 ## Differences to the original PR - `src/vite/sentryVitePlugins.ts`: dropped the `warnOnRemovedBuildOptions(options, ['unstable_sentryVitePluginOptions'])` call. That line is pre-existing context on `develop` from #23366, which removed the option in v11 — v10 still supports it, and `warnOnRemovedBuildOptions` isn't exported from v10's `@sentry/core`. - `src/vite/sentryVitePlugins.ts` (`generateVitePluginOptions`): kept v10's deprecated `sourceMapsUploadOptions` / `unstable_sentryVitePluginOptions` merging untouched. Only this PR's actual change was applied — `adapter` is now destructured out of the options handed to the Vite plugin and the explicit `adapter: svelteKitPluginOptions.adapter` was dropped. The placeholder is `_filtered5` rather than `_filtered3` because v10 filters two extra deprecated options. - `test/vite/sentrySvelteKitPlugins.test.ts`: plugin-count expectations are v10's counts plus one for the new kit config resolver (8/3/4/7), not `develop`'s (9/4/5/8). v10 has no orchestrion Vite plugin — that's #22768, v11-only.
SvelteKit 3 removed
svelte.config.js(adapter,filesandoutDirnow go to thesveltekit()Vite plugin), and SvelteKit 2.66+ lets users move their config there too. The SDK still importedsvelte.config.js, so those setups silently fell back to defaults, breaking source map upload paths andrewriteFramesfor custom adapterout,outDiror hooks paths.The config now comes from the SvelteKit Vite plugin's
api.options, normalized across both majors.svelte.config.jsstays as the fallback — SvelteKit only exposesapi.optionsfrom 2.62 on, so older 2.x apps still resolve through the file.Why not
@sveltejs/load-config?It re-resolves the
vite.config.jswe're being constructed by, so itwaits on itself and hangs (verified on Vite 8) — and it reads this same
api.optionsanyway.