nodejs/node

Add `--env-file-if-exists`

mbrevda opened this issue ยท 10 comments

What is the problem this feature will solve?

#50588 introduced a throw if a requested env file isn't found. When dealing with multiple environments, a .env file may sometimes be merely optional - and throwing isn't desired. For example, during local development, devs might keep variables in a .env file, which isn't committed to source control, while in production, these variables come from the environment. This option will allow the env file to be loaded only if it exists without changing the command used to invoke node between environments.

What is the feature you are proposing to solve the problem?

Add a flag (or other mechanism) to indicate that the .env file should be loaded only it's found, and to throw otherwise.

What alternatives have you considered?

touching .env before running node; invoking node via a shell script and "building up" the cli opts.

A few random thoughts:

Another simple (yet non-portable) alternative is to put something like this in your .bashrc or so:

function env-file-if-exists() { if [ -f "$1" ]; then echo "--env-file=$1"; fi }

And then use it like this:

node $(env-file-if-exists local.env)

Or, for better readability, something like this:

function if-exists() { if [ -f "$1" ]; then echo "$1"; else echo /dev/null; fi }

To be used as:

node --env-file=$(if-exists local.env)

For example, during local development, devs might keep variables in a .env file, which isn't committed to source control, while in production, these variables come from the environment.

On a side note, from a security point of view, I think this is an anti-pattern. Loading environment variables from a file that may or may not exist opens up a potential attack vector.

this is easily achievable with a little shell statement:

 node $([[ -f .env ]] && echo "--env-file .env ")index.js 

this is easily achievable with a little shell statement

This request is for a pure node solution

I second that it would be really desirable to have this feature. We're working with a .env and a .env.local file in our projects, the latter only being available locally. If this doesn't work anymore, the whole feature is rendered useless for us. You could put all your resentiments against such a feature in it's documentation: "Warning! It's an attack vector, it's not deterministic." etc., and us daredevils could use it despite those warnings. ;)

Conundrum: use the "native" feature and add complexity to your own packages OR use the pre-existing npm package which is "not native" and requires an additional dependency tree.

edit: original comment was maybe rude

I have a similar issue, posted here (and got ๐Ÿ’ฉ on but ok).

The recc. here would help me but Node is meant to be a generic runtime, not a batteries-included server package. insisting on installing zilch and instead asking it to do all the lifting is starting to sound a bit much.

I have the same philosophy and don't install unless abs. necessary.
We're currently trying out this scheme, with 2 files checked in version control:

  • .env.local.dev
  • .env.local.test

which list reasonable safe defaults, ie:

NODE_ENV=development
DATABASE_URL=postgres://dev:123456@localhost:5432/app_dev
FOO=BAR

All other .env file formats are .gitignored

Here's the runners:

// remote envs dont load .env files, duh
"start": "node server/app.js",
"test-ci": "node --test test/**/**.spec.js",

// oh well
"start-dev": "node --env-file=.env.local.dev --watch server/app.js",
"test": "node --env-file=.env.local.test --test test/**/**.spec.js"

internally we do something like this:

const db = pg(DATABASE_URL)

I think this kind of sucks, it's convoluted and has potential of someone seeing an .env-like file
and pushing his grandmothers banking credentials up in VC but why would I care?

A Github org. can setup server git hooks and reject anything resembling a cred.

I support a --optional-env-file argument. I don't see how this would be more of an attack vector than --env-file is already. This would simply go forth regardless of whether it found the desired .env file, and it would allow not having to do the solutions mentioned in #51451 nor having to implement the scripts above (which don't work in Windows)

Edit: Solved in #53060. Now we have to wait for it to be merged

I was setting up a GitHub action for my project and wanted to use secrets to set env variables in the YAML file depending on if it was a production or development build. In this situation, the .env file for developers is missing for the build server since it's excluded via .gitignore. It looks like the work-around is to create a .env file for each build.

I was setting up a GitHub action for my project and wanted to use secrets to set env variables in the YAML file depending on if it was a production or development build. In this situation, the .env file for developers is missing for the build server since it's excluded via .gitignore. It looks like the work-around is to create a .env file for each build.

That's exactly what we've been doing until now while waiting for a non-mandatory env injection version. All of our env-sensible scripts look something like that: touch .env && node --env-file .env scripts/xyz.js. This keeps the current .env file if one exists, and creates an empty one if it doesn't. Not a huge deal, but useless IMHO compared to an optional version. Let's be patient!

The TSC had a vote on this, and IIRC this is the plan

https://github.com/nodejs/TSC/blob/main/votes/2024-06-25-0.json