在 React Native Expo 项目中,为开发、测试和生产环境配置不同的 API endpoint 是一个常见的需求。这可以确保你在不同的环境中使用正确的配置,避免数据混乱或错误。下面是如何正确配置环境变量的步骤:
1. 安装 dotenv
和 react-native-dotenv
首先,你需要安装 dotenv
来加载 .env
文件中的环境变量,以及 react-native-dotenv
来在 React Native 应用中使用这些变量。
npm install dotenv react-native-dotenv --save
# 或者使用 yarn
yarn add dotenv react-native-dotenv
2. 创建 .env
文件
在你的项目根目录下,创建以下几个 .env
文件,分别对应不同的环境:
.env.development
:开发环境.env.staging
:测试环境.env.production
:生产环境
每个文件都包含对应环境的 API endpoint:
API_ENDPOINT=https://dev.example.com/api
API_ENDPOINT=https://staging.example.com/api
API_ENDPOINT=https://example.com/api
3. 配置 babel.config.js
为了让 react-native-dotenv
能够正确地注入环境变量,你需要配置 babel.config.js
文件。如果没有这个文件,请在项目根目录下创建一个。
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: [
['module:react-native-dotenv', {
moduleName: '@env',
path: '.env',
blacklist: null,
whitelist: null,
safe: false,
allowUndefined: true,
}]
]
};
};
moduleName
: 指定导入环境变量的模块名,这里设置为'@env'
,你可以根据自己的喜好修改。path
: 指定.env
文件的路径,默认为.env
,这里我们让它根据不同环境读取不同的.env
文件。blacklist
和whitelist
: 用于指定哪些变量可以被导入,可以设置为null
允许所有变量。safe
: 设置为true
时,如果.env
文件不存在,会抛出一个错误。设置为false
则不会。allowUndefined
: 设置为true
时,允许环境变量未定义。设置为false
则会抛出一个错误。
4. 修改 metro.config.js
(可选)
如果你的项目使用了自定义的 metro.config.js
文件,你可能需要确保它能够正确处理 .env
文件。通常情况下,Expo 项目不需要手动配置这个文件,但如果你有自定义配置,请检查以下内容:
const { getDefaultConfig } = require('metro-config');
module.exports = (async () => {
const defaultConfig = await getDefaultConfig();
const { resolver: { sourceExts, assetExts } } = defaultConfig;
return {
...defaultConfig,
transformer: {
...defaultConfig.transformer,
babelTransformerPath: require.resolve('react-native-babel-transformer'),
},
resolver: {
assetExts: assetExts.filter(ext => ext !== 'svg'),
sourceExts: [...sourceExts, 'svg', 'cjs'],
},
};
})();
确保 sourceExts
包含 cjs
,这可以解决一些模块加载的问题。
5. 在代码中使用环境变量
现在你可以在你的 React Native 代码中使用环境变量了。首先,你需要导入 @env
模块:
import { API_ENDPOINT } from '@env';
然后,你就可以使用 API_ENDPOINT
变量了:
import React, { useEffect, useState } from 'react';
import { View, Text } from 'react-native';
import { API_ENDPOINT } from '@env';
const App = () => {
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(`${API_ENDPOINT}/data`);
const json = await response.json();
setData(json);
} catch (error) {
console.error(error);
}
};
fetchData();
}, []);
return (
<View>
<Text>API Endpoint: {API_ENDPOINT}</Text>
{data && <Text>Data: {JSON.stringify(data)}</Text>}
</View>
);
};
export default App;
6. 配置 Expo 的启动脚本
为了让 Expo 在不同的环境下加载不同的 .env
文件,你需要修改 package.json
中的启动脚本。
{
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject",
"dev": "env-cmd -f .env.development expo start",
"staging": "env-cmd -f .env.staging expo start",
"production": "env-cmd -f .env.production expo start"
},
"dependencies": {
"@env": "^1.0.0",
"expo": "~48.0.18",
"expo-status-bar": "~1.4.4",
"react": "18.2.0",
"react-native": "0.71.8",
"react-native-dotenv": "^3.4.8"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"env-cmd": "^10.1.0"
}
}
这里我们使用了 env-cmd
这个包来指定要加载的 .env
文件。首先,你需要安装它:
npm install env-cmd --save-dev
# 或者使用 yarn
yarn add env-cmd --dev
然后,在 package.json
中添加对应的启动脚本,例如:
dev
:env-cmd -f .env.development expo start
staging
:env-cmd -f .env.staging expo start
production
:env-cmd -f .env.production expo start
现在,你可以使用以下命令来启动不同环境的应用:
npm run dev # 启动开发环境
npm run staging # 启动测试环境
npm run production # 启动生产环境
7. 清除缓存
在修改了 .env
文件或 babel.config.js
文件后,你可能需要清除 Expo 的缓存,以确保新的配置生效。
expo start -c
或者删除 node_modules
文件夹并重新安装依赖:
rm -rf node_modules && npm install
# 或者使用 yarn
rm -rf node_modules && yarn install
总结
通过以上步骤,你就可以在 React Native Expo 项目中为不同的环境配置不同的 API endpoint 了。这种方法可以帮助你更好地管理不同环境的配置,提高开发效率,并减少出错的可能性。记住,环境变量是敏感信息,不要将它们提交到代码仓库中。