Flutter 多环境配置:flavor

在真实项目开发中,多环境切换是每个开发者都会遇到的常见需求。无论是开发、测试、预发布还是正式环境,甚至是白标产品的构建,都需要能够快速、可靠地在不同配置间切换。

手动修改配置文件虽然简单直接,但随着项目复杂度增加,这种方式容易出错且效率低下。而使用Flavor,可以将不同环境的配置完全隔离,通过构建时选择特定flavor,确保每次构建都使用正确的配置,大大降低了人为错误的风险,提高了开发效率和发布安全性,显著提升 CI/CD 流程效率与开发团队协作体验。

什么是Flutter flavor?

Flutter flavor本质上类似于Android的Build Variant和iOS的Scheme。它允许开发者从同一代码库构建多个具有不同配置的应用版本,每个版本可以拥有独立的:

  • 应用标识(包名/Bundle ID)
  • 资源文件(图标、字符串等)
  • 构建配置
  • 运行时参数

其典型应用场景包括:

  • 不同环境间的配置隔离(dev/staging/prod)
  • 灰度测试或白标化需求
  • 免费版/付费版功能差异化

这样我们便可以在构建时自动区分包名与资源、简化构建流程、减少手动出错风险、便于团队协作与 CI/CD 自动部署。

在Android上配置flavor

根据 Flutter 官方文档,在Android上配置Flavor主要通过修改android/app/build.gradle文件实现:

arduino 复制代码
android {
  flavorDimensions "default"
  productFlavors {
    dev {
      dimension "default"
      applicationIdSuffix ".dev"
      resValue "string", "app_name", "MyApp Dev"
    }
    staging {
      dimension "default"
      applicationIdSuffix ".stg"
      resValue "string", "app_name", "MyApp Stg"
    }
    prod {
      dimension "default"
      applicationIdSuffix ".prod"
      resValue "string", "app_name", "MyApp"
    }
  }
}

配置项说明:

其中flavorDimensions定义了 flavor 所属的维度名称。在 Android Gradle 插件(3.0.0 及以上)中,每个 flavor 必须指定所属维度,否则会报错。 **dimension "default":**将当前 flavor(如 dev)归属到 default 维度中。所有 flavors 必须指定维度,且同一维度内的 flavors 为互斥条件(仅能选其中一个构建)。

**applicationIdSuffix ".dev":**设置包名后缀,如果基础包名为 com.example.app,dev 版本实际的包名为 com.example.app.dev。这样我们可以在同一设备上同时安装不同 flavor 的 APK,便于开发、测试不同环境版本 。

resValue "string", "app_name", "MyApp Dev": 动态生成一个 Android string 资源,资源名为 app_name,值为 MyApp Dev。这样当我们将AndroidManifest.xml 中的 android:label 设置为 @string/app_name之后,我们启动不同的flavor的应用后,每个app将会显示各自的app名称。 之后运行命令:

arduino 复制代码
flutter run --flavor dev -t lib/main_dev.dart
flutter run --flavor staging -t lib/main_staging.dart
flutter run --flavor prod -t lib/main_prod.dart

就可以分别运行安装不同配置多个版本的app,同时app名称和包名保持独立。

在iOS上配置flavor

iOS上的Flavor配置主要通过配置Scheme以及Build Configuration来实现:

  1. 打开 ios/Runner.xcworkspace
  2. 在 Xcode 中通过 Product → Scheme → New Scheme 添加 devstagingprod
  3. Info → Configurations 中新建多种配置 Debug-dev, Release-dev
  1. 为每个 Scheme 指定不同的 Bundle Identifier 和 Display Name(通过 APP_DISPLAY_NAME 自定义变量绑定到 Info.plist)

我们可以创建不同的资源目录如(DevAssets,StagingAssets等),在Build Settings中为每个Configuration设置不同的图标集以及名称。

运行时配置

flavors 适合构建时配置(如包名、图标、App 名称),而 runtime 参数 (如 API URL、调试标识、公钥私钥)推荐用**---dart-define**或 .env/JSON 配置文件方式加载:

---dart-define:

arduino 复制代码
flutter run --flavor dev --dart-define API_URL=https://dev.api.com

运行期间,在代码中可通过 const String.fromEnvironment('API_URL') 获取对应值。

.env/JSON:

  1. 创建环境特定配置文件(如 config_dev.json, config_prod.json
  2. 在应用启动时加载对应配置:
arduino 复制代码
Future<void> main() async {
  const flavor = String.fromEnvironment('FLAVOR', defaultValue: 'dev');
  final config = await loadConfig('config_$flavor.json');
  runApp(MyApp(config: config));
}

Firebase 多环境配置

如果 App 使用 Firebase,flavor 通常需要配置独立的 Firebase 项目与配置文件。推荐使用 FlutterFire CLI:

  • 为每个 flavor(dev/staging/prod)分别创建 Firebase 项目
  • 使用 flutterfire configure --project --out-lib firebase_options_.dart
  • 每个 flavor 对应不同的配置文件,并且可通过独立入口文件(main_dev.dart 等)加载

在这里我的建议是为每个 flavor 设置独立入口文件,以确保只有当前 flavor 的配置被打包。

常见的问题

问题 建议解决方式
构建混乱、资源覆盖 引入统一管理工具(flutter_flavorizr / FlutterFire CLI)并生成文档
flavor 命名规范 建议统一使用 dev/staging/prod 命名,Bundle ID 后缀匹配(如 .dev, .stg)
敏感配置泄露风险 使用多个入口文件,避免全部配置都打包在同一个 main.dart 中
CI/CD 集成不统一 使用 shell 脚本或 YAML 配置统一构建流程,避免人为误操作

通过使用flavor,我们可以在同一代码库中轻松管理多个 App 环境,从 Android 与 iOS 构建配置入手,再结合运行时参数与 Firebase 设置,将 App 的构建流程标准化、自动化。结合 CI/CD 自动发布能力,我们的项目将具备真正的工程级管理能力,适应复杂真实项目场景。

相关推荐
luckyzlb5 小时前
03-node.js & webpack
前端·webpack·node.js
左耳咚5 小时前
如何解析 zip 文件
前端·javascript·面试
程序员小寒5 小时前
前端高频面试题之Vue(初、中级篇)
前端·javascript·vue.js
陈辛chenxin5 小时前
软件测试大赛Web测试赛道工程化ai提示词大全
前端·可用性测试·测试覆盖率
沿着路走到底5 小时前
python 判断与循环
java·前端·python
Code知行合壹5 小时前
AJAX和Promise
前端·ajax
大菠萝学姐6 小时前
基于springboot的旅游攻略网站设计与实现
前端·javascript·vue.js·spring boot·后端·spring·旅游
心随雨下6 小时前
TypeScript中extends与implements的区别
前端·javascript·typescript
摇滚侠6 小时前
Vue 项目实战《尚医通》,底部组件拆分与静态搭建,笔记05
前端·vue.js·笔记·vue
双向336 小时前
CANN训练营实战指南:从算子分析到核函数定义的完整开发流程
前端