netlify / cli

Netlify Command Line Interface
http://cli.netlify.com
MIT License
1.56k stars 343 forks source link

Support for import.meta.env or $env/dynamic/private in Netlify background functions. #5286

Open kyllerss opened 1 year ago

kyllerss commented 1 year ago

Describe the bug

SvelteKit uses a wrapper around import.meta.env ($env/dynamic/private, ...see all here) to expose environment variables. When deploying code to Netlify background functions, these configuration parameters are not visible. I find myself having to write code such as:

let db_url = process.env.DB_URL ?? import.meta.env.DB_URL;

Is support for import.meta.env or $env/dynamic/private on the roadmap?

Similarly, when I try to use SvelteKit's $env/dynamic/public, I get the following error:

[ERROR] Could not resolve "$env/dynamic/public"
docker-web-app-1     | 
docker-web-app-1     |     src/lib/env/env_clientside.ts:1:20:
docker-web-app-1     |       1 │ import { env } from '$env/dynamic/public';
docker-web-app-1     |         ╵                     ~~~~~~~~~~~~~~~~~~~~~
docker-web-app-1     | 
docker-web-app-1     |   You can mark the path "$env/dynamic/public" as external to exclude it from the bundle, which will remove this error.

Steps to reproduce

Import $env/dynamic/private or any of its related variants in a background function.

Configuration

No response

Environment

System:
    OS: Linux 5.15 KDE neon 5.26 5.26
    CPU: (16) x64 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz
    Memory: 7.27 GB / 15.34 GB
    Container: Yes
    Shell: 5.1.16 - /bin/bash
  Binaries:
    Node: 16.18.0 - ~/apps/node-v16.18.0-linux-x64/bin/node
    npm: 8.19.2 - ~/apps/node-v16.18.0-linux-x64/bin/npm
  npmPackages:
    netlify-cli: ^12.0.11 => 12.2.7 
kyllerss commented 1 year ago

Can anyone point me to some information that would help me understand how a Netlify function differs from a background function from an implementation standpoint that would help explain this issue? Thanks!

ascorbic commented 1 year ago

Hi @kyllerss Is this a Netlify background function that you have created in netlify/functions (or wherever your functions live)? While SvelteKit itself is deployed on Netlify Functions, any functions that you create yourself are not part of the framework, and are not compiled by SvelteKit, so cannot access any SvelteKit-specific imports. import.meta.env is a Vite API, so is available in SvelteKit, which uses Vite, but not elsewhere. I'd recommend using process.env in background functions.

kyllerss commented 1 year ago

OK. I understand. A challenge that people are going to run into (especially as more people adopt SvelteKit + Netlify now that SvelteKit is 1.0) is that they (like myself) will be writing background functions that re-use code from their project. This is going to be a source of confusion.

Unless there is a way you can compile background functions to use the same runtime as regular endpoint functions, then it will be helpful to add a note on SvelteKit instructions that point out that background functions don't have SvelteKit support. Ideally some best practices would be useful as to how to structure a project so that one can re-use code from the SvelteKit portion of the deployment.

Thanks!

ascorbic commented 1 year ago

We'd love for there to be a way of deploying SvelteKit API routes as background functions or scheduled functions, but that would require work on the SvelteKit adapter. Certainly a possibility though.

kyllerss commented 1 year ago

One additional note to add as vote in favor or prioritizing this a little higher in the roadmap is a problem I ran into today which resulted in an unfortunate amount of time lost.

Deep in my class dependency graph I added a call to a class that made use of $env/static/public environment variables. As a result the deployment would error out pointing to the fact that it cannot interpret said imports (without a stack-trace to help identify the issue). It took me a while to unwind my commits to find the culprit - especially because I wasn't expecting it and assumed the issue was something else.

I anticipate this is going to be a common occurrence for people that use Netlify + SvelteKit and want to use background functions. Unfortunately, I can't think of anything other than keeping this peculiarity constantly in my mind while coding to make sure I don't add dependencies between classes that may cause this issue to surface.

In any case, +1 to lessen one this persistent landmine people are going to stumble upon.

Shackless commented 1 year ago

+1 from me. I'm having the same issue and think this should just work because it's the recommended way to handle ENV VARS in SvelteKit. In Vercel, this just works, so maybe their adapter does something helpful?

ascorbic commented 1 year ago

@Shackless does Vercel have background functions?

Shackless commented 1 year ago

@ascorbic Not 100% sure regarding the terminology. They have serverless functions and edge functions and access to $env/dynamic/private and $env/dynamic/public definitely "just works" in both when using adapter-vercel as long as you add the variables from your .env file as environment vars to the project in their WebUI.

ascorbic commented 1 year ago

@Shackless Are these SvelteKit +server.js files or something else?

Shackless commented 1 year ago

@ascorbic Yes, basic endpoints / RequestHandlers in +server.ts. If you leave them at defaults, they run as serverless functions. If you add a config param, they run as edge functions.

import type { Config } from '@sveltejs/adapter-vercel';
import { MY_KEY } from '$env/static/private';

export const config: Config = {
    runtime: 'edge'
};

// or GET, DELETE, ...
export const POST: RequestHandler = async ({ request, fetch }) => {
   console.log(MY_KEY); // works fine with or without edge runtime
}
ascorbic commented 1 year ago

I think this is the source of the confusion. A +server.ts endpoint should work just fine on Netlify too, with access to $env/dynamic/private and so on. The difference is that the background functions that people are creating are not SvelteKit endpoints. They run entirely separately from the SvelteKit site, so can't do anything SvelteKit-specific.

The feature that is needed is for support for the new per-route config to be added to the Netlify adapter, and for background to be one of the options. That way endpoints can be created that run in the background and have access to all the SvelteKit stuff

Shackless commented 1 year ago

Unfortunately, it doesn't. I am currently trying to migrate a site from Vercel to Netlify and when I just swapped out adapter-vercel for adapter-netlify, I could not access the environment variables. I have to read them using process.env.MY_KEY instead. I'm using endpoints only to access my env vars because the frontend should not know them at all. I basically just wrote these endpoints to abstract this away instead of communicating with Firebase, OpenAI and whatnot directly from my web frontend. Or am I doing this wrong?

ascorbic commented 1 year ago

OK, in that case that's an issue unrelated to this one, which isn't about endpoints. It certainly should work. Could you open an issue on the SvelteKit repo?

kyllerss commented 1 year ago

@ascorbic Any updates on this one? I recently ran into another issue closely related to this: SvelteKit's build-related environment variable (import { building } from "$app/environment";) is also impacted by this discrepancy. This one is just as bad - if not perhaps even more inconvenient as there is no good way (to my knowledge) of detecting if code is being run during a build process or while the app server is running.

Doesn't seem as if Vercel is impacted by this.

Any idea if this is something that is on the roadmap?

nickytonline commented 1 year ago

@kyllerss, I've added this to our backlog. At the moment, I'm unable to give a timeline though.

phil-w commented 3 months ago

Yeah, same problem here... anyone got a good work around? I'm thinking that the Sveltekit $env stuff just won't work here without some work from netlify.

sam-whitmore commented 1 week ago

Just wanted to write a brief comment here to say that I'm encountering the same issue as the other developers above have described.