Open AbdulBsit opened 1 year ago
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
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.
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
yarn start --reset-cache
"resolutions": {
"@babel/core": "^7.20.2",
"babel-loader": "^8.3.0"
}
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'],
},
};
})();
I experience the same issue. Is there any update or solution?
same here
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
Having the same issue. Setting api.cache(false)
doesn't solve it either.
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
I am having the same issue. Is there any update or solution?
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 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.
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 ;))
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!
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
This is what worked for me in the metro.config.js
file:
resetCache: true
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.
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.
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.
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(‘’)
}
Shouldn't this be the default behavior?
At least for the development variables. Should they be cached at all?
I can confirm this happens with React Native CLI too (i.e. react-native
command)
npm start -- --reset-cache
it worked for me
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
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.
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 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
@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"
}]
]
}
@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
@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
this works for me rm -rf node_modules/react-native-config/ios/ReactNativeConfig/GeneratedDotEnv.m
Hi,
the module import with version 3.4.11
is breaking but I tried lower the version to 3.4.9
and only process.env.
seems to work.
Could not resolve @env
on launch.
After scratching my head a lot the workaround i did is explained in this article
updating cacheVersion
in metro.config.js
did not work for me
so i used resetCache
and to update that i am calculating hash of env files and updating as required in a prestart script
since i am working on windows my solution is mainly for that but i think it can be used on other platforms
hope this helps!
prestart.mjs
import inquirer from 'inquirer';
import fs from 'fs';
import crypto from 'crypto'; // To calculate file hashes
const questions = [
{
type: 'list',
name: 'environment',
message: 'Which environment to run in?',
choices: ['development', 'production'],
default: 'development'
}
];
inquirer.prompt(questions).then(async (answers) => {
const env = answers.environment;
const envFile = `.env.${env}`;
try {
// Check if the environment file exists
if (!fs.existsSync(envFile)) {
console.error(`Environment file ${envFile} not found.`);
return;
}
// Calculate the hash of the environment file
const fileHash = calculateFileHash(envFile);
// Store previous state (if available)
const prevStateFile = '.prestart.state.json';
let prevState = {};
if (fs.existsSync(prevStateFile)) {
prevState = JSON.parse(fs.readFileSync(prevStateFile, 'utf8'));
}
// Check for changes
const envChanged = prevState.env !== env;
const fileChanged = prevState.fileHash !== fileHash;
// Update .env file and set resetCache
const shouldResetCache = envChanged || fileChanged;
fs.writeFileSync('.env', `APP_ENV=${env}\nresetCache=${shouldResetCache}`);
// Update the state file
fs.writeFileSync(prevStateFile, JSON.stringify({ env, fileHash }));
console.log(`Running in ${env} mode...`);
} catch (error) {
console.error('Error during setting environment:', error);
}
});
function calculateFileHash(filename) {
const fileBuffer = fs.readFileSync(filename);
const hash = crypto.createHash('sha256');
hash.update(fileBuffer);
return hash.digest('hex');
}
metro.config.js
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
require('dotenv').config();
/**
* Metro configuration
* https://reactnative.dev/docs/metro
*
* @type {import('metro-config').MetroConfig}
*/
const config = {
resetCache: process.env.resetCache === 'true',
};
module.exports = mergeConfig(getDefaultConfig(__dirname), config);
package.json
{
...,
"scripts": {
...,
"prestart": "node prestart.mjs",
...
},
...
}
I wonder, when the files change, it should already be picked up by the plugin, since it checks the modified time of each file?
even using cacheVersion in metro.config does not work reliably. Because the babel plugin will only pick up changes in files and not reprocess them, even if the metro cache ins invalidated.
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