fix: eagerly initialise dynamic env vars from process.env at module-eval time#16303
Conversation
|
Install the latest version of pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/3508875d9d7fd77328f4c541ee97774f4d73e9bdOpen in |
🦋 Changeset detectedLatest commit: 3508875 The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
90d3458 to
a436ecb
Compare
8b29742 to
4a96498
Compare
a436ecb to
2b5ae26
Compare
7ba2ae9 to
348e72d
Compare
348e72d to
265a930
Compare
Previously, `$app/env/private` and `$app/env/public` dynamic variable values were only populated when `Server.init()` called `set_env()`. If any module reading these values was evaluated before `Server.init()` ran (e.g. via bundler chunk colocation with `instrumentation.server.js`), the values would be silently `undefined`. `builder.instrument()` now accepts an `env` option. When provided, the generated facade creates a separate init module that imports `set_env` and calls it with the platform's env before instrumentation is imported. This ensures dynamic env vars are populated (and validated) before any instrumentation or application code is evaluated. Adapters that have env available at module-load time pass the appropriate expression: - adapter-node, adapter-vercel (serverless): `process.env` - adapter-cloudflare: `env` from `cloudflare:workers` - adapter-vercel (edge), adapter-netlify (serverless): env init via `generateText` If required env vars are missing, `set_env` will throw — this is intentional, as the app cannot function without them.
265a930 to
3508875
Compare
|
Tested this branch against the repro for #16288 (adapter-node + The facade written in |
|
Yeah, this is still a draft, not ready yet 😅 |
Previously,
$app/env/privateand$app/env/publicdynamic variable values were only populated whenServer.init()calledset_env(). If any module reading these values was evaluated beforeServer.init()ran — for example via bundler chunk colocation withinstrumentation.server.js(see #16288) — the values would be silentlyundefined.What changed
builder.instrument()now accepts anenvoption. When provided, the generated facade creates a separate init module that importsset_envfrom the env module and calls it with the platform's env before instrumentation is imported. Since static imports are evaluated in order, this ensures env is populated (and validated) before any instrumentation or application code runs.Each adapter passes the appropriate env source:
process.envenvfromcloudflare:workers(available at module scope)generateTextfacadesIf required env vars are missing,
set_envwill throw a clear validation error at startup — this is intentional, as the app cannot function without them.Why?
This eliminates the entire class of "captured
undefined" bugs regardless of when a module evaluates, and works across all platforms (not just Node-like ones) because each adapter provides its own env source.Stacked on top of #16302 (which externalizes
@opentelemetry/apito prevent the primary colocation vector). Both fixes are complementary:@opentelemetry/apito prevent chunk colocation #16302 fixes the isolation problem (prevents colocation via the OTEL shared dep).