Expo React Native:app.config.ts导入模块报错,需按设备切换服务器地址
问题根源
app.config.ts 是在 Node.js 环境中执行的构建/打包配置文件,而 expo-device、expo-constants 这类模块依赖 React Native 原生环境的 API(比如 NativeModulesProxy),无法在纯 Node.js 环境中运行。直接导入会触发模块语法错误,且即使强行导入,也无法获取到设备、调试主机地址等原生环境数据。
解决方案
推荐将「设备类型判断、动态 URL 生成」移到应用运行时处理,而非构建阶段的配置文件中。
步骤1:修改 app.config.ts 存储静态环境配置
只保留不同环境的基础配置,把动态逻辑剥离:
export default { // 其他原有配置(比如 name、slug、ios/android 配置) extra: { // 按环境定义基础URL和密钥 baseSupabaseUrl: process.env.NODE_ENV === 'development' ? 'http://localhost:54321' : 'https://project.supabase.co', anonKey: process.env.NODE_ENV === 'development' ? 'anonKey_dev' : process.env.NODE_ENV === 'staging' ? 'anonKey_staging' : 'anonKey_prod', bucket: process.env.NODE_ENV === 'development' ? 'bucket-dev' : process.env.NODE_ENV === 'staging' ? 'bucket-staging' : 'bucket-prod', }, };
步骤2:在应用入口(如 App.tsx)中动态生成 URL
在运行时获取设备信息和调试主机地址,拼接正确的 API URL:
import React, { useEffect, useState } from 'react'; import Constants from 'expo-constants'; import * as Device from 'expo-device'; export default function App() { // 初始化URL为配置文件中的基础值 const [supabaseUrl, setSupabaseUrl] = useState<string>( Constants.expoConfig?.extra?.baseSupabaseUrl || '' ); useEffect(() => { if (process.env.NODE_ENV === 'development') { let apiUrl = ''; if (Device.isDevice) { // 真机环境:从debuggerHost提取主机IP const hostIp = Constants.debuggerHost?.split(':')?.shift(); apiUrl = hostIp ? `http://${hostIp}:54321` : Constants.expoConfig?.extra?.baseSupabaseUrl || ''; } else { // 模拟器环境:使用固定的10.0.2.2映射本地服务 apiUrl = 'http://10.0.2.2:54321'; } setSupabaseUrl(apiUrl); } }, []); // 后续用supabaseUrl初始化Supabase客户端即可 return ( // 你的应用UI代码 ); }
备选方案:通过环境变量手动传递主机IP(适合必须在配置文件处理的场景)
如果一定要在 app.config.ts 中生成 URL,只能通过手动设置环境变量传递主机IP(Node.js 环境无法自动获取原生调试地址):
启动 Expo 时传入环境变量:
# Windows set EXPO_DEV_HOST_IP=你的本地IPv4地址&& npx expo start # macOS/Linux EXPO_DEV_HOST_IP=你的本地IPv4地址 npx expo start修改
app.config.ts读取环境变量:export default { // 其他配置 extra: { get supabaseUrl() { const env = process.env.NODE_ENV || 'development'; if (env === 'development') { // 手动通过环境变量区分真机/模拟器(比如启动时加 DEVICE_TYPE=device) const isDevice = process.env.DEVICE_TYPE === 'device'; const hostIp = process.env.EXPO_DEV_HOST_IP || '10.0.2.2'; return isDevice ? `http://${hostIp}:54321` : 'http://10.0.2.2:54321'; } return process.env.NODE_ENV === 'staging' ? 'https://project.supabase.co' : 'https://project.supabase.co'; }, anonKey: process.env.NODE_ENV === 'development' ? 'anonKey_dev' : process.env.NODE_ENV === 'staging' ? 'anonKey_staging' : 'anonKey_prod', bucket: process.env.NODE_ENV === 'development' ? 'bucket-dev' : process.env.NODE_ENV === 'staging' ? 'bucket-staging' : 'bucket-prod', }, };
内容的提问来源于stack exchange,提问作者Asaraspo
相关产品推荐
相关产品推荐

