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

Contradictory behaviour when NODE_ENV is undefined and no validation rule set #65

Closed
foiseworth opened this issue Sep 8, 2017 · 9 comments

Comments

@foiseworth
Copy link

If you define validation for NODE_ENV and it is undefined then due to [1] isProduction will return true and isDev returns false.

However due to [2] dev defaults will be used. This behaviour is contradictory and confusing.

I'd submit a PR but I'm not 100% on what the fix would be, I think possibly that:

  • actual node env should be calculated early on (including using default if not set)
  • actual node env should then be used through out
  • actual node env should be added to output

[1] https://github.com/af/envalid/blob/master/index.js#L79
[2] https://github.com/af/envalid/blob/master/index.js#L89

@SimenB
Copy link
Collaborator

SimenB commented Sep 8, 2017

I agree defaultNodeEnv seems weird. it should instead add itself to the env if NODE_ENV is not set.

Does that make sense? Would love to se a PR for it!

@af
Copy link
Owner

af commented Sep 11, 2017

Agreed, this is contradictory, thanks for pointing it out. The original intent was for NODE_ENV validation to be "baked in", and if you ever forgot to set the env var, production is the safest choice. devDefaults came later and I never noticed that they would also be applied in this case.

IMO the fix here is that in this case devDefaults should not be used. Any downside to just closing that loophole?

@SimenB
Copy link
Collaborator

SimenB commented Sep 11, 2017

I think this is the key: "actual node env should then be used through out" combined with using a default

So something like:

function cleanEnv(inputEnv, specs, options = {}) {
    let output = {}
    const errors = {}
    // If validation for NODE_ENV isn't specified, use the default validation:
    specs = Object.assign(
        {
            NODE_ENV: validateVar({
                name: 'NODE_ENV',
                spec: str({ choices: ['development', 'test', 'production'] }),
                rawValue: env.NODE_ENV || 'production'
            })
        },
        specs
    )
    const env =
        options.dotEnvPath !== null ? extendWithDotEnv(inputEnv, options.dotEnvPath) : inputEnv
    const varKeys = Object.keys(specs)

    // the rest...

Then everything should work correctly, right?

@af
Copy link
Owner

af commented Sep 11, 2017

Yes that looks like it should do the trick

@neezer
Copy link
Contributor

neezer commented May 9, 2018

Just ran into this confusion myself refactoring #81.

@SimenB 's code is on the right track, but won't work as-is: the keys in specs are iterated below in // the rest ... and passed back to validateVar again, which expects spec objects and not values. So you'll end up with this error.


I like the intent behind this feature, but honestly I'm wary of its auto-magical nature. There's nothing on NodeJS docs about NODE_ENV specifically (go there and search the page for NODE_ENV and find nothing).

According to a Nodejitsu engineer from back in the day:

[NODE_ENV is] not documented in node core because it's just a convention, made
popular by express. Node itself doesn't care what the environment vars
are really, it just lets you read and write them via
http://nodejs.org/docs/latest/api/process.html#process_process_env

This leads me to wanting to treat it like any other str env var and not do anything special with it. ❄️

Since there's no official spec about what its values should or shouldn't be (just convention)—or what will or won't happen if its not set (depends on your code and packages installed)—I think its probably safer, easier, and simpler to leave this definition in user-land.

My two cents.

@af
Copy link
Owner

af commented Jan 26, 2021

Fiiiiinally fixed this, devDefault values will no longer be used when NODE_ENV is not present in the environment.

Also:

This leads me to wanting to treat it like any other str env var and not do anything special with it. ❄️

Since there's no official spec about what its values should or shouldn't be (just convention)—or what will or won't happen if its not set (depends on your code and packages installed)—I think its probably safer, easier, and simpler to leave this definition in user-land.

This will be the case in v7, NODE_ENV is just like any other env var and you need to add a validator for it if you want it to be validated.

@misha-erm
Copy link

@af I have a small question about this fix:

Shouldn't devDefault also work when I set NODE_ENV: str({default: 'development'}) in the cleanEnv ?
Thanks

@af
Copy link
Owner

af commented Mar 21, 2021

@MikeYermolayev here's the current logic for when devDefault is used. So in the case above, if NODE_ENV is not set to production then I believe it should be used.

    // Use devDefault values only if NODE_ENV was explicitly set, and isn't 'production'
    const usingDevDefault =
      rawNodeEnv && rawNodeEnv !== 'production' && spec.hasOwnProperty('devDefault')

@misha-erm
Copy link

@af well looks like it's not true.

I assume rawNodeEnv is being read only from provided environment so usingDevDefault doesn't consider any defaults from provided spec

tuannm151 pushed a commit to BSSCommerce/shopify-envalid that referenced this issue Jul 1, 2024
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

No branches or pull requests

5 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy