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 的形式在新行中添加环境相关变量:
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 地址)。
.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_ENV 为 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 项目来说,最好不要为了这个用例进一步滥用它。
如果你使用 EAS,建议改用 eas env:pull。这会用你选择的环境替换 .env.local,而不是依赖 NODE_ENV。如果你不使用 EAS,也可以通过编写脚本,用适合目标环境的内容覆盖 .env.local 或 .env,来实现类似的行为。
禁用环境变量
Expo CLI 中的环境变量有两个部分,并且这两部分都可以被禁用:
- Expo CLI 会自动将 .env 文件加载到全局进程中。要禁用此行为,请在运行任何 Expo CLI 命令之前,将环境变量
EXPO_NO_DOTENV设置为1:EXPO_NO_DOTENV=1。 - 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_ 前缀:
- 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 配置 中移除该插件:
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_ 前缀的环境变量用于存储敏感密钥。当终端用户运行你的应用时,他们可以访问应用中的所有代码以及嵌入的环境变量。阅读更多关于存储敏感信息的内容。