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

Added import.meta.env for environment variables #5

Closed
wants to merge 1 commit into from

Conversation

franciscop
Copy link

@franciscop franciscop commented Aug 6, 2024

See relevant Github for all of the details, but basically this proposal is for a single place where the Environment Variables are all already loaded from the environment:

const myenv = import.meta.env.MY_VARIABLE;

If this is relevant, I can also add a polyfill and some test, so please let me know and I can add those!

@franciscop franciscop changed the title Added import.meta.env for environment variables Added import.meta.env for environment variables Aug 6, 2024
@ljharb
Copy link
Member

ljharb commented Aug 6, 2024

import.meta is meant for things that are specific to an ESM module, which env vars aren't - why is this the best place to put it, versus a global (which would be accessible to CJS code as well)?

@franciscop
Copy link
Author

You are right, of all of the currently used variables, I thought import.meta.env sounded the best and the most "standard-like", but import.meta is about the current file, right? Like import.meta.url refers to the current file.

I just wanted to try to suggest a possible solution to this, but it seems none of the currently used names are good candidates for a standard after hearing your comment:

const env = typeof process !== "undefined"
  ? process.env
  : typeof import.meta?.env !== "undefined"
  ? import.meta.env
  : typeof Netlify !== "undefined"
  ? Netlify.env.toObject()
  : null;

@ljharb
Copy link
Member

ljharb commented Aug 15, 2024

Yes, but environment variables do not change based on the current file - they are the same in every file.

@jkrems
Copy link

jkrems commented Sep 30, 2024

FWIW, this is actively in use by Vite, bun, and rspack today.

It seems like adding it to this repo could reduce the risk of somebody adding a conflicting property to another runtime?

I'm not arguing that import.meta is the right place to put this info, just that it's where real, existing code now expects to find environment variables and that documenting the use of this property would be helpful.

@franciscop
Copy link
Author

My main grip was on how weird Cloudflare is and this is the main reason I even started this, since I'd like to be able to access the environment properties outside of fetch(), however it's true that it'd be nice for the others to be the same. @ljharb I'll let you decide here whether to close this issue or not, your arguments are very true and this is not "the right place" (even though I initially proposed this), however @jkrems is also right this is becoming more and more common and we'd benefit from an official place that documents/recommends it this way.

@guybedford
Copy link

I suppose the Cloudflare env vars as secrets thing is actually an argument for contextual import.meta, since they could be optionally made available on a per-variable basis to modules with the capability to view them. For example the main application module could read import.meta.env.PRIVATE_KEY but dependencies might only get import.meta.env.NODE_ENV say.

@jkrems
Copy link

jkrems commented Sep 30, 2024

There's likely also some finer details around mutability. E.g. I assume import.meta.env (as implemented in most bundlers at least) is readonly or not shared mutable state. But I'm not sure that level of detail needs to be called out beyond "beware, exact semantics beyond simple reads may vary".

@ljharb
Copy link
Member

ljharb commented Oct 1, 2024

I simply don't think there's any argument for it. Environment variables are global within an environment; changing them contextually is a misuse/abuse of the feature; if we want contextual values per-module than "env" is simply the wrong name for the concept.

Additionally, import.meta is ONLY intended for contextual things that differ per module.

@guybedford
Copy link

guybedford commented Oct 1, 2024

Contextual secrets make a lot of sense to me as a concept personally. So far as folks use environment variables for secrets, techniques like this may allow them to use them more safely by allow-listing environment variables per module consumer.

@ljharb
Copy link
Member

ljharb commented Oct 1, 2024

Contextual secrets are clearly valuable and useful and important - I just don't think it makes any sense to subvert environment variables for that purpose. Let's work across the runtimes and come up with a way to do it that's actually intended for that purpose :-)

@guybedford
Copy link

So far as this meta registry is concerned, the value in standardizing patterns is in ensuring coordination between runtimes.

If more tools and runtimes continue to adopt this pattern, we cannot gate landing the spec for the pattern on coming up with something better.

@ljharb
Copy link
Member

ljharb commented Oct 1, 2024

That’s true. But we can advise them not to propagate a pattern further if we’re working on a better alternative.

@franciscop
Copy link
Author

I think contextual secrets are different, I do want my env variables to be accessible by my modules in 99% of the cases, in fact I wish more modules would directly read those instead of having to manually pass them all around.

"if we’re working on a better alternative"

So the conclusion is that globalThis.env would be a better place to recommend putting these, right? Is there work in progress there that I can read about?

@ljharb
Copy link
Member

ljharb commented Oct 1, 2024

Contextual secrets certainly shouldn't be on globalThis, and environment variables should - so I'm suggesting that import.meta.somethingThatIsNotEnv be the place for a module-contextual secrets/metadata API.

@franciscop
Copy link
Author

Contextual secrets certainly shouldn't be on globalThis, and environment variables should - so I'm suggesting that import.meta.somethingThatIsNotEnv be the place for a module-contextual secrets/metadata API.

Oh sorry yeah, "this" I meant environment variables should go within globalThis.env. Closing this issue then, thanks for the replies!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants