react-native-dotenv icon indicating copy to clipboard operation
react-native-dotenv copied to clipboard

.env variables are cached

Open AbdulBsit opened this issue 2 years ago • 36 comments

  • [ ] Asked question in discussions
  • [x] Tried the troubleshooting Wiki
  • [x] Followed the migration Wiki

Describe the bug I tried upgrading, dev dependencies releated to babel, but no luck, it cached the variable, until we change something in to the file we imported the "@env", when we undo the change, it goes back to cached value

Expected behavior Change in .env should reflect in files, after a restart

Additional context

"@babel/core": "^7.21.3",
"@babel/runtime": "^7.21.0",
"react-native-dotenv": "^3.4.7",

AbdulBsit avatar Mar 16 '23 08:03 AbdulBsit

Hey, thank you for opening this issue! 🙂 To boost priority on this issue and support open source please tip the team at https://issuehunt.io/r/goatandsheep/react-native-dotenv/issues/422

github-actions[bot] avatar Mar 16 '23 08:03 github-actions[bot]

Hi @AbdulBsit those Babel package versions are only really if you're using something overwrites the versions such as expo. Are you using expo? Also are the babel packages installed as dependencies or resolutions? Please tell me what else you tried that didn't work in the cacheing section of the README as I'm unable to reproduce this.

goatandsheep avatar Mar 18 '23 01:03 goatandsheep

Hey @goatandsheep These babel packages are installed as devDependencies, and I am not using expo

Also things i have tried which not solves the issue

  • Reset cache
yarn start --reset-cache
  • Adding resolutions to my package.json
"resolutions": {
  "@babel/core": "^7.20.2",
  "babel-loader": "^8.3.0"
}

For your reference here is my current configuration

package.json

{
  "name": "app",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "postinstall": "patch-package",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
  },
  "dependencies": {
    "@bandwidth/webrtc-browser": "^0.13.1",
    "@gorhom/bottom-sheet": "^4.4.5",
    "@notifee/react-native": "^7.3.0",
    "@react-native-async-storage/async-storage": "~1.15.0",
    "@react-native-clipboard/clipboard": "^1.11.1",
    "@react-native-community/datetimepicker": "^6.7.1",
    "@react-native-community/netinfo": "^9.3.7",
    "@react-native-firebase/app": "^16.5.0",
    "@react-native-firebase/messaging": "^16.5.0",
    "@react-native-menu/menu": "^0.7.3",
    "@react-navigation/bottom-tabs": "^6.0.9",
    "@react-navigation/drawer": "^6.5.0",
    "@react-navigation/material-top-tabs": "^6.0.6",
    "@react-navigation/native": "^6.0.6",
    "@react-navigation/stack": "^6.0.11",
    "@sentry/react-native": "^5.0.0-alpha.10",
    "appcenter": "4.4.5",
    "appcenter-analytics": "4.4.5",
    "appcenter-crashes": "4.4.5",
    "axios": "^0.21.1",
    "events": "^3.3.0",
    "jwt-decode": "^3.1.2",
    "moment": "^2.29.1",
    "newrelic-react-native-agent": "0.0.9",
    "react": "18.1.0",
    "react-native": "^0.70.7",
    "react-native-action-sheet": "^2.2.0",
    "react-native-autolink": "^3.0.0",
    "react-native-background-timer": "^2.4.1",
    "react-native-callkeep": "^4.3.6",
    "react-native-clean-project": "^4.0.1",
    "react-native-code-push": "^7.1.0",
    "react-native-device-info": "^8.7.1",
    "react-native-document-picker": "^8.1.3",
    "react-native-elements": "^3.4.2",
    "react-native-gesture-handler": "^2.6.2",
    "react-native-get-random-values": "~1.7.0",
    "react-native-image-picker": "^4.7.3",
    "react-native-image-viewing": "^0.2.1",
    "react-native-incall-manager": "^3.3.0",
    "react-native-logs": "^5.0.1",
    "react-native-permissions": "^3.1.0",
    "react-native-popup-menu": "^0.15.10",
    "react-native-reanimated": "^2.14.4",
    "react-native-safe-area-context": "3.2.0",
    "react-native-screens": "~3.4.0",
    "react-native-simple-toast": "^1.1.4",
    "react-native-snackbar": "^2.4.0",
    "react-native-sound": "^0.11.2",
    "react-native-splash-screen": "^3.3.0",
    "react-native-svg": "^12.3.0",
    "react-native-tab-view": "^2.15.2",
    "react-native-vector-icons": "^9.2.0",
    "react-native-voip-push-notification": "^3.3.0",
    "react-native-webrtc": "^106.0.5",
    "react-native-webview": "^11.26.1",
    "react-style-object-to-css": "^1.1.2",
    "socket.io-client": "^2.4.0",
    "sp-react-native-in-app-updates": "^1.2.0",
    "uuid": "^8.3.2",
    "validator": "^13.5.2"
  },
  "devDependencies": {
    "@babel/core": "^7.21.3",
    "@babel/runtime": "^7.21.0",
    "@react-native-community/eslint-config": "^2.0.0",
    "@tsconfig/react-native": "^2.0.2",
    "@types/jest": "^26.0.23",
    "@types/react": "^18.0.21",
    "@types/react-native": "^0.70.6",
    "@types/react-test-renderer": "^18.0.0",
    "@typescript-eslint/eslint-plugin": "^5.37.0",
    "@typescript-eslint/parser": "^5.37.0",
    "babel-jest": "^26.6.3",
    "babel-plugin-inline-import": "^3.0.0",
    "eslint": "^7.32.0",
    "jest": "^26.6.3",
    "metro-react-native-babel-preset": "0.72.3",
    "patch-package": "^6.5.1",
    "react-native-dotenv": "^3.4.7",
    "react-native-svg-transformer": "^1.0.0",
    "react-test-renderer": "18.1.0",
    "typescript": "^4.8.3"
  },
  "jest": {
    "preset": "react-native",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ]
  }
}

babel.config.js

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: ['module:react-native-dotenv', 'react-native-reanimated/plugin'], // react-native-reanimated/plugin must be last
};

metro.config.js

const {getDefaultConfig} = require('metro-config');

module.exports = (async () => {
  const {
    resolver: {sourceExts, assetExts},
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve('react-native-svg-transformer'),
      getTransformOptions: async () => ({
        transform: {
          experimentalImportSupport: false,
          inlineRequires: false,
        },
      }),
    },
    resolver: {
      assetExts: assetExts.filter(ext => ext !== 'svg'),
      sourceExts: [...sourceExts, 'svg'],
    },
  };
})();

AbdulBsit avatar Mar 18 '23 06:03 AbdulBsit

I experience the same issue. Is there any update or solution?

MedulHasan avatar Mar 28 '23 03:03 MedulHasan

same here

Jamal-ReachFirst avatar Apr 17 '23 06:04 Jamal-ReachFirst

api.cache(true) thats what causes the caching, it has nothing to do with this lib. Its the fact that babel is caching it, so you can reset a cache on every start when you update your envs. other libs like inline-env also have the same behaviour. Hope it helps

Amurmurmur avatar Apr 19 '23 20:04 Amurmurmur

Having the same issue. Setting api.cache(false) doesn't solve it either.

prageeth avatar May 02 '23 05:05 prageeth

I come to my react native project root directory, run these command

rm -rf ~/Library/Developer/Xcode/DerivedData
xcrun simctl erase all
rm -rf node_modules
npm install
npx react-native start --reset-cache

it does work

illusion77 avatar May 14 '23 02:05 illusion77

I am having the same issue. Is there any update or solution?

prateekuttreja2020 avatar May 17 '23 10:05 prateekuttreja2020

I am having the same issue. Is there any update or solution?

In my case, using a single quote instead of the double quote when importing the 'env' variable does not cause this problem. ex: import {BASE_API_URL} from '@env';

MedulHasan avatar May 18 '23 03:05 MedulHasan

I am having the same issue. Is there any update or solution?

In my case, using a single quote instead of the double quote when importing the 'env' variable does not cause this problem. ex: import {BASE_API_URL} from '@env';

I don't think it does. Try changing the value in the variable and see if it picks it up.

winston-lee avatar May 27 '23 01:05 winston-lee

This is the one that worked for me https://github.com/goatandsheep/react-native-dotenv/issues/75#issuecomment-728055969

In my package.json

"scripts": {
    "start:devmobile": "APP_ENV=devmobile expo start --clear",
}

And I ran

npm run start:devmobile

(P.S. i'm just starting out front end development so don't laugh at what i just did ;))

winston-lee avatar May 27 '23 01:05 winston-lee

I am having the same issue. Is there any update or solution?

In my case, using a single quote instead of the double quote when importing the 'env' variable does not cause this problem. ex: import {BASE_API_URL} from '@env';

This solved it for me. Says more about my experience with node than anything. Thank you for pointing this out!

philipostli avatar Jun 01 '23 12:06 philipostli

The problem in my case was Metro cache. My solution was to add this line to the metro.config.js file:

module.exports = {
  ...
  cacheVersion: process.env.APP_ENV,
  ...
};

my package.json scripts are (always clearing cache for production runs) -

    "start": "react-native start",
    "start:staging": "APP_ENV=staging react-native start",
    "start:prod": "APP_ENV=prod react-native start --reset-cache",

according to the docs it's "an arbitrary string appended to all cache keys in the project before they are hashed". Subsequent runs of the same env keep the cache, while switching between them seems to invalidate it.

Hope it helps

david-a avatar Jun 01 '23 18:06 david-a

This is what worked for me in the metro.config.js file:

resetCache: true

rob-johansen avatar Jul 11 '23 01:07 rob-johansen

This is what worked for me in the metro.config.js file:

