goatandsheep / react-native-dotenv

Load react native environment variables using import statements for multiple env files.
https://www.npmjs.com/package/react-native-dotenv
MIT License
793 stars 47 forks source link

Incompatible with expo-router #501

Open brentvatne opened 3 months ago

brentvatne commented 3 months ago

Describe the bug

Cross-posting from the Expo repository: https://github.com/expo/expo/issues/28933

So what's happening here is that react-native-dotenv is agressively inlining all environment variables from the machine in the bundle. This has 2 side effects that cause the behavior we are seeing: It precedes the babel-preset-expo/src/expo-router-plugin.ts transformation, causing important settings of Expo Router to be overwritten. (this file) In the system environment (outside the bundle), there is an environment variable with the same name used as the require.context within Expo Router. It's from the type generation, and uses the absolute path we are seeing here (generated here, set as process.env here)

react-native-dotenv seems to do some internal evaluation (possibly due to static rendering, since we evaluate bundle code). Even when setting safe or allowlist / blocklist, it seems to pollute/mutate all environment variables

To Reproduce Steps to reproduce the behavior:

  1. Run npx create-expo-app
  2. cd my-app
  3. npm install react-native-dotenv
  4. Add the react-native-dotenv babel plugin
  5. Boot the app with npx expo start --ios
  6. Notice that you see "Welcome to Expo" screen rather than the routes in /app (without the plugin, you will see tabs and the app/(tabs)/index.tsx screen.

https://github.com/brentvatne/repro-dotenv

Expected behavior react-native-dotenv should play nicely with expo-router.

Screenshots n/a

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context Given this incompatibility, we are currently recommending that developers using Expo Router use Expo CLI's built-in environment variable support.

I think that one way to fix this issue would be to change the default behavior to whitelisted env vars only. In my opinion, not having this default can be a footgun.

github-actions[bot] commented 3 months 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/501

byCedric commented 3 months ago

To provide some more context, Expo uses internal environment variables that are not considered public (and therefore should never end up in the bundle). If these variables can be left untouched, we should have a way to get Expo Router and react-native-dotenv to work together.

Basically, all EXPO_* variables should be left alone, with the gray area being EXPO_PUBLIC_* variables. This is mostly defined by users using the default .env integration in Expo.

goatandsheep commented 3 months ago

Does it work if you add these to blocklist? I'm happy to add this hint to docs if it works.

goatandsheep commented 3 months ago

This babel plugin is meant to be simple and non specific. React native dotenv is meant to encourage best practices and you're welcome to go around this using blocklist. Expo-variables is a great alternative, but I'm not sure this is a fault of the library just yet. If you can provide a sample I'd be happy to take a look.

goatandsheep commented 3 months ago

My bad I didn't see you provided a repro project. I'm taking a look now

goatandsheep commented 3 months ago

I also didn't read that blocklist didn't work for you. That is concerning.

byCedric commented 3 months ago

Yeah, I'm not exactly sure what's going on. In Expo, we do some bundling and possible static rendering (basically evaluating parts of bundle code in Node). Not sure if that might have anything to do with it. So far, neither safe + path, blocklist, or allowlist worked for me, unclear why.

It would be nice if this library can work in Expo, if users need more control over it.

danicunhac commented 3 months ago

I'm having the same problem and since my project is still under development I've unshifted EXPO_PUBLIC_ to my env variables, as specified in https://docs.expo.dev/guides/environment-variables/.

mayel15 commented 2 months ago

I was facing the same problem. FYI, the incompatibility of react-native-dotenv with expo-router can load a default screen of expo, and not your normal dev app you're building.

Simulator Screenshot - iPhone SE (3rd generation) - 2024-07-01 at 22 22 23

As an alternative for react-native-dotenv, they're the default Expo CLI's built-in environment variable support or react-native-config for bare react native app.

a-eid commented 2 months ago

@mayel15 unfortunately expo's built in env variables is not ideal, rn dotenv is way better.

brentvatne commented 1 month ago

@a-eid - can you explain the limitations that you're encountering? you could try disabling them, i'm not sure if that will help here though: https://docs.expo.dev/guides/environment-variables/#disabling-environment-variables

a-eid commented 1 month ago

@brentvatne in expo we don't have the ability to load arbitrary .env files. for example .env.qa or .env.staging you can only load standard .env files .env.production, .env.test or .env.development.

however with RN dotenv, we're able to do so use the APP_ENV env variable.

RobSteward commented 1 week ago

I was facing the same problem. FYI, the incompatibility of react-native-dotenv with expo-router can load a default screen of expo, and not your normal dev app you're building.

Simulator Screenshot - iPhone SE (3rd generation) - 2024-07-01 at 22 22 23

As an alternative for react-native-dotenv, they're the default Expo CLI's built-in environment variable support or react-native-config for bare react native app.

+1 Fortunately, I was able not to depend on react-native-dotenv.

cchoi94 commented 3 days ago

+1 here, our app is dependent on this package for reasons outlined by @a-eid. Is there something in the works for a fix? Would love to update to expo 51 asap.