expo / expo

An open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.
https://docs.expo.dev
MIT License
31.05k stars 4.91k forks source link

react-native-dotenv incompatible with expo-router #28933

Open brentvatne opened 1 month ago

brentvatne commented 1 month ago

Minimal reproducible example

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

What platform(s) does this occur on?

Android, iOS, Web

Did you reproduce this issue in a development build?

Yes

Summary

The problem: when you use react-native-dotenv in an app with expo-router, the react-native-dotenv babel plugin will clobber all of the expo-router env vars and inject an env var that is normally only set for the sake of type generation.

The result is that Expo CLI can't find the app directory containing your routes, and you see a "Welcome to Expo" screen inviting you to get started. More detailed analysis from @byCedric:

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

Environment

  expo-env-info 1.2.0 environment info:
    System:
      OS: macOS 14.4.1
      Shell: 5.9 - /bin/zsh
    Binaries:
      Node: 20.12.2 - ~/.nvm/versions/node/v20.12.2/bin/node
      Yarn: 1.22.21 - /opt/homebrew/bin/yarn
      npm: 10.5.0 - ~/.nvm/versions/node/v20.12.2/bin/npm
      Watchman: 2024.03.25.00 - /opt/homebrew/bin/watchman
    Managers:
      CocoaPods: 1.15.2 - /opt/homebrew/bin/pod
    SDKs:
      iOS SDK:
        Platforms: DriverKit 23.4, iOS 17.4, macOS 14.4, tvOS 17.4, visionOS 1.1, watchOS 10.4
      Android SDK:
        API Levels: 34
        Build Tools: 33.0.1, 34.0.0
        System Images: android-34 | Google APIs ARM 64 v8a
    IDEs:
      Android Studio: 2023.2 AI-232.10227.8.2321.11479570
      Xcode: 15.3/15E204a - /usr/bin/xcodebuild
    npmPackages:
      expo: ~51.0.7 => 51.0.7
      expo-router: ~3.5.14 => 3.5.14
      react: 18.2.0 => 18.2.0
      react-dom: 18.2.0 => 18.2.0
      react-native: 0.74.1 => 0.74.1
      react-native-web: ~0.19.10 => 0.19.11
    npmGlobalPackages:
      eas-cli: 9.0.6
    Expo Workflow: managed

Expo Doctor Diagnostics

npx expo-doctor@latest

✔ Check Expo config for common issues
✔ Check package.json for common issues
✔ Check native tooling versions
✔ Check dependencies for packages that should not be installed directly
✔ Check for common project setup issues
✔ Check for issues with metro config
✔ Check npm/ yarn versions
✔ Check Expo config (app.json/ app.config.js) schema
✔ Check that packages match versions required by installed Expo SDK
✔ Check for legacy global CLI installed locally
✔ Check that native modules do not use incompatible support packages
✔ Check that native modules use compatible support package versions for installed Expo SDK

Didn't find any issues with the project!
bruno-monteiro1 commented 1 month ago

babel-plugin-transform-inline-environment-variables also seems to cause the issue

navom1 commented 1 month ago

I am having this same issue... is there an react-native-dotenv alternative we can use to read a .env file?

JoeM-RP commented 4 weeks ago

I am having this same issue... is there an react-native-dotenv alternative we can use to read a .env file?

I converted to the built-in system following this guide, with this caveat from the docs:

Do not store sensitive info, such as private keys, in EXPOPUBLIC variables. These variables will be visible in plain-text in your compiled application.

I'm still pondering a good solution for private keys in our solution, but the standard convention works for most of our variables in the meantime.