feat: allow $env to be used outside Vite context#15250
Conversation
🦋 Changeset detectedLatest commit: 2e937dc The changes in this PR will be included in the next version bump. 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 |
I don't know if one vs the other is better. |
I guess only the STATIC secrets need to be? Because presumably the DYNAMIC secrets get read from |
|
One last thought... Even though this isn't a breaking change, I would personally add it to the 3.0 milestone because it is highly demanded and I think that people are more likely to learn about it if it's part of the 3.0 release notes and it will make the 3.0 release more exciting |
| /** | ||
| * Load environment variables from process.env and .env files | ||
| * @param {import('types').ValidatedKitConfig['env']} env_config | ||
| * @param {string} mode | ||
| */ | ||
| export function get_env(env_config, mode) { | ||
| const { publicPrefix: public_prefix, privatePrefix: private_prefix } = env_config; | ||
| const env = loadEnv(mode, env_config.dir, ''); | ||
|
|
||
| return { | ||
| public: filter_env(env, public_prefix, private_prefix), | ||
| private: filter_env(env, private_prefix, public_prefix) | ||
| }; | ||
| } | ||
|
|
There was a problem hiding this comment.
This needs to be moved to a separate module to avoid type errors when users import $env/dynamic/* and they type check their code. We're currently using it in the generated module to avoid serialising users' dynamic env vars
|
Are there plans to include $app/environment too? |
Yes, but I'm wondering if it's just about making everything in |
| test.describe('$env access outside the Vite pipeline', () => { | ||
| test('$env/static/public', async () => { | ||
| const env = await import('$env/static/public'); | ||
| expect(env.PUBLIC_DYNAMIC).toBe('accessible anywhere/evaluated at run time'); | ||
| }); | ||
|
|
||
| test('$env/static/private', async () => { | ||
| const env = await import('$env/static/private'); | ||
| expect(env.PRIVATE_STATIC).toBe('accessible to server-side code/replaced at build time'); | ||
| }); | ||
|
|
||
| test('$env/dynamic/public', async () => { | ||
| const { env } = await import('$env/dynamic/public'); | ||
| expect(env.PUBLIC_DYNAMIC).toBe('accessible anywhere/evaluated at run time'); | ||
| }); | ||
|
|
||
| test('$env/dynamic/private', async () => { | ||
| const { env } = await import('$env/dynamic/private'); | ||
| expect(env.PRIVATE_DYNAMIC).toBe('accessible to server-side code/evaluated at run time'); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
We could also change these to Playwright component tests, which is what the majority of users are facing issues with.
|
@benmccann do we still want to merge this into the version-3 branch instead of main? |
I don't have strong feelings either way. I'm curious if @Rich-Harris and the rest of the team think it's better to hold it back for marketing impact or just get it out there sooner |
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to version-3, this PR will be updated.⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ `version-3` is currently in **pre mode** so this branch has prereleases rather than normal releases. If you want to exit prereleases, run `changeset pre exit` on `version-3`.⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ # Releases ## @sveltejs/adapter-auto@8.0.0-next.0 ### Major Changes - breaking: require SvelteKit 3 ([#15506](#15506)) ### Patch Changes - Updated dependencies [[`fa335bd`](fa335bd), [`3031d89`](3031d89), [`cb9d416`](cb9d416), [`caf3a18`](caf3a18), [`4777827`](4777827), [`a2792e2`](a2792e2), [`ba36148`](ba36148), [`48e8710`](48e8710), [`e2f3075`](e2f3075), [`047d6a0`](047d6a0), [`87603d1`](87603d1), [`096962c`](096962c), [`d545970`](d545970), [`e2f3075`](e2f3075), [`d06affc`](d06affc), [`8af47eb`](8af47eb), [`e2f3075`](e2f3075), [`5c4d130`](5c4d130), [`3f11f35`](3f11f35), [`caf3a18`](caf3a18), [`8823037`](8823037), [`1d76212`](1d76212), [`0dc0548`](0dc0548), [`00d81fa`](00d81fa)]: - @sveltejs/kit@3.0.0-next.0 ## @sveltejs/adapter-cloudflare@8.0.0-next.0 ### Major Changes - breaking: upgrade `@cloudflare/workers-types` to 4.20260219.0 ([#15347](#15347)) - breaking: upgrade minimum `wrangler` version to ^4.67.0 ([#15347](#15347)) - breaking: remove `platform.context` in favour of `platform.ctx` ([#15347](#15347)) - breaking: require SvelteKit 3 ([#15506](#15506)) ### Patch Changes - chore: check the `WORKERS_CI` environment variable to determine if we're building for Cloudflare Workers ([#13733](#13733)) - Updated dependencies [[`fa335bd`](fa335bd), [`3031d89`](3031d89), [`cb9d416`](cb9d416), [`caf3a18`](caf3a18), [`4777827`](4777827), [`a2792e2`](a2792e2), [`ba36148`](ba36148), [`48e8710`](48e8710), [`e2f3075`](e2f3075), [`047d6a0`](047d6a0), [`87603d1`](87603d1), [`096962c`](096962c), [`d545970`](d545970), [`e2f3075`](e2f3075), [`d06affc`](d06affc), [`8af47eb`](8af47eb), [`e2f3075`](e2f3075), [`5c4d130`](5c4d130), [`3f11f35`](3f11f35), [`caf3a18`](caf3a18), [`8823037`](8823037), [`1d76212`](1d76212), [`0dc0548`](0dc0548), [`00d81fa`](00d81fa)]: - @sveltejs/kit@3.0.0-next.0 ## @sveltejs/adapter-netlify@7.0.0-next.0 ### Major Changes - chore: use `rolldown` for edge function bundling ([#15432](#15432)) - breaking: write output that conforms to the stable [Netlify Frameworks API](https://docs.netlify.com/build/frameworks/frameworks-api/). ([#15294](#15294)) Deploying and previewing with Netlify CLI now requires [v17.31.0](https://github.com/netlify/cli/releases/tag/v17.31.0) or later. Run `npm i -g netlify-cli@latest` to upgrade. - breaking: require SvelteKit 3 ([#15506](#15506)) - breaking: edge function build target is now `es2022` ([#15432](#15432)) ### Patch Changes - Updated dependencies [[`fa335bd`](fa335bd), [`3031d89`](3031d89), [`cb9d416`](cb9d416), [`caf3a18`](caf3a18), [`4777827`](4777827), [`a2792e2`](a2792e2), [`ba36148`](ba36148), [`48e8710`](48e8710), [`e2f3075`](e2f3075), [`047d6a0`](047d6a0), [`87603d1`](87603d1), [`096962c`](096962c), [`d545970`](d545970), [`e2f3075`](e2f3075), [`d06affc`](d06affc), [`8af47eb`](8af47eb), [`e2f3075`](e2f3075), [`5c4d130`](5c4d130), [`3f11f35`](3f11f35), [`caf3a18`](caf3a18), [`8823037`](8823037), [`1d76212`](1d76212), [`0dc0548`](0dc0548), [`00d81fa`](00d81fa)]: - @sveltejs/kit@3.0.0-next.0 ## @sveltejs/adapter-node@6.0.0-next.0 ### Major Changes - chore: migrate from rollup to rolldown ([#15297](#15297)) - breaking: require SvelteKit 3 ([#15506](#15506)) ### Patch Changes - Updated dependencies [[`fa335bd`](fa335bd), [`3031d89`](3031d89), [`cb9d416`](cb9d416), [`caf3a18`](caf3a18), [`4777827`](4777827), [`a2792e2`](a2792e2), [`ba36148`](ba36148), [`48e8710`](48e8710), [`e2f3075`](e2f3075), [`047d6a0`](047d6a0), [`87603d1`](87603d1), [`096962c`](096962c), [`d545970`](d545970), [`e2f3075`](e2f3075), [`d06affc`](d06affc), [`8af47eb`](8af47eb), [`e2f3075`](e2f3075), [`5c4d130`](5c4d130), [`3f11f35`](3f11f35), [`caf3a18`](caf3a18), [`8823037`](8823037), [`1d76212`](1d76212), [`0dc0548`](0dc0548), [`00d81fa`](00d81fa)]: - @sveltejs/kit@3.0.0-next.0 ## @sveltejs/adapter-static@4.0.0-next.0 ### Major Changes - breaking: require SvelteKit 3 ([#15506](#15506)) ### Patch Changes - Updated dependencies [[`fa335bd`](fa335bd), [`3031d89`](3031d89), [`cb9d416`](cb9d416), [`caf3a18`](caf3a18), [`4777827`](4777827), [`a2792e2`](a2792e2), [`ba36148`](ba36148), [`48e8710`](48e8710), [`e2f3075`](e2f3075), [`047d6a0`](047d6a0), [`87603d1`](87603d1), [`096962c`](096962c), [`d545970`](d545970), [`e2f3075`](e2f3075), [`d06affc`](d06affc), [`8af47eb`](8af47eb), [`e2f3075`](e2f3075), [`5c4d130`](5c4d130), [`3f11f35`](3f11f35), [`caf3a18`](caf3a18), [`8823037`](8823037), [`1d76212`](1d76212), [`0dc0548`](0dc0548), [`00d81fa`](00d81fa)]: - @sveltejs/kit@3.0.0-next.0 ## @sveltejs/adapter-vercel@7.0.0-next.0 ### Major Changes - chore: use `rolldown` for edge function bundling ([#15432](#15432)) - breaking: edge function build target is now `es2022` ([#15432](#15432)) ### Patch Changes - Updated dependencies [[`fa335bd`](fa335bd), [`3031d89`](3031d89), [`cb9d416`](cb9d416), [`caf3a18`](caf3a18), [`4777827`](4777827), [`a2792e2`](a2792e2), [`ba36148`](ba36148), [`48e8710`](48e8710), [`e2f3075`](e2f3075), [`047d6a0`](047d6a0), [`87603d1`](87603d1), [`096962c`](096962c), [`d545970`](d545970), [`e2f3075`](e2f3075), [`d06affc`](d06affc), [`8af47eb`](8af47eb), [`e2f3075`](e2f3075), [`5c4d130`](5c4d130), [`3f11f35`](3f11f35), [`caf3a18`](caf3a18), [`8823037`](8823037), [`1d76212`](1d76212), [`0dc0548`](0dc0548), [`00d81fa`](00d81fa)]: - @sveltejs/kit@3.0.0-next.0 ## @sveltejs/enhanced-img@1.0.0-next.0 ### Major Changes - breaking: require Node 22 or newer ([#12548](#12548)) ### Minor Changes - breaking: require Vite 8 and `vite-plugin-svelte` 7 ([#15542](#15542)) ## @sveltejs/kit@3.0.0-next.0 ### Major Changes - breaking: TypeScript 6 is now the minimum required version ([#15930](#15930)) - breaking: upgrade to cookie v1. Cookie names must now contain only ASCII characters ([#13386](#13386)) - breaking: require Node 22 or newer ([#12548](#12548)) - breaking: remove the `preloadStrategy` option. `modulepreload` will always be used ([#15256](#15256)) - breaking: default the cookie `path` option to `'/'` ([#15398](#15398)) - breaking: remove `@sveltejs/kit/node/polyfills` ([#15430](#15430)) - breaking: add `config.kit.output.linkHeaderPreload` to preload using the `Link` header ([#15939](#15939)) - breaking: require `@sveltejs/vite-plugin-svelte` v7 ([#15371](#15371)) - breaking: remove `createEntries` from the `Builder` object passed to adapter functions ([#15509](#15509)) - breaking: remove the deprecated CSRF `checkOrigin` option in favor of `trustedOrigins` ([#15437](#15437)) - breaking: the `delta` property now only exists for `popstate` navigation events ([#15522](#15522)) - breaking: remove deprecated `pragma` header in version polling for improved CORS support ([#15428](#15428)) - breaking: require Svelte 5.48.0 or newer ([#15371](#15371)) - chore: change `error`, `isHttpError`, `redirect`, and `isRedirect` to refer to public type instead of internal class ([#15250](#15250)) - breaking: require Vite 8. Provides new functionality even for existing Vite 8 users such as faster builds with Vite hook filters and more powerful SvelteKit adapters with the Vite environment API ([#15371](#15371)) - breaking: remove `data-sveltekit-*` option `'off'` in favour of `false` ([#15907](#15907)) ### Minor Changes - feat: resolve paths using the Vite config `root` option instead of `process.cwd()` to better support monorepo configurations such as Vitest workspaces ([#15469](#15469)) - chore: deprecate `Response` helpers in favor of platform-provided alternatives ([#15448](#15448)) - feat: explicit env vars ([#15934](#15934)) ### Patch Changes - fix: remove check for svelte.config.js before running `sync` ([#15946](#15946)) - fix: generate a placeholder tsconfig.json to squelch sync-time warnings ([#15948](#15948)) - chore: remove dependency on kleur ([#12548](#12548)) - chore: remove dependency on `set-cookie-parser` ([#15384](#15384)) - fix: allow use of `$app/env/public` in service workers ([#15950](#15950)) ## @sveltejs/package@3.0.0-next.0 ### Major Changes - breaking: require Node 22 or newer ([#12548](#12548)) ### Patch Changes - chore: remove dependency on kleur ([#12548](#12548)) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
closes #15212
and helps with #1485
This PR writes the virtual env modules to disk so that they can be used in files that run outside of the Vite pipeline.
Some thoughts while implementing this:
It's not very nice that secrets can now exist in both the .env file and the generated module. But maybe it's fine because it's gitignored and bound to be overwritten when updated and sync runs?the dynamic module no longer serialises the .env filesvelte-kit syncused to only generate types but now it generates modules too so that we can use $env without starting the dev server.I noticed our test apps had tests in a "test" folder instead of "tests" (plural). Is that on purpose? Or should we include both variations in the generated tsconfig.json in case of mistakes like this? createdfix: includetestdirectory in generatedtsconfig.json#15254Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
Tests
pnpm testand lint the project withpnpm lintandpnpm checkChangesets
pnpm changesetand following the prompts. Changesets that add features should beminorand those that fix bugs should bepatch. Please prefix changeset messages withfeat:,fix:, orchore:.Edits