sveltejs / kit

web development, streamlined
https://kit.svelte.dev
MIT License
18.56k stars 1.91k forks source link

$env/dynamic/private not getting loaded by vitest and vite-node #6225

Closed acarl005 closed 2 years ago

acarl005 commented 2 years ago

Describe the bug

Context

This is a followup to #5886. I began using vite-node in order to make my SvelteKit code (which depends on Vite's transforms and plugins) importable to backend/database/sysadmin-related scripts. In particular, I need access to the $env store from my shared code. Running my backend scripts with vite-node correctly populates $env/static/private for those scripts 🙌

Problem

HOWEVER, confusingly $env/dynamic/private is not getting populated through vite-node. It ends up being an empty object at runtime even though my .env file is set up correctly. $env/dynamic/private is getting properly populated when I run my sveltekit app through vite dev though.

Reproduction

See my stackblitz. To prove that my env setup is correct, I am serving both static and dynamic env vars from my page endpoint, and rendering on the page (not a "realistic" example, I only want to show that my .env is hooked up correctly). Now, to show the actual bug, run npm run bug. This goes through vite-node. The static env is printing BUT NOT the dynamic env.

I'm not sure if this is a sveltekit or vite-node issue. The vite config knows about the sveltekit plugin, so it should be able to load sveltekit's stores.

Reproduction

https://stackblitz.com/edit/sveltejs-kit-template-default-9six26?file=src%2Froutes%2F%2Bpage.svelte,src%2Froutes%2F%2Bpage.server.js,.env,package.json,bug.js&terminal=dev

Logs

No response

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (4) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 16.14.2 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 7.17.0 - /usr/local/bin/npm
  npmPackages:
    @sveltejs/adapter-auto: next => 1.0.0-next.66 
    @sveltejs/kit: next => 1.0.0-next.433 
    svelte: ^3.46.0 => 3.49.0 
    vite: ^3.0.8 => 3.0.9

Severity

annoyance

Additional Information

No response

elliott-with-the-longest-name-on-github commented 2 years ago

Ah, I think you may be hosed here.

Dynamic vars are populated by the adapter calling server.init, meaning the adapter has to at least start up in order for you to see them. vite-node runs your plugins, but not your adapter.

benmccann commented 2 years ago

It sounds like $env/dynamic/public would also not be compatible with Vitest, Storybook, etc. at the moment. If we can't define these another way, we might have to document that. We should probably have a section in the docs about running components in isolation for testing, etc.

elliott-with-the-longest-name-on-github commented 2 years ago

I wonder if there's a simple way to allow testing frameworks to populate it, similar to how server.init does?

Rich-Harris commented 2 years ago

I haven't used vite-node but from reading the README I think it's a dev time thing? Could we just populate env in the virtual module during dev, and only require you to await server.init({ env }) with a built app?

elliott-with-the-longest-name-on-github commented 2 years ago

But we're already populating it in dev...

Rich-Harris commented 2 years ago

We're initialising it in dev...

https://github.com/sveltejs/kit/blob/26cdad69bc6cac0e4aae918ca3d9b52efb8aa72e/packages/kit/src/vite/dev/index.js#L275-L277

...but I'm suggesting that we actually populate this module instead of re-exporting the env object that gets set during that initialisation:

https://github.com/sveltejs/kit/blob/26cdad69bc6cac0e4aae918ca3d9b52efb8aa72e/packages/kit/src/core/env.js#L27-L30

It feels there might be some timing issues that could be resolved with this approach? Not sure

elliott-with-the-longest-name-on-github commented 2 years ago

Interesting. I'm going to self-assign this and see what I can do...

acarl005 commented 2 years ago

It sounds like $env/dynamic/public would also not be compatible with Vitest

@benmccann I can confirm that the same thing is happening with vitest, which I am also using. vitest is probably the more commonly used tool compared to vite-node.

DoisKoh commented 2 years ago

For me, I find that $env/dynamic/public in dev mode, get's populated in the client but not in the server. However, in a production build it works fine.

Edit: I tried $env/dynamic/public on StackBlitz and was wondering why it was working there, but not when I ran a new create-svelte app... and I've confirmed that it works on Linux and not Windows.

biswajit-saha commented 2 years ago

and I've confirmed that it works on Linux and not Windows.

I am also facing the same issue on windows. env returning an empty array.

elliott-with-the-longest-name-on-github commented 2 years ago

env shouldn't be returning an array at all. Did you mean an object? If not, there's likely some strange other issue involved.

biswajit-saha commented 2 years ago

Sorry, yes it is an empty object.