Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for environment variables #581

Closed
wants to merge 11 commits into from

Conversation

jacobhq
Copy link
Member

@jacobhq jacobhq commented Feb 20, 2025

Checklist

Related issue

Fixes #570

Overview

Adds support for environment variables.

  • Hook into build process and load in environment variables
  • Make environment variables available in build
  • Make environment variables available in serverside code
  • Make environment variables available in clientside react code (only with TUONO_PUBLIC_ prefix)
  • Hot reload for clientside env vars
  • Hot reload for serverside env vars
  • Typescript should not complain on client
  • Some kind of thing to prevent environment variables without TUONO_PUBLIC_ prefix from ever being sent clientside (That is the user's job)
  • Nicely handle errors for when they are not set (That is the user's job)
  • Add documentation for environment variable usage
  • Handle precedence of different .env.X files in the same way as vite
  • Add a subset of common .env files to default .gitignore (See Add .env to .gitignore file generated in the starter code templates vitejs/vite#14380 for more context around my choice)
  • Write tests for all env var scenarios
    • Unit tests for env vars
    • E2E test to check consistency between client and server

@github-actions github-actions bot added the rust Requires rust knowledge label Feb 20, 2025
@jacobhq
Copy link
Member Author

jacobhq commented Feb 20, 2025

Env Loading Priorities

An env file for a specific mode (e.g. .env.production) will take higher priority than a generic one (e.g. .env).

Vite will always load .env and .env.local in addition to the mode-specific .env.[mode] file. Variables declared in mode-specific files will take precedence over those in generic files, but variables defined only in .env or .env.local will still be available in the environment.

In addition, environment variables that already exist when Vite is executed have the highest priority and will not be overwritten by .env files. For example, when running VITE_SOME_KEY=123 vite build.

.env files are loaded at the start of Vite. Restart the server after making changes.

https://vite.dev/guide/env-and-mode#env-files

@github-actions github-actions bot added the typescript Requires typescript knowledge label Feb 20, 2025
Copy link
Member

@Valerioageno Valerioageno left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey! The PR looks good!
I think that this solution does not work right now for the production server since for starting it we run cargo run --release that by-passes the env set.
Also I couldn't understand if it is possible to manage all the env file expected by vite. I mean if I want to create a .env.staging file. How can I use it?

Good work!

Comment on lines 18 to 21
let mode_name = match mode {
Mode::Dev => "development",
Mode::Prod => "production",
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might have multiple environments.
I think the user could just define PROJECT_MODE variable in its own .envs to deal with this

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid point. I wrote this to correspond to vite modes, although that was the wrong decision. Staging env gives production mode from vite's table.

I think the user could just define PROJECT_MODE variable in its own .envs to deal with this

Can we use NODE_ENV for that? (My brain is exploding with all these different variables 😅)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmm from the doc looks like there are just two mode production and development. Maybe more are not necessary!

I'm not sure about NODE_ENV since we are not using node... It might be misleading.

@jacobhq
Copy link
Member Author

jacobhq commented Feb 20, 2025

Thanks for your feedback. I will finish addressing in the morning.

@jacobhq
Copy link
Member Author

jacobhq commented Feb 21, 2025

In terms of splitting the PR, here's my plan:

  • Vite env prefix (TUONO_PUBLIC_), and set up support for env clientside (no extra work apart from fixing TS issues that exist at the moment), and write tests
  • Rust EnvManager struct and hot reload for serverside env changes (and tests)
  • PR to write docs
  • Write E2E tests (IMHO that doesn't fit in any of the other PRs)

I think that would be quite nice, since each would be easy to revert without too much work. I read the atomic PRs article, and I think I agree - although I don't think it makes sense to split this into >4 PRs. WDYT?

And one question - can we test stuff across TS and Rust with our E2E system or is that just TS?

@Valerioageno
Copy link
Member

And one question - can we test stuff across TS and Rust with our E2E system or is that just TS?

You can test both. Better using the e2e as less as possible. The most we can test with integration the best

About your plan:

  • Shouldn't we create also a tuono start command for the production server?
  • I saw in your PR description that the client side hot reloading does not work. Do you have a fix for that?
  • The test cases should be in the same PR in which you implement the case

@jacobhq
Copy link
Member Author

jacobhq commented Feb 21, 2025

You can test both. Better using the e2e as less as possible. The most we can test with integration the best

Nice. Then integration can be done in the specific PRs for Rust and TS.

Shouldn't we create also a tuono start command for the production server?

We can, I think it is a good idea because cargo run can trigger a build, which is undesirable IMHO.

I saw in your PR description that the client side hot reloading does not work. Do you have a fix for that?

It works although there are typescript errors. I don't have a fix for them yet.

The test cases should be in the same PR in which you implement the case

Yep :)

So just these three PRs then, and E2E done in the last PR because the point of that will be to check that all the PRs are consistent with each other.

  • Vite env prefix (TUONO_PUBLIC_), and set up support for env clientside (no extra work apart from fixing TS issues that exist at the moment), and write tests
  • Rust EnvManager struct and hot reload for serverside env changes (and tests)
  • PR to write docs

E2E may not even be needed, I think we can cover it with unit and integration.

@Valerioageno
Copy link
Member

So 4 tasks I'd say:

  • Create tuono start
  • Vite env prefix (TUONO_PUBLIC_), and set up support for env clientside (no extra work apart from fixing TS issues that exist at the moment), and write tests (fixing also the typescript errors)
  • Rust EnvManager struct and hot reload for serverside env changes (and tests)
  • PR to write docs and update tutorial to mention tuono start

@jacobhq
Copy link
Member Author

jacobhq commented Feb 21, 2025

Alright. I'll leave this PR here as a proof of concept/reference, and I'll start work on each of those tasks in separate PRs. Since this will be quite a big addition, what do you want to do about releasing it? IMHO it may warrant a new minor release.

jacobhq added a commit to jacobhq/tuono that referenced this pull request Feb 21, 2025
jacobhq added a commit to jacobhq/tuono that referenced this pull request Feb 21, 2025
@jacobhq
Copy link
Member Author

jacobhq commented Feb 21, 2025

I'm closing this, but I will keep the branch in my fork around for now.

@jacobhq jacobhq closed this Feb 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rust Requires rust knowledge typescript Requires typescript knowledge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Enhancement: Implement .env file support for configuration management
2 participants