Expo 中的环境变量

编辑页面

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


For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.

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

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

从 .env 文件读取环境变量

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

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

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

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 或你的开发构建中摇一摇手势后点击 Reload)才能看到更新后的值。

警告 不要将敏感信息(例如私钥)存储在 EXPO_PUBLIC_ 变量中。这些变量会以明文形式出现在你编译后的应用中。

变量如何被加载

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

如何从环境变量中读取

  • 每个环境变量都必须以 JavaScript 的点表示法静态地作为 process.env 的属性来引用,才能被内联。 例如,表达式 process.env.EXPO_PUBLIC_KEY 是有效的,并且会被内联。

  • 不支持该表达式的其他形式。例如,process.env['EXPO_PUBLIC_KEY']const {EXPO_PUBLIC_X} = process.env 是无效的,并且不会被内联。

使用多个 .env 文件定义不同环境

你可以定义任意 标准 .env 文件,因此可以同时拥有独立的 .env.env.local 文件,它们会按照标准优先级加载。

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

.gitignore
.env*.local

环境变量与 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_ENVtest 来执行命令。

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

如果你使用 EAS,建议改用 eas env:pull。这会用你选择的环境替换 .env.local,而不是依赖 NODE_ENV。如果你不使用 EAS,也可以通过编写脚本,用适合目标环境的内容覆盖 .env.local.env,来实现类似的行为。

禁用环境变量

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

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

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

Expo Application Services 中的环境变量

EAS Build

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

EAS Update

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

迁移到 Expo 环境变量

从 react-native-config 迁移

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

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

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

然后更新代码以使用 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 迁移

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

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

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

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 清除缓存。

从 direnv 迁移

将 JavaScript 中使用的任何环境变量从 .envrc 文件移动到 .env 文件中,并为其添加 EXPO_PUBLIC_ 前缀。

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

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

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

安全注意事项

切勿将带有 EXPO_PUBLIC_ 前缀的环境变量用于存储敏感密钥。当终端用户运行你的应用时,他们可以访问应用中的所有代码以及嵌入的环境变量。阅读更多关于存储敏感信息的内容。