Expo 中的环境变量

了解如何在 Expo 项目中使用环境变量。


环境变量是配置在源代码之外的键值对,它们允许你的应用根据不同的环境表现出不同的行为。例如,在构建应用的测试版本时,你可以启用或禁用某些功能,或在构建生产版本时切换到不同的 API 端点。

🌐 Environment variables are key-value pairs configured outside your source code that allow your app to behave differently depending on the environment. For example, you can enable or disable certain features when building a test version of your app, or switch to a different API endpoint when building for production.

Expo CLI 会自动从 .env 文件中加载带有 EXPO_PUBLIC_ 前缀的环境变量,以便在你的 JavaScript 代码中使用,无论何时使用 Expo CLI,例如在运行 npx expo start 启动应用的本地开发模式时。

🌐 The Expo CLI will automatically load environment variables with an EXPO_PUBLIC_ prefix from .env files for use within your JavaScript code whenever you use the Expo CLI, such as when running npx expo start to start your app in local development mode.

从 .env 文件读取环境变量

🌐 Reading environment variables from .env files

在项目目录的根目录下创建一个 .env 文件,并以 EXPO_PUBLIC_[NAME]=VALUE 的形式在新行中添加特定于环境的变量:

🌐 Create a .env file in the root of your project directory and add environment-specific variables on new lines in the form of EXPO_PUBLIC_[NAME]=VALUE:

.env
EXPO_PUBLIC_API_URL=https://staging.example.com EXPO_PUBLIC_API_KEY=abc123

现在你可以直接在源代码中使用环境变量:

🌐 Now you can use environment variables directly in your source code:

import { Button } from 'react-native'; function Post() { const apiUrl = process.env.EXPO_PUBLIC_API_URL; async function onPress() { await fetch(apiUrl, { ... }) } return <Button onPress={onPress} title="帖子" />; }

当你运行 npx expo start 时,process.env.EXPO_PUBLIC_API_URL 将在你的应用包中被替换为 https://staging.example.com。在你编辑代码时,变量可以实时更新,无需重启 Expo CLI 或清除缓存。你需要执行完全重新加载(例如,在 Expo Go 或你的开发构建中摇动设备后选择重新加载)才能看到更新后的值。

🌐 When you run npx expo start, process.env.EXPO_PUBLIC_API_URL will be replaced with https://staging.example.com in your app bundle. Variables can be updated as you edit your code without restarting the Expo CLI or clearing the cache. You will need to perform a full reload (for example, shake gesture and then Reload in Expo Go or your development build) to see the updated value.

警告 不要在 EXPO_PUBLIC_ 变量中存储敏感信息,如私钥。这些变量将在编译后的应用中以明文显示。

变量如何加载

🌐 How variables are loaded

Expo CLI 会根据标准 .env 文件解析加载 .env 文件,然后将代码中对 process.env.EXPO_PUBLIC_[VARNAME] 的所有引用替换为 .env 文件中设置的相应值。出于安全考虑,node_modules 中的代码不会受到影响。

🌐 Expo CLI loads .env files according to the standard .env file resolution and then replaces all references in your code to process.env.EXPO_PUBLIC_[VARNAME] with the corresponding value set in the .env files. Code inside node_modules is not affected for security purposes.

如何读取环境变量

🌐 How to read from environment variables

  • 每个环境变量必须作为 process.env 的属性使用 JavaScript 的点表示法静态引用,以便进行内联。 例如,表达式 process.env.EXPO_PUBLIC_KEY 是有效的,并且会被内联。
  • 不支持该表达式的替代版本。例如,process.env['EXPO_PUBLIC_KEY']const {EXPO_PUBLIC_X} = process.env 是无效的,并且不会被内联。

使用多个 .env 文件定义单独的环境

🌐 Using multiple .env files to define separate environments

你可以定义任何标准 .env 文件,因此可以有单独的 .env.env.local 文件,它们将按照标准优先级加载。

🌐 You can define any of the standard .env files, so it is possible to have separate .env and .env.local, files and they will load according to the standard priority.