resetCache: true

Adding the resetCache: true to my metro.config.js worked. The final file is:

const { getDefaultConfig } = require('expo/metro-config');

module.exports = (() => {
  const config = getDefaultConfig(__dirname);

  const { transformer, resolver } = config;

  config.transformer = {
    ...transformer,
    babelTransformerPath: require.resolve('react-native-svg-transformer'),
  };
  config.resolver = {
    ...resolver,
    assetExts: resolver.assetExts.filter((ext) => ext !== 'svg'),
    sourceExts: [...resolver.sourceExts, 'svg'],
  };

  config.resetCache = true; // ADDED IT HERE <<<

  return config;
})();

But it was a nightmare until I found out about the caching. Probably this shouldn't be the default behaviour.

jfbaraky avatar Jul 21 '23 20:07 jfbaraky

resetCache is a bad option to solve the caching issue, as you disable caching for everything.

Using cacheVersion described in detail in the prior comment is the only rational solution.

o-alexandrov avatar Jul 21 '23 20:07 o-alexandrov

The cacheVersion will only work if you manually set a new version every time you update your environment variables.

Having it only separated for each environment will make you face the same issues with the cache.

jfbaraky avatar Jul 21 '23 20:07 jfbaraky

You should concatenate all environment variables, so the cacheVersion changes together with any environment variable.

Example metro.config.js:

module.exports = {
  cacheVersion: [process.env.VAR1, process.env.VAR2, …].join(‘’)
}

o-alexandrov avatar Jul 21 '23 21:07 o-alexandrov

Shouldn't this be the default behavior?

At least for the development variables. Should they be cached at all?

jfbaraky avatar Jul 24 '23 11:07 jfbaraky

I can confirm this happens with React Native CLI too (i.e. react-native command)

sanjarcode avatar Oct 12 '23 08:10 sanjarcode

npm start -- --reset-cache it worked for me

pauloguilherm avatar Oct 28 '23 13:10 pauloguilherm

Setting cacheVersion in metro.config.js doesn't reset cache when switch from one .env to another (or just any changes that happens in .env basically).

We want to repeat : resetCache is a bad option to solve the caching issue, as you disable caching for everything.

You might wanna change your .env settings easily without manual deleting of cache. But still want to keep your cache when your working on the same env

louisiscoding avatar Nov 14 '23 10:11 louisiscoding

The problem in my case was Metro cache. My solution was to add this line to the metro.config.js file:

module.exports = {
  ...
  cacheVersion: process.env.APP_ENV,
  ...
};

my package.json scripts are (always clearing cache for production runs) -

    "start": "react-native start",
    "start:staging": "APP_ENV=staging react-native start",
    "start:prod": "APP_ENV=prod react-native start --reset-cache",

according to the docs it's "an arbitrary string appended to all cache keys in the project before they are hashed". Subsequent runs of the same env keep the cache, while switching between them seems to invalidate it.

Hope it helps

when I trying with this I got the following error only. even after I change in the metro.config.js

'APP_ENV' is not recognized as an internal or external command, operable program or batch file.

SulthanYS avatar Nov 24 '23 11:11 SulthanYS

I'm only seemingly having this issue with my "Production" file. Staging and Dev works, but the moment I set it to APP_ENV=Production it only reads from my .env.staging file. However when I set the release to Debug (dev), it reads from my .env.development file without any issue.

mofolo avatar Jan 04 '24 07:01 mofolo

@mofolo this is a whole other issue unfortunately. If you're using production, you don't need APP_ENV, since NODE_ENV should already do it. Also, APP_ENV doesn't really work with production and development. Basically APP_ENV was introduced very late for people who were struggling to override NODE_ENV, but it has it's quirks so try to avoid using it where possible. Feel free to open a separate ticket on this if I'm wrong

goatandsheep avatar Feb 09 '24 18:02 goatandsheep

@mofolo actually it occurred to me, what if you try in the config setting the name for APP_ENV to something like REACT_APP_ENV

{
  "plugins": [
    ["module:react-native-dotenv", {
     "envName": "REACT_APP_ENV"
    }]
  ]
}

goatandsheep avatar Feb 09 '24 18:02 goatandsheep

@SulthanYS are you using Windows Powershell? to set environment variables in CLI, you need to do it differently

Set APP_ENV=test&& react-native start

goatandsheep avatar Feb 09 '24 18:02 goatandsheep

@jfbaraky you're right about the cache. it should be working and it isn't working. I just tested it now even with the package version resolutions. I worked with the babel team to try fix this. so i'm not sure why it's not working. Anyways, the solution is just to have to do api.cache(false) or --reset-cache every time you change your env type, or env values

goatandsheep avatar Feb 09 '24 19:02 goatandsheep

this works for me rm -rf node_modules/react-native-config/ios/ReactNativeConfig/GeneratedDotEnv.m

jovanialferez avatar Apr 22 '24 12:04 jovanialferez