自定义 Maps Config Plugin 实战
Created on
前言
在真实项目里,地图接入经常遇到两个问题:不同地区的地图服务差异,以及多环境 Key 与原生配置的复杂性。用 Config Plugin 把这些配置固化下来,才能保证 prebuild 和升级的稳定性。
本文以“高德 + Google Maps 双栈”作为目标,拆解一个可复用的地图插件设计与落地方式。
设计目标
- 同时支持高德和 Google Maps
- 使用环境变量配置不同环境的 Key
- 按平台自动注入原生配置
- 运行时可切换地图提供商
插件入口:统一解析与分发
一个合理的入口应负责三件事:
- 解析环境变量占位符
- 生成高德与 Google 的配置
- 按需组合多个子插件
示例结构:
const { withPlugins } = require("@expo/config-plugins");
const withGoogleMapsAndroid = require("./withGoogleMapsAndroid");
const withGoogleMapsIOS = require("./withGoogleMapsIOS");
const withGaodeMap = require("expo-gaode-map/app.plugin");
const withMaps = (config, props = {}) => {
const iosKey = resolveEnvPlaceholder(
props.iosKey || process.env.EXPO_PUBLIC_GAODE_IOS_API_KEY || ""
);
const androidKey = resolveEnvPlaceholder(
props.androidKey || process.env.EXPO_PUBLIC_GAODE_ANDROID_API_KEY || ""
);
const googleMapsApiKey = resolveEnvPlaceholder(
props.googleMapsApiKey || process.env.EXPO_PUBLIC_GOOGLE_MAPS_KEY || ""
);
const plugins = [];
if (iosKey || androidKey) {
plugins.push([withGaodeMap, { iosKey, androidKey }]);
}
if (googleMapsApiKey) {
plugins.push([withGoogleMapsAndroid, { googleMapsApiKey }]);
plugins.push([withGoogleMapsIOS, { googleMapsApiKey }]);
}
return withPlugins(config, plugins);
};
Android: Manifest + Gradle
Google Maps 的 Android 侧需要两块配置:
- Manifest meta-data 写入 API Key
- app/build.gradle 添加 Google Play Services 依赖
示例片段:
AndroidConfig.Manifest.addMetaDataItemToMainApplication(
mainApplication,
"com.google.android.geo.API_KEY",
props.googleMapsApiKey,
"value"
);
// build.gradle
implementation "com.google.android.gms:play-services-maps:18.2.0"
implementation "com.google.android.gms:play-services-location:21.0.1"
同时建议补齐定位权限,避免地图加载但无法获取位置信息。
iOS: Info.plist 注入
Google Maps 的 iOS 侧只需要写入 GMSApiKey,并确保定位文案存在:
config.modResults.GMSApiKey = props.googleMapsApiKey;
config.modResults.NSLocationWhenInUseUsageDescription ||=
"我们需要访问您的位置以显示您附近的服务";
高德: 使用官方插件
高德 SDK 的原生接入较复杂,推荐直接调用 expo-gaode-map 官方插件。你的自定义插件只需要做两件事:
- 统一 Key 的来源
- 将配置透传给官方插件
这样既复用社区维护能力,又避免自己维护原生 SDK 更新。
运行时切换地图提供商
在 JS 层通过环境变量决定使用哪个 Provider:
const provider = process.env.EXPO_PUBLIC_MAP_PROVIDER;
// gaode 或 google
这样可以实现:
- 国内环境默认高德
- 国际环境默认 Google
- QA 环境可切换验证
在 app.config 中启用
[
"@repo/maps/plugin",
{
iosKey: process.env.EXPO_PUBLIC_GAODE_IOS_API_KEY,
androidKey: process.env.EXPO_PUBLIC_GAODE_ANDROID_API_KEY,
googleMapsApiKey: process.env.EXPO_PUBLIC_GOOGLE_MAPS_KEY,
enableLocation: true,
enableBackgroundLocation: false,
},
];
验证流程
expo prebuild后检查 AndroidManifest 与 Info.plist- 真机运行确认定位权限与地图加载
- 切换地图提供商验证渲染差异
小结
一个好的 Maps Config Plugin 不只是“写 Key”,而是把多地图服务、多环境 Key、原生配置差异封装成统一入口。只要这层稳定,地图能力在项目内的复用成本会大幅下降。