你可以选择提交默认的 .env 文件或其他标准配置,但通常 .env.local 文件应添加到你的 .gitignore 中,因为它们用于指定特定于本地机器的环境配置(例如,如果你需要对本地服务器发出请求,则可能需要你的网络 IP 地址)。

🌐 You may choose to commit the default .env file or other standard configurations, but generally .env.local files should be added to your .gitignore, because they are used to specify environment configuration specific to your local machine (such as, for example, your network IP address if you need it to make a request against a local server).

.gitignore
.env*.local

环境变量和 NODE_ENV

🌐 Environment variables and NODE_ENV

我们不建议使用 NODE_ENV 来切换 .env 文件(例如 .env.test.env.production)。虽然从技术上来说是可行的(NODE_ENV=test npx expo start 会加载 .env.test)——但它可能不会按照你预期的方式工作。例如,npx expo export 总是会强制 NODE_ENV 设置为 production,所以 NODE_ENV=test npx expo export 实际上不会在将 NODE_ENV 设置为 test 的情况下运行命令。

🌐 We recommend against using NODE_ENV to switch between .env files (such as .env.test and .env.production). While it is technically possible (NODE_ENV=test npx expo start will load .env.test) — it may not behave as you would expect. For example, npx expo export always forces NODE_ENV to production, so NODE_ENV=test npx expo export will not actually run the command with the NODE_ENV set to test.

构建在 Expo CLI 命令之上的其他工具也会表现出相同的行为——例如,eas update 会调用 npx expo export,因此 NODE_ENV=test eas update 也将不会在 NODE_ENV 设置为 test 的情况下运行(它会是 production)。NODE_ENV 环境变量被许多工具以不同的方式使用(例如,如果你运行 NODE_ENV=production npm install,那么你的 devDependencies 将不会被安装),我们发现对于 React Native 项目来说,最好不要为了这个用例进一步过度使用它。

🌐 Other tools that build on top of Expo CLI commands will exhibit the same behavior — for example, eas update calls into npx expo export and, as a result, NODE_ENV=test eas update will similarly not run with the NODE_ENV set to test (it will be production). The NODE_ENV environment variable is used by many tools in different ways (for example, if you run NODE_ENV=production npm install then your devDependencies will not be installed) and we have found that for React Native projects, it's best not to overload it further for this use case.

如果你使用 EAS,考虑改用 eas env:pull。这将会把你的 .env.local 与你选择的环境互换,而不依赖于 NODE_ENV。即使没有 EAS,你也可以通过编写脚本将 .env.local.env 覆盖为你希望使用的环境的内容,从而实现类似的行为。

🌐 If you use EAS, consider using eas env:pull instead. This will swap your .env.local with an environment of your choice, rather than depending on NODE_ENV. You can accomplish a similar behavior without EAS by writing a script to overwrite .env.local or .env with the appropriate contents for the environment you wish to work with.

禁用环境变量

🌐 Disabling environment variables

Expo CLI 中的环境变量有两部分,并且都可以禁用:

🌐 Environment variables in Expo CLI have two parts and both can be disabled:

  1. Expo CLI 会自动将 .env 文件加载到全局进程中。要禁用此行为,请在运行任何 Expo CLI 命令之前,将环境变量 EXPO_NO_DOTENV 设置为 1EXPO_NO_DOTENV=1
  2. Expo 的 Metro 配置包括在客户端 JavaScript 包中内联序列化环境变量。要禁用此行为,你可以使用 EXPO_NO_CLIENT_ENV_VARS=1

如果你遇到环境变量问题,可以尝试禁用其中一项或两项功能。

🌐 If you're experiencing issues with environment variables, you can try disabling one or both of these features.

Expo 应用服务中的环境变量

🌐 Environment variables in Expo Application Services

EAS 构建

🌐 EAS Build

EAS Build 使用 Metro Bundler 构建嵌入在你的应用二进制文件中的 JavaScript 包,因此它会使用随构建作业上传的 .env 文件将 EXPO_PUBLIC_ 变量内联到你的代码中。EAS Build 还允许你在 eas.json 的构建配置文件中以及通过 EAS Secrets 定义环境变量。有关更多信息,请查看 EAS Build 关于环境变量和构建密钥的文档。

EAS 更新

🌐 EAS Update

EAS 更新 在你的本地环境或 CI 中使用 Metro Bundler 来构建你的应用包,因此它会使用可用的 .env 文件将 EXPO_PUBLIC_ 变量内联到你的代码中。有关更多信息,请查看 EAS 更新文档中的环境变量

迁移到 Expo 环境变量

🌐 Migrating to Expo environment variables

来自 react-native-config

🌐 From react-native-config

更新你的 .env 文件,在 JavaScript 代码中使用的任何变量前加上前缀 EXPO_PUBLIC_

🌐 Update your .env files to prefix any variables used within your JavaScript code with EXPO_PUBLIC_:

.env
- API_URL=https://myapi.com + EXPO_PUBLIC_API_URL=https://myapi.com

如果你有任何非标准的 .env 文件(例如 .env.staging),你需要将它们迁移到其中一个标准 .env 文件中。

然后更新你的代码以使用 process.env.EXPO_PUBLIC_[VARNAME]

🌐 Then update your code to use process.env.EXPO_PUBLIC_[VARNAME]:

- import Config from 'react-native-config'; - const apiUrl = Config.API_URL; + const apiUrl = process.env.EXPO_PUBLIC_API_URL;

来自 babel-plugin-transform-inline-environment-variables

🌐 From babel-plugin-transform-inline-environment-variables

使用 Babel 插件来转换代码中的环境变量引用,类似于 Expo 环境变量的工作方式。在 .env 文件中设置你的变量,并将变量名更新为使用 EXPO_PUBLIC_ 前缀:

🌐 Using a Babel plugin to transform your environment variable references in your code is similar to how Expo environment variables work. Set your variables inside a .env file and update your variable names to use the EXPO_PUBLIC_ prefix:

- const apiUrl = process.env.API_URL; + const apiUrl = process.env.EXPO_PUBLIC_API_URL;

然后你可以从你的 Babel 配置 中移除该插件:

🌐 Then you can remove the plugin from your Babel config:

babel.config.js
module.exports = function (api) { api.cache(true); return { presets: ['babel-preset-expo'], -- plugins: ['transform-inline-environment-variables'], }; };

更新 Babel 配置文件后,请务必使用 npx expo start --clear 清除缓存。

🌐 After updating your Babel config file, be sure to clear your cache with npx expo start --clear.

来自 direnv

🌐 From direnv

将 JavaScript 中使用的任何环境变量从 .envrc 文件移动到 .env 文件,并在前面加上前缀 EXPO_PUBLIC_

🌐 Move any environment variables used in your JavaScript from their .envrc file to a .env file and prefix it with EXPO_PUBLIC_.

以前使用 direnv 时,你需要使用一个 动态应用配置,该配置从 process.env 读取,以在 extra 字段上设置环境变量,以便可以通过 expo-constants 在 JavaScript 代码中使用它们。将这些引用直接移入你的代码,并添加 EXPO_PUBLIC_ 前缀:

🌐 Previously with direnv, you would need to use a dynamic app config that reads from process.env to set environment variables on the extra field so they can be used in your JavaScript code via expo-constants. Move those references directly into your code, adding the EXPO_PUBLIC_ prefix:

- import Constants from 'expo-constants'; - const apiUrl = Constants.expoConfig.extra.apiUrl; + const apiUrl = process.env.EXPO_PUBLIC_API_URL;

direnv 会根据你当前的目录在你的 shell 中自动加载和卸载环境变量,这意味着它可以影响在该目录下运行的任何进程的环境,而不仅仅是 Expo CLI。你可能仍然希望继续使用 direnv 来管理其他不用于 JavaScript 代码的环境变量。

安全考虑

🌐 Security considerations

切勿将敏感的秘密存储在以 EXPO_PUBLIC_ 为前缀的环境变量中。当终端用户运行你的应用时,他们可以访问应用中的所有代码和嵌入的环境变量。了解有关存储敏感信息的更多信息。

🌐 Never store sensitive secrets in environment variables that are prefixed with EXPO_PUBLIC_. When an end-user runs your app, they have access to all of the code and embedded environment variables in your app. Read more about storing sensitive info.