zetachang / react-native-dotenv

A Babel preset let you import application configs from .env file (zero runtime dependency)
MIT License
915 stars 68 forks source link

Don't Require JS Edits For Variable Changes #70

Open special-character opened 4 years ago

special-character commented 4 years ago

I really appreciate this project!

To get env vars to be updated locally, we have to change the JS file that imports an ENV var Docs.

The bigger problem I see is for applications that use an ENV var in more than 1 file. For example, I have an ENV var called A_WACKY_ENV_VAR used in two files. Here is a log of the ENV var from both files:

Screen Shot 2019-11-05 at 5 04 17 PM

After I change the ENV var and make a change to one of the JS files, I expected the env var to be updated for both but it only updated in one file.

Screen Shot 2019-11-05 at 5 07 12 PM

To get the same variable in both files, I had to update each of them. This was confusing, even after reading the docs. It would be ideal if we could update one of the files and both env vars would get updated.

Not sure if this is easy or possible but I am willing to try and find out!

Voochichichi commented 4 years ago

Let me know if you find a solution to this, I'm about to move away from react-native-dotenv over this single issue

josephfinlayson commented 4 years ago

@AirEssY What did you move to?

special-character commented 4 years ago

I eventually couldn't find a way to make this work. I switched to using expo release channels for my application.

https://docs.expo.io/versions/latest/distribution/release-channels/

TJTorola commented 4 years ago

Our CI agents cached the env from one of our release channels then did not change for another even though the env file was swapped out. If we had been less lucky about discovering this issue we could have deployed a codepush bundle to production that rolled all of our users onto a different environment :scream:.

TJTorola commented 4 years ago

Ok, after a lot of digging, I think this https://github.com/babel/babel/issues/8497 is really what react-native-dotenv needs to get this fixed. Seeing as there is currently no way to tell babel that the .env file is a dependency requiring a new build react-native-dotenv cannot possibly get it to rebuild when the env file changes. Which makes sense considering what we've seen.

I think I have a partial workaround though, changing metro.config.js to include:

const crypto = require('crypto');
const fs = require('fs');

let hash = crypto.createHash('sha256');
hash.update(fs.readFileSync('.env'));
const cacheVersion = hash.digest('hex');

module.exports = { // eslint-disable-line import/no-commonjs
  ...
  cacheVersion,
};

This results in metro using the hash of the .env file as a cache key and therefore invalidates the cache when the env file changes. I don't believe this will work for live reloading, you would still need to restart react-native whenever the env or any files using it changes, but from some initial testing I think it resolves the issue I was seeing with our bundles created in CI reusing env vars from other release channels.

See: https://facebook.github.io/metro/docs/configuration#cacheversion