wasp icon indicating copy to clipboard operation
wasp copied to clipboard

Allow configuration of frontend web-app env vars via the main `.env` file

Open shayneczyzewski opened this issue 2 years ago • 7 comments

Is your feature request related to a problem? Please describe. Right now, we only copy the .env file into the server directory. This means to set frontend env vars, you have to set them when invoking the Wasp CLI command. So for example, if you want to run a Wasp app on a different port, you can set PORT=4040 in your .env file to get the server running on 4040, but to have the web-app send the API calls to the backend you have to invoke start like so: REACT_APP_API_URL=http://localhost:4040 wasp start

Describe the solution you'd like It would be better if we could set REACT_APP_API_URL in the .env file. Or perhaps have some cleaner way to specify it in a single env var even.

shayneczyzewski avatar Jul 23 '22 14:07 shayneczyzewski

Aha interesting! I think when I was doing .env I just tried to do the simplest solution that offers value, which was at that point an .env file for server, which sets env vars during development. We could use it also for frontend I guess, why not? It would still be only for development of course. So we would copy .env file to fronend also, and we would need to make sure it is picked up - I think CRA maybe comes with some .env support so it might work out of the box or with very minor tweaking. If not we would add support on our own (probably using dot-env library).

Martinsos avatar Jul 24 '22 14:07 Martinsos

Hi there, I'd like to take this one.

Two facts:

  • CRA already comes with .env file support. Once we put it in web app root dir, React scripts will load it. So there is no need to add additional support.
  • Simply copying .env to the web app and server app can lead to unexpected result. If it contains PORT variable then both server and frontend apps will receive it. And both will try to use it.

I see the following solutions:

  1. Instead of only one .env file, we introduce two files .env.server and .env.webapp (or .env.backend and .env.frontend)
  2. We keep one .env file and encourage user to use some convention when naming env vars. Like SERVER_TEST_ENV_VAR and WEBAPP_TEST_ENV_VAR. We have to keep in mind that there is already REACT_APP_ prefix required by web app.
  3. We can introduce new DSL expressions inside app.wasp or even .env file that would enable user to distinguish which environmental variable goes where. Let me know if you would like to know more about this approach, I have some ideas.

I think the first approach would be the best for user.

I'm happy to hear any ideas on this

preshetin avatar Aug 01 '22 09:08 preshetin

As per third approach, an .env file can look like this:

# {= Server
TEST_ENV_VAR="I am test"
DATABASE_URL=postgresql://postgres:devpass1234@localhost:5432/postgres
PORT=4041
# =}

# {= Client
REACT_APP_API_URL=http://localhost:4041
PORT=4040
# =}

I'm new to Haskell so I'm not sure if such kinds of expressions are best for implementation.

preshetin avatar Aug 01 '22 09:08 preshetin

Hi @preshetin! Thanks for wanting to take lead on this one, definitely feel free to run with it!

I like the idea of (1) to start with, personally. I also agree it would be nice even if we split client/server if we had consistent Wasp-specific envar prefixes, and not be tied to REACT_APP_ if possible. Not sure if CRA has an override for that prefix we can tweak.

Last thing to consider is if, in addition to tier-specific env files, we also had different environments like dev, test, etc. Prod will be different since as of now we don't copy .env files on wasp build to be included in your Docker container, and instead assume they will be set in your PaaS (like Heroku).

I will be excited to see what you learn and come up with! @Martinsos may have some thoughts here as well.

shayneczyzewski avatar Aug 01 '22 14:08 shayneczyzewski

Awesome analysis @preshetin ! I agree that option (1) is maybe the easiest to start with. I also agree it would be cool if we can remove REACT_APP_ requirement. Different envs are something we could consider, and I think dotenv library and also CRA have quite something to say about that so we can possibly see what others do and model that. But I hope we can postpone that for now. As for more advanced options, one that might be very cool is also specifying env vars directly in the .wasp file so Wasp knows about them and can reason about them -> but that is certainly a thing to consider for the future.

Martinsos avatar Aug 03 '22 11:08 Martinsos

Thanks @shayneczyzewski and @Martinsos for sharing this.

Looks like we have consensus on (1) approach. I feel like I'm ready to prepare a PR implementing this.

Some thoughts on the implementation:

  • If we want compiler to consume .env.server, not .env file, it means it will be breaking change. Existing Wasp users have to manually update .env to .env.server. To avoid breaking change, we can postpone with changing this file name and leave it as it is now, .env. Still, since we are in Alfa, I suppose we have the right to do this. The name like .env.server feels more suitable to me.
  • To handle client env var, I'm going to add dotEnvClientFile field to AppSpec data type.

Let me know your thoughts

preshetin avatar Aug 04 '22 17:08 preshetin

Awesome, @preshetin! 🥳 I think in general, we are not opposed to breaking changes given our stage when they make sense. You may also want to rename the existing dotEnvFile to indicate server while you are adding something like clientDotEnvFile to AppSpec. Excited to see what you come up with!

shayneczyzewski avatar Aug 04 '22 19:08 shayneczyzewski