fix(dev): avoid dynamic import.meta.env access in dev notice helper#403
fix(dev): avoid dynamic import.meta.env access in dev notice helper#403stickerdaniel wants to merge 1 commit into
Conversation
Vite's module-runner rejects dynamic property access on import.meta.env
("Dynamic access of import.meta.env is not supported"), so every
SvelteKit dev request was crashing with a 500 in hooks.server.ts before
any +error.svelte could render.
Switch the SvelteKit/browser dev detection from
`(import.meta as { env?: { DEV?: boolean } }).env?.DEV`
to
`process.env.NODE_ENV === 'development'`.
SvelteKit SSR reads NODE_ENV from Node at runtime; the browser bundle
gets it via Vite's static define replacement. No Vite-specific
import.meta access, so no dynamic-access rejection, and the module
type-checks cleanly under both the Vite tsconfig and the Convex
tsconfig without @ts-expect-error escape hatches.
The Vitest case sets NODE_ENV='development' in beforeEach and restores
it in afterEach so the existing "logs a vite-public feature" test still
exercises the live dev path.
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
saas-starter | f8c1ddd | Commit Preview URL Branch Preview URL |
May 23 2026, 11:12 PM |
There was a problem hiding this comment.
Pull request overview
Fixes a SvelteKit dev-server crash caused by Vite’s module-runner rejecting dynamic import.meta.env access in the shared devNotice helper (which runs early via hooks.server.ts), and updates the unit test to keep exercising the dev-only path.
Changes:
- Replace the non-Convex dev check in
isDev()from a dynamically-accessedimport.meta.envvalue toprocess.env.NODE_ENV === 'development'. - Update the
devNoticeVitest to set/restoreNODE_ENVso the dev path is covered.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/lib/dev/notice.ts | Updates dev-detection logic and documentation to avoid dynamic import.meta.env access. |
| src/lib/dev/notice.test.ts | Adjusts unit tests to force the dev path by setting NODE_ENV during tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // SvelteKit SSR reads NODE_ENV from Node; the browser gets it via Vite's | ||
| // static define replacement at build time. Avoids the dynamic | ||
| // `import.meta.env` access that Vite's module-runner rejects, and | ||
| // type-checks under both the Vite tsconfig and the Convex tsconfig | ||
| // (which has @types/node but not Vite's import.meta augmentations). | ||
| return typeof process !== 'undefined' && process.env?.NODE_ENV === 'development'; |
| * **Active only in dev** (`NODE_ENV === 'development'` under SvelteKit and | ||
| * in the browser, `LOCAL_CONVEX_DEV` on the Convex backend). The helper is | ||
| * a no-op in production builds and on cloud deployments. |

SvelteKit dev was crashing every request with HTTP 500 because Vite's module-runner now rejects dynamic property access on
import.meta.env("Dynamic access of import.meta.env is not supported"). The crash happened insrc/lib/dev/notice.tsviahooks.server.ts:21, before any+error.sveltecould render, so every page onbun run devlooked broken.The notice helper had to dodge
import.meta.env.DEVoriginally because the module is imported from both the Vite tsconfig (SvelteKit, browser) and the Convex tsconfig (Convex isolates), and the Convex tsconfig has no Vite types. The previous workaround was a cast to a partial type, but the runtime access was still dynamic, which is what Vite's module-runner objects to.Switched the SvelteKit/browser dev check from
import.meta.env.DEVtoprocess.env.NODE_ENV === 'development'. SvelteKit SSR gets NODE_ENV from Node at runtime, and Vite statically replacesprocess.env.NODE_ENVin the browser bundle, so the check works in both environments.@types/nodecovers it under both tsconfigs, no@ts-expect-errorneeded. The Convex-scope branch is unchanged.The Vitest case now sets
NODE_ENV='development'inbeforeEachand restores it inafterEachso the live "logs a vite-public feature" assertion still exercises the dev path.bun scripts/static-checks.tsandbun run test:unit src/lib/dev/notice.test.tspass. Verified live:curl http://localhost:5175/enreturned HTTP 500 before the fix and HTTP 200 after, on a fresh dev server in this worktree.