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

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

5 ответов

Решение

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

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

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

Основываясь на идее Сета, вот пример, который устанавливает глобальное представление 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());
}
  • Импортировать 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 функция, но я не думаю, что аргументы в настоящее время могут быть переданы в командной строке с flutter run или же flutter build, хотя VS Code и Android Studio поддерживают передачу аргументов в main, Также кажется, что сборка в виде командной строки main не подходит, так как аргументы могут быть переданы после процесса сборки.

Режим выпуска и отладки теперь можно получить с помощью

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

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

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

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

Начиная с Flutter 1.17 вы можете использовать --dart-defineдля создания приложения с разными переменными времени компиляции. Он работает как для Dart, так и для собственных слоев. В дротике эти значения можно получить с помощьюString.fromEnvironmentнапример. Таким образом, вам не нужно будет иметь тонны или точки входа и предоставлять учетные данные вашей среды.

Вот статья, которая объясняет больше https://link.medium.com/ibuTsWHrk6

import 'package:flutter/foundation.dart';

И используйте следующие значения const:

if (kReleaseMode) {
  // App is running in release mode. 
} else if (kProfileMode) {
  // App is running in profile mode.
} else if (kDebugMode) {
  // App is running in debug mode.
} else if (kIsWeb) {
  // App is running on the web.
}

Более чистый способ сделать это - использовать Build Flavors.

В качестве быстрого примера, если вы хотите иметь другой идентификатор приложения для своего приложения для сборки "dev", вы можете указать это в файле gradle:

flavorDimensions "version"
productFlavors {
    dev {
        applicationIdSuffix ".dev"
        versionNameSuffix "-dev"
    }
}

Подробнее о конфигурации варианта сборки gradle здесь.


Теперь вы можете запустить этот вариант сборки с помощью командной строки:

flutter run --flavor dev

Если вы используете Android Studio, вы также можете указать вариант сборки в конфигурации запуска:

Подробнее о настройке iOS читайте в этом блоге. И официальная документация по флаттерам о вариантах сборки.

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

В андроиде:

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:

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

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

У меня была та же проблема, и я использовал решение, предложенное Сетом Лэддом. Поэтому я также нуждался в различной конфигурации для каждой версии приложения (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"));
     }
}

Создайте файл в корне проекта app_environment.dart. ИспользоватьkReleaseMode переменная от foundation.dart пакет для проверки рабочего режима.

import 'package:flutter/foundation.dart';

class AppEnvironment {

  String getApiURL() {
    if (kReleaseMode) {
      return 'PROD_API_URL';
    } else {
      return 'STAGING_API_URL';
    }
  }
}
Другие вопросы по тегам