Как создать различные версии моего приложения Flutter для qa/dev/prod?

Я создаю приложение Flutter, и у меня есть переменные с разными значениями для разных сред (QA, dev, prod и т.д.). Какой хороший способ организовать мое приложение, чтобы я мог легко создать сборку для QA, dev, prod и других сред?

Ответ 1

Один из способов сделать это: создать различные main_<environment>.dart каталоге lib/ вашего проекта.

Каждый main_<environment>.dart содержит конфигурационные параметры/значения, специфичные для среды (например, имена разных баз данных и т.д.). Каждый main_<environment>.dart затем импортирует фактическую библиотеку приложений и запускает приложение, передавая значения/конфигурации среды.

Затем выберите, какой файл .dart для сборки: flutter run -t lib/main_debug.dart

Ответ 2

Основываясь на идее Сета, вот пример, который устанавливает глобальное представление BuildEnvironment именем env.

env.dart

import 'package:meta/meta.dart';

enum BuildFlavor { production, development, staging }

BuildEnvironment get env => _env;
BuildEnvironment _env;

class BuildEnvironment {
  /// The backend server.
  final String baseUrl;
  final BuildFlavor flavor;

  BuildEnvironment._init({this.flavor, this.baseUrl});

  /// Sets up the top-level [env] getter on the first call only.
  static void init({@required flavor, @required baseUrl}) =>
      _env ??= BuildEnvironment._init(flavor: flavor, baseUrl: baseUrl);
}

main_dev.dart

import 'package:flutter/material.dart';
import 'env.dart';
import 'app.dart';

void main() {
  BuildEnvironment.init(
      flavor: BuildFlavor.development, baseUrl: 'http://dev.example.com');
  assert(env != null);
  runApp(App());
}

main_prod.dart

import 'package:flutter/material.dart';
import 'env.dart';
import 'app.dart';

void main() {
  BuildEnvironment.init(
      flavor: BuildFlavor.production, baseUrl: 'http://example.com');
  assert(env != null);
  runApp(App());
}
  • import env.dart чтобы открыть переменную env.
  • запустить и создать приложение, используя target параметр.

    flutter run -t lib/main_dev.dart flutter build -t lib/main_dev.dart

Для интеграции с VS Code определите конфигурации запуска:

.vscode/launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "development",
      "program": "lib/main_dev.dart",
      "request": "launch",
      "type": "dart"
    },
    {
      "name": "production",
      "program": "lib/main_prod.dart",
      "request": "launch",
      "type": "dart"
    }
  ]
}

Я изначально собирался использовать аргументы командной строки, переданные main функции Dart, но я не думаю, что в командной строке можно передавать аргументы в командной строке с помощью flutter run или flutter build, хотя VS Code и Android Studio поддерживают передачу аргументов main, Это также кажется, что компоновка компоновки в качестве командной строки arg main не подходит, поскольку args могут быть переданы после процесса сборки.

Ответ 3

Режим освобождения и отладки теперь можно получить, используя

const bool isProduction = bool.fromEnvironment('dart.vm.product');

Поскольку это константа, она работает с дрожанием дерева.
Так что код вроде

if(isProduction) {
  // branch 1
} else {
  // branch 2
}

будет включать только один из этих двух ветвей в производственный код в зависимости от isProduction

Ответ 4

Просто вы можете реализовать варианты сборки.

В андроиде:

buildTypes {
    release {
        // TODO: Add your own signing config for the release build.
        // Signing with the debug keys for now, so 'flutter run --release' works.
        signingConfig signingConfigs.release
    }
    debug{
        applicationIdSuffix ".dev"
        signingConfig signingConfigs.debug
    }
   qa{
        applicationIdSuffix ".qa"
        signingConfig signingConfigs.qa
    }
}

В iOS:

добавьте конфигурацию, выбрав project-> runner-> configuration, добавьте еще один

Ответ 5

Обновление от июля 2019 года:

Я написал пакет, в который интегрирована глобальная конфигурация Flutter.

EZ Flutter - это коллекция виджетов, пакетов и многих других полезных вещей, смешанных в небольшом фреймворке. Цель состоит в том, чтобы сделать стандартные функции доступными с нуля.

Github: https://github.com/Ephenodrom/EZ-Flutter

dependencies:
  ez_flutter: ^0.2.0

Ознакомьтесь с документацией о том, как работают различные конфигурации.

https://github.com/Ephenodrom/EZ-Flutter/blob/master/documentation/APPLICATION_SETTINGS.md

++++ СТАРЫЙ ОТВЕТ ++++

Дополнительная информация:

У меня была та же проблема, и я использовал решение, предложенное Сетом Лэддом. Поэтому мне также требовались разные конфигурации для каждой версии приложения (dev/prod), и я не хочу записывать конфигурацию в файл main_dev.dart или main_prod.dart.

Я написал простой пакет флаттера, который имеет дело с разделением файлов конфигурации и загрузкой их при запуске приложения. Конфигурация будет доступна в каждой строке кода в вашем приложении.

https://github.com/Ephenodrom/Flutter-Global-Config

  Как это использовать:

Создайте файл json в assets/cfg/$ file.json

Добавьте assets/cfg в ваш pubspec.yaml

Загрузка различных файлов конфигурации при запуске приложения:

import 'package:flutter/material.dart';
import 'package:global_configuration/global_configuration.dart';

void main() async{
  await GlobalConfiguration().loadFromAsset("app_settings");
  await GlobalConfiguration().loadFromAsset("env_dev_settings");
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  ...
}

Использование конфигурации в вашем приложении:

import 'package:flutter/material.dart';
import 'package:global_configuration/global_configuration.dart';

class CustomWidget extends StatelessWidget {

    CustomWiget(){
        // Access the config in the constructor
        print(GlobalConfiguration().getString("key1"); // prints value1
    }

    @override
     Widget build(BuildContext context) {
        // Access the config in the build method
        return new Text(GlobalConfiguration().getString("key2"));
     }
}

Ответ 6

Идея состоит в том, чтобы унаследовать виджет для типов сборки (у меня DEV, STAGE, PRO) и иметь конфигурацию 3 типов для запуска!

class AppConfig extends InheritedWidget {
  var flavorName;
  var apiBaseUrl;
  var appName;

  AppConfig(
      {@required this.appName,
      @required this.flavorName,
      @required this.apiBaseUrl,
      @required Widget child})
  : super(child: child);

  static AppConfig of(BuildContext context) {
   return context.inheritFromWidgetOfExactType(AppConfig);
  }

  @override
  bool updateShouldNotify(InheritedWidget oldWidget) => false;
}

так что мы имеем в основном:

 void main() {
   var configuredApp = AppConfig(
   appName: 'DEV',
   flavorName: 'develop',
   apiBaseUrl: 'https://dev-api.example.com/',
   child: new MyApp(),
  );
 runApp(configuredApp);
 }

тогда: enter image description here

это хороший ответ, и эта страница сработала для меня.

fooobar.com/info/14718456/...

шаг за шагом: https://iirokrankka.com/2018/03/02/separating-build-environments